1/*
2 * Copyright 2009 Marcin KoÅcielnicki
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#define CP_FLAG_CLEAR                 0
24#define CP_FLAG_SET                   1
25#define CP_FLAG_SWAP_DIRECTION        ((0 * 32) + 0)
26#define CP_FLAG_SWAP_DIRECTION_LOAD   0
27#define CP_FLAG_SWAP_DIRECTION_SAVE   1
28#define CP_FLAG_UNK01                 ((0 * 32) + 1)
29#define CP_FLAG_UNK01_CLEAR           0
30#define CP_FLAG_UNK01_SET             1
31#define CP_FLAG_UNK03                 ((0 * 32) + 3)
32#define CP_FLAG_UNK03_CLEAR           0
33#define CP_FLAG_UNK03_SET             1
34#define CP_FLAG_USER_SAVE             ((0 * 32) + 5)
35#define CP_FLAG_USER_SAVE_NOT_PENDING 0
36#define CP_FLAG_USER_SAVE_PENDING     1
37#define CP_FLAG_USER_LOAD             ((0 * 32) + 6)
38#define CP_FLAG_USER_LOAD_NOT_PENDING 0
39#define CP_FLAG_USER_LOAD_PENDING     1
40#define CP_FLAG_UNK0B                 ((0 * 32) + 0xb)
41#define CP_FLAG_UNK0B_CLEAR           0
42#define CP_FLAG_UNK0B_SET             1
43#define CP_FLAG_XFER_SWITCH           ((0 * 32) + 0xe)
44#define CP_FLAG_XFER_SWITCH_DISABLE   0
45#define CP_FLAG_XFER_SWITCH_ENABLE    1
46#define CP_FLAG_STATE                 ((0 * 32) + 0x1c)
47#define CP_FLAG_STATE_STOPPED         0
48#define CP_FLAG_STATE_RUNNING         1
49#define CP_FLAG_UNK1D                 ((0 * 32) + 0x1d)
50#define CP_FLAG_UNK1D_CLEAR           0
51#define CP_FLAG_UNK1D_SET             1
52#define CP_FLAG_UNK20                 ((1 * 32) + 0)
53#define CP_FLAG_UNK20_CLEAR           0
54#define CP_FLAG_UNK20_SET             1
55#define CP_FLAG_STATUS                ((2 * 32) + 0)
56#define CP_FLAG_STATUS_BUSY           0
57#define CP_FLAG_STATUS_IDLE           1
58#define CP_FLAG_AUTO_SAVE             ((2 * 32) + 4)
59#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0
60#define CP_FLAG_AUTO_SAVE_PENDING     1
61#define CP_FLAG_AUTO_LOAD             ((2 * 32) + 5)
62#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
63#define CP_FLAG_AUTO_LOAD_PENDING     1
64#define CP_FLAG_NEWCTX                ((2 * 32) + 10)
65#define CP_FLAG_NEWCTX_BUSY           0
66#define CP_FLAG_NEWCTX_DONE           1
67#define CP_FLAG_XFER                  ((2 * 32) + 11)
68#define CP_FLAG_XFER_IDLE             0
69#define CP_FLAG_XFER_BUSY             1
70#define CP_FLAG_ALWAYS                ((2 * 32) + 13)
71#define CP_FLAG_ALWAYS_FALSE          0
72#define CP_FLAG_ALWAYS_TRUE           1
73#define CP_FLAG_INTR                  ((2 * 32) + 15)
74#define CP_FLAG_INTR_NOT_PENDING      0
75#define CP_FLAG_INTR_PENDING          1
76
77#define CP_CTX                   0x00100000
78#define CP_CTX_COUNT             0x000f0000
79#define CP_CTX_COUNT_SHIFT               16
80#define CP_CTX_REG               0x00003fff
81#define CP_LOAD_SR               0x00200000
82#define CP_LOAD_SR_VALUE         0x000fffff
83#define CP_BRA                   0x00400000
84#define CP_BRA_IP                0x0001ff00
85#define CP_BRA_IP_SHIFT                   8
86#define CP_BRA_IF_CLEAR          0x00000080
87#define CP_BRA_FLAG              0x0000007f
88#define CP_WAIT                  0x00500000
89#define CP_WAIT_SET              0x00000080
90#define CP_WAIT_FLAG             0x0000007f
91#define CP_SET                   0x00700000
92#define CP_SET_1                 0x00000080
93#define CP_SET_FLAG              0x0000007f
94#define CP_NEWCTX                0x00600004
95#define CP_NEXT_TO_SWAP          0x00600005
96#define CP_SET_CONTEXT_POINTER   0x00600006
97#define CP_SET_XFER_POINTER      0x00600007
98#define CP_ENABLE                0x00600009
99#define CP_END                   0x0060000c
100#define CP_NEXT_TO_CURRENT       0x0060000d
101#define CP_DISABLE1              0x0090ffff
102#define CP_DISABLE2              0x0091ffff
103#define CP_XFER_1      0x008000ff
104#define CP_XFER_2      0x008800ff
105#define CP_SEEK_1      0x00c000ff
106#define CP_SEEK_2      0x00c800ff
107
108#include "drmP.h"
109#include "nouveau_drv.h"
110#include "nouveau_grctx.h"
111
112#define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf)
113#define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac)
114
115/*
116 * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's
117 * the GPU itself that does context-switching, but it needs a special
118 * microcode to do it. And it's the driver's task to supply this microcode,
119 * further known as ctxprog, as well as the initial context values, known
120 * as ctxvals.
121 *
122 * Without ctxprog, you cannot switch contexts. Not even in software, since
123 * the majority of context [xfer strands] isn't accessible directly. You're
124 * stuck with a single channel, and you also suffer all the problems resulting
125 * from missing ctxvals, since you cannot load them.
126 *
127 * Without ctxvals, you're stuck with PGRAPH's default context. It's enough to
128 * run 2d operations, but trying to utilise 3d or CUDA will just lock you up,
129 * since you don't have... some sort of needed setup.
130 *
131 * Nouveau will just disable acceleration if not given ctxprog + ctxvals, since
132 * it's too much hassle to handle no-ctxprog as a special case.
133 */
134
135/*
136 * How ctxprogs work.
137 *
138 * The ctxprog is written in its own kind of microcode, with very small and
139 * crappy set of available commands. You upload it to a small [512 insns]
140 * area of memory on PGRAPH, and it'll be run when PFIFO wants PGRAPH to
141 * switch channel. or when the driver explicitely requests it. Stuff visible
142 * to ctxprog consists of: PGRAPH MMIO registers, PGRAPH context strands,
143 * the per-channel context save area in VRAM [known as ctxvals or grctx],
144 * 4 flags registers, a scratch register, two grctx pointers, plus many
145 * random poorly-understood details.
146 *
147 * When ctxprog runs, it's supposed to check what operations are asked of it,
148 * save old context if requested, optionally reset PGRAPH and switch to the
149 * new channel, and load the new context. Context consists of three major
150 * parts: subset of MMIO registers and two "xfer areas".
151 */
152
153/* TODO:
154 *  - document unimplemented bits compared to nvidia
155 *  - NVAx: make a TP subroutine, use it.
156 *  - use 0x4008fc instead of 0x1540?
157 */
158
159enum cp_label {
160	cp_check_load = 1,
161	cp_setup_auto_load,
162	cp_setup_load,
163	cp_setup_save,
164	cp_swap_state,
165	cp_prepare_exit,
166	cp_exit,
167};
168
169static void nv50_graph_construct_mmio(struct nouveau_grctx *ctx);
170static void nv50_graph_construct_xfer1(struct nouveau_grctx *ctx);
171static void nv50_graph_construct_xfer2(struct nouveau_grctx *ctx);
172
173/* Main function: construct the ctxprog skeleton, call the other functions. */
174
175int
176nv50_grctx_init(struct nouveau_grctx *ctx)
177{
178	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
179
180	switch (dev_priv->chipset) {
181	case 0x50:
182	case 0x84:
183	case 0x86:
184	case 0x92:
185	case 0x94:
186	case 0x96:
187	case 0x98:
188	case 0xa0:
189	case 0xa3:
190	case 0xa5:
191	case 0xa8:
192	case 0xaa:
193	case 0xac:
194	case 0xaf:
195		break;
196	default:
197		NV_ERROR(ctx->dev, "I don't know how to make a ctxprog for "
198				   "your NV%x card.\n", dev_priv->chipset);
199		NV_ERROR(ctx->dev, "Disabling acceleration. Please contact "
200				   "the devs.\n");
201		return -ENOSYS;
202	}
203
204	cp_set (ctx, STATE, RUNNING);
205	cp_set (ctx, XFER_SWITCH, ENABLE);
206	/* decide whether we're loading/unloading the context */
207	cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
208	cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save);
209
210	cp_name(ctx, cp_check_load);
211	cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load);
212	cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load);
213	cp_bra (ctx, ALWAYS, TRUE, cp_exit);
214
215	/* setup for context load */
216	cp_name(ctx, cp_setup_auto_load);
217	cp_out (ctx, CP_DISABLE1);
218	cp_out (ctx, CP_DISABLE2);
219	cp_out (ctx, CP_ENABLE);
220	cp_out (ctx, CP_NEXT_TO_SWAP);
221	cp_set (ctx, UNK01, SET);
222	cp_name(ctx, cp_setup_load);
223	cp_out (ctx, CP_NEWCTX);
224	cp_wait(ctx, NEWCTX, BUSY);
225	cp_set (ctx, UNK1D, CLEAR);
226	cp_set (ctx, SWAP_DIRECTION, LOAD);
227	cp_bra (ctx, UNK0B, SET, cp_prepare_exit);
228	cp_bra (ctx, ALWAYS, TRUE, cp_swap_state);
229
230	/* setup for context save */
231	cp_name(ctx, cp_setup_save);
232	cp_set (ctx, UNK1D, SET);
233	cp_wait(ctx, STATUS, BUSY);
234	cp_wait(ctx, INTR, PENDING);
235	cp_bra (ctx, STATUS, BUSY, cp_setup_save);
236	cp_set (ctx, UNK01, SET);
237	cp_set (ctx, SWAP_DIRECTION, SAVE);
238
239	/* general PGRAPH state */
240	cp_name(ctx, cp_swap_state);
241	cp_set (ctx, UNK03, SET);
242	cp_pos (ctx, 0x00004/4);
243	cp_ctx (ctx, 0x400828, 1); /* needed. otherwise, flickering happens. */
244	cp_pos (ctx, 0x00100/4);
245	nv50_graph_construct_mmio(ctx);
246	nv50_graph_construct_xfer1(ctx);
247	nv50_graph_construct_xfer2(ctx);
248
249	cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
250
251	cp_set (ctx, UNK20, SET);
252	cp_set (ctx, SWAP_DIRECTION, SAVE); /* no idea why this is needed, but fixes at least one lockup. */
253	cp_lsr (ctx, ctx->ctxvals_base);
254	cp_out (ctx, CP_SET_XFER_POINTER);
255	cp_lsr (ctx, 4);
256	cp_out (ctx, CP_SEEK_1);
257	cp_out (ctx, CP_XFER_1);
258	cp_wait(ctx, XFER, BUSY);
259
260	/* pre-exit state updates */
261	cp_name(ctx, cp_prepare_exit);
262	cp_set (ctx, UNK01, CLEAR);
263	cp_set (ctx, UNK03, CLEAR);
264	cp_set (ctx, UNK1D, CLEAR);
265
266	cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
267	cp_out (ctx, CP_NEXT_TO_CURRENT);
268
269	cp_name(ctx, cp_exit);
270	cp_set (ctx, USER_SAVE, NOT_PENDING);
271	cp_set (ctx, USER_LOAD, NOT_PENDING);
272	cp_set (ctx, XFER_SWITCH, DISABLE);
273	cp_set (ctx, STATE, STOPPED);
274	cp_out (ctx, CP_END);
275	ctx->ctxvals_pos += 0x400; /* padding... no idea why you need it */
276
277	return 0;
278}
279
280/*
281 * Constructs MMIO part of ctxprog and ctxvals. Just a matter of knowing which
282 * registers to save/restore and the default values for them.
283 */
284
285static void
286nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx);
287
288static void
289nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
290{
291	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
292	int i, j;
293	int offset, base;
294	uint32_t units = nv_rd32 (ctx->dev, 0x1540);
295
296	/* 0800: DISPATCH */
297	cp_ctx(ctx, 0x400808, 7);
298	gr_def(ctx, 0x400814, 0x00000030);
299	cp_ctx(ctx, 0x400834, 0x32);
300	if (dev_priv->chipset == 0x50) {
301		gr_def(ctx, 0x400834, 0xff400040);
302		gr_def(ctx, 0x400838, 0xfff00080);
303		gr_def(ctx, 0x40083c, 0xfff70090);
304		gr_def(ctx, 0x400840, 0xffe806a8);
305	}
306	gr_def(ctx, 0x400844, 0x00000002);
307	if (IS_NVA3F(dev_priv->chipset))
308		gr_def(ctx, 0x400894, 0x00001000);
309	gr_def(ctx, 0x4008e8, 0x00000003);
310	gr_def(ctx, 0x4008ec, 0x00001000);
311	if (dev_priv->chipset == 0x50)
312		cp_ctx(ctx, 0x400908, 0xb);
313	else if (dev_priv->chipset < 0xa0)
314		cp_ctx(ctx, 0x400908, 0xc);
315	else
316		cp_ctx(ctx, 0x400908, 0xe);
317
318	if (dev_priv->chipset >= 0xa0)
319		cp_ctx(ctx, 0x400b00, 0x1);
320	if (IS_NVA3F(dev_priv->chipset)) {
321		cp_ctx(ctx, 0x400b10, 0x1);
322		gr_def(ctx, 0x400b10, 0x0001629d);
323		cp_ctx(ctx, 0x400b20, 0x1);
324		gr_def(ctx, 0x400b20, 0x0001629d);
325	}
326
327	nv50_graph_construct_mmio_ddata(ctx);
328
329	/* 0C00: VFETCH */
330	cp_ctx(ctx, 0x400c08, 0x2);
331	gr_def(ctx, 0x400c08, 0x0000fe0c);
332
333	/* 1000 */
334	if (dev_priv->chipset < 0xa0) {
335		cp_ctx(ctx, 0x401008, 0x4);
336		gr_def(ctx, 0x401014, 0x00001000);
337	} else if (!IS_NVA3F(dev_priv->chipset)) {
338		cp_ctx(ctx, 0x401008, 0x5);
339		gr_def(ctx, 0x401018, 0x00001000);
340	} else {
341		cp_ctx(ctx, 0x401008, 0x5);
342		gr_def(ctx, 0x401018, 0x00004000);
343	}
344
345	/* 1400 */
346	cp_ctx(ctx, 0x401400, 0x8);
347	cp_ctx(ctx, 0x401424, 0x3);
348	if (dev_priv->chipset == 0x50)
349		gr_def(ctx, 0x40142c, 0x0001fd87);
350	else
351		gr_def(ctx, 0x40142c, 0x00000187);
352	cp_ctx(ctx, 0x401540, 0x5);
353	gr_def(ctx, 0x401550, 0x00001018);
354
355	/* 1800: STREAMOUT */
356	cp_ctx(ctx, 0x401814, 0x1);
357	gr_def(ctx, 0x401814, 0x000000ff);
358	if (dev_priv->chipset == 0x50) {
359		cp_ctx(ctx, 0x40181c, 0xe);
360		gr_def(ctx, 0x401850, 0x00000004);
361	} else if (dev_priv->chipset < 0xa0) {
362		cp_ctx(ctx, 0x40181c, 0xf);
363		gr_def(ctx, 0x401854, 0x00000004);
364	} else {
365		cp_ctx(ctx, 0x40181c, 0x13);
366		gr_def(ctx, 0x401864, 0x00000004);
367	}
368
369	/* 1C00 */
370	cp_ctx(ctx, 0x401c00, 0x1);
371	switch (dev_priv->chipset) {
372	case 0x50:
373		gr_def(ctx, 0x401c00, 0x0001005f);
374		break;
375	case 0x84:
376	case 0x86:
377	case 0x94:
378		gr_def(ctx, 0x401c00, 0x044d00df);
379		break;
380	case 0x92:
381	case 0x96:
382	case 0x98:
383	case 0xa0:
384	case 0xaa:
385	case 0xac:
386		gr_def(ctx, 0x401c00, 0x042500df);
387		break;
388	case 0xa3:
389	case 0xa5:
390	case 0xa8:
391	case 0xaf:
392		gr_def(ctx, 0x401c00, 0x142500df);
393		break;
394	}
395
396	/* 2000 */
397
398	/* 2400 */
399	cp_ctx(ctx, 0x402400, 0x1);
400	if (dev_priv->chipset == 0x50)
401		cp_ctx(ctx, 0x402408, 0x1);
402	else
403		cp_ctx(ctx, 0x402408, 0x2);
404	gr_def(ctx, 0x402408, 0x00000600);
405
406	/* 2800: CSCHED */
407	cp_ctx(ctx, 0x402800, 0x1);
408	if (dev_priv->chipset == 0x50)
409		gr_def(ctx, 0x402800, 0x00000006);
410
411	/* 2C00: ZCULL */
412	cp_ctx(ctx, 0x402c08, 0x6);
413	if (dev_priv->chipset != 0x50)
414		gr_def(ctx, 0x402c14, 0x01000000);
415	gr_def(ctx, 0x402c18, 0x000000ff);
416	if (dev_priv->chipset == 0x50)
417		cp_ctx(ctx, 0x402ca0, 0x1);
418	else
419		cp_ctx(ctx, 0x402ca0, 0x2);
420	if (dev_priv->chipset < 0xa0)
421		gr_def(ctx, 0x402ca0, 0x00000400);
422	else if (!IS_NVA3F(dev_priv->chipset))
423		gr_def(ctx, 0x402ca0, 0x00000800);
424	else
425		gr_def(ctx, 0x402ca0, 0x00000400);
426	cp_ctx(ctx, 0x402cac, 0x4);
427
428	/* 3000: ENG2D */
429	cp_ctx(ctx, 0x403004, 0x1);
430	gr_def(ctx, 0x403004, 0x00000001);
431
432	/* 3400 */
433	if (dev_priv->chipset >= 0xa0) {
434		cp_ctx(ctx, 0x403404, 0x1);
435		gr_def(ctx, 0x403404, 0x00000001);
436	}
437
438	/* 5000: CCACHE */
439	cp_ctx(ctx, 0x405000, 0x1);
440	switch (dev_priv->chipset) {
441	case 0x50:
442		gr_def(ctx, 0x405000, 0x00300080);
443		break;
444	case 0x84:
445	case 0xa0:
446	case 0xa3:
447	case 0xa5:
448	case 0xa8:
449	case 0xaa:
450	case 0xac:
451	case 0xaf:
452		gr_def(ctx, 0x405000, 0x000e0080);
453		break;
454	case 0x86:
455	case 0x92:
456	case 0x94:
457	case 0x96:
458	case 0x98:
459		gr_def(ctx, 0x405000, 0x00000080);
460		break;
461	}
462	cp_ctx(ctx, 0x405014, 0x1);
463	gr_def(ctx, 0x405014, 0x00000004);
464	cp_ctx(ctx, 0x40501c, 0x1);
465	cp_ctx(ctx, 0x405024, 0x1);
466	cp_ctx(ctx, 0x40502c, 0x1);
467
468	/* 6000? */
469	if (dev_priv->chipset == 0x50)
470		cp_ctx(ctx, 0x4063e0, 0x1);
471
472	/* 6800: M2MF */
473	if (dev_priv->chipset < 0x90) {
474		cp_ctx(ctx, 0x406814, 0x2b);
475		gr_def(ctx, 0x406818, 0x00000f80);
476		gr_def(ctx, 0x406860, 0x007f0080);
477		gr_def(ctx, 0x40689c, 0x007f0080);
478	} else {
479		cp_ctx(ctx, 0x406814, 0x4);
480		if (dev_priv->chipset == 0x98)
481			gr_def(ctx, 0x406818, 0x00000f80);
482		else
483			gr_def(ctx, 0x406818, 0x00001f80);
484		if (IS_NVA3F(dev_priv->chipset))
485			gr_def(ctx, 0x40681c, 0x00000030);
486		cp_ctx(ctx, 0x406830, 0x3);
487	}
488
489	/* 7000: per-ROP group state */
490	for (i = 0; i < 8; i++) {
491		if (units & (1<<(i+16))) {
492			cp_ctx(ctx, 0x407000 + (i<<8), 3);
493			if (dev_priv->chipset == 0x50)
494				gr_def(ctx, 0x407000 + (i<<8), 0x1b74f820);
495			else if (dev_priv->chipset != 0xa5)
496				gr_def(ctx, 0x407000 + (i<<8), 0x3b74f821);
497			else
498				gr_def(ctx, 0x407000 + (i<<8), 0x7b74f821);
499			gr_def(ctx, 0x407004 + (i<<8), 0x89058001);
500
501			if (dev_priv->chipset == 0x50) {
502				cp_ctx(ctx, 0x407010 + (i<<8), 1);
503			} else if (dev_priv->chipset < 0xa0) {
504				cp_ctx(ctx, 0x407010 + (i<<8), 2);
505				gr_def(ctx, 0x407010 + (i<<8), 0x00001000);
506				gr_def(ctx, 0x407014 + (i<<8), 0x0000001f);
507			} else {
508				cp_ctx(ctx, 0x407010 + (i<<8), 3);
509				gr_def(ctx, 0x407010 + (i<<8), 0x00001000);
510				if (dev_priv->chipset != 0xa5)
511					gr_def(ctx, 0x407014 + (i<<8), 0x000000ff);
512				else
513					gr_def(ctx, 0x407014 + (i<<8), 0x000001ff);
514			}
515
516			cp_ctx(ctx, 0x407080 + (i<<8), 4);
517			if (dev_priv->chipset != 0xa5)
518				gr_def(ctx, 0x407080 + (i<<8), 0x027c10fa);
519			else
520				gr_def(ctx, 0x407080 + (i<<8), 0x827c10fa);
521			if (dev_priv->chipset == 0x50)
522				gr_def(ctx, 0x407084 + (i<<8), 0x000000c0);
523			else
524				gr_def(ctx, 0x407084 + (i<<8), 0x400000c0);
525			gr_def(ctx, 0x407088 + (i<<8), 0xb7892080);
526
527			if (dev_priv->chipset < 0xa0)
528				cp_ctx(ctx, 0x407094 + (i<<8), 1);
529			else if (!IS_NVA3F(dev_priv->chipset))
530				cp_ctx(ctx, 0x407094 + (i<<8), 3);
531			else {
532				cp_ctx(ctx, 0x407094 + (i<<8), 4);
533				gr_def(ctx, 0x4070a0 + (i<<8), 1);
534			}
535		}
536	}
537
538	cp_ctx(ctx, 0x407c00, 0x3);
539	if (dev_priv->chipset < 0x90)
540		gr_def(ctx, 0x407c00, 0x00010040);
541	else if (dev_priv->chipset < 0xa0)
542		gr_def(ctx, 0x407c00, 0x00390040);
543	else
544		gr_def(ctx, 0x407c00, 0x003d0040);
545	gr_def(ctx, 0x407c08, 0x00000022);
546	if (dev_priv->chipset >= 0xa0) {
547		cp_ctx(ctx, 0x407c10, 0x3);
548		cp_ctx(ctx, 0x407c20, 0x1);
549		cp_ctx(ctx, 0x407c2c, 0x1);
550	}
551
552	if (dev_priv->chipset < 0xa0) {
553		cp_ctx(ctx, 0x407d00, 0x9);
554	} else {
555		cp_ctx(ctx, 0x407d00, 0x15);
556	}
557	if (dev_priv->chipset == 0x98)
558		gr_def(ctx, 0x407d08, 0x00380040);
559	else {
560		if (dev_priv->chipset < 0x90)
561			gr_def(ctx, 0x407d08, 0x00010040);
562		else if (dev_priv->chipset < 0xa0)
563			gr_def(ctx, 0x407d08, 0x00390040);
564		else
565			gr_def(ctx, 0x407d08, 0x003d0040);
566		gr_def(ctx, 0x407d0c, 0x00000022);
567	}
568
569	/* 8000+: per-TP state */
570	for (i = 0; i < 10; i++) {
571		if (units & (1<<i)) {
572			if (dev_priv->chipset < 0xa0)
573				base = 0x408000 + (i<<12);
574			else
575				base = 0x408000 + (i<<11);
576			if (dev_priv->chipset < 0xa0)
577				offset = base + 0xc00;
578			else
579				offset = base + 0x80;
580			cp_ctx(ctx, offset + 0x00, 1);
581			gr_def(ctx, offset + 0x00, 0x0000ff0a);
582			cp_ctx(ctx, offset + 0x08, 1);
583
584			/* per-MP state */
585			for (j = 0; j < (dev_priv->chipset < 0xa0 ? 2 : 4); j++) {
586				if (!(units & (1 << (j+24)))) continue;
587				if (dev_priv->chipset < 0xa0)
588					offset = base + 0x200 + (j<<7);
589				else
590					offset = base + 0x100 + (j<<7);
591				cp_ctx(ctx, offset, 0x20);
592				gr_def(ctx, offset + 0x00, 0x01800000);
593				gr_def(ctx, offset + 0x04, 0x00160000);
594				gr_def(ctx, offset + 0x08, 0x01800000);
595				gr_def(ctx, offset + 0x18, 0x0003ffff);
596				switch (dev_priv->chipset) {
597				case 0x50:
598					gr_def(ctx, offset + 0x1c, 0x00080000);
599					break;
600				case 0x84:
601					gr_def(ctx, offset + 0x1c, 0x00880000);
602					break;
603				case 0x86:
604					gr_def(ctx, offset + 0x1c, 0x018c0000);
605					break;
606				case 0x92:
607				case 0x96:
608				case 0x98:
609					gr_def(ctx, offset + 0x1c, 0x118c0000);
610					break;
611				case 0x94:
612					gr_def(ctx, offset + 0x1c, 0x10880000);
613					break;
614				case 0xa0:
615				case 0xa5:
616					gr_def(ctx, offset + 0x1c, 0x310c0000);
617					break;
618				case 0xa3:
619				case 0xa8:
620				case 0xaa:
621				case 0xac:
622				case 0xaf:
623					gr_def(ctx, offset + 0x1c, 0x300c0000);
624					break;
625				}
626				gr_def(ctx, offset + 0x40, 0x00010401);
627				if (dev_priv->chipset == 0x50)
628					gr_def(ctx, offset + 0x48, 0x00000040);
629				else
630					gr_def(ctx, offset + 0x48, 0x00000078);
631				gr_def(ctx, offset + 0x50, 0x000000bf);
632				gr_def(ctx, offset + 0x58, 0x00001210);
633				if (dev_priv->chipset == 0x50)
634					gr_def(ctx, offset + 0x5c, 0x00000080);
635				else
636					gr_def(ctx, offset + 0x5c, 0x08000080);
637				if (dev_priv->chipset >= 0xa0)
638					gr_def(ctx, offset + 0x68, 0x0000003e);
639			}
640
641			if (dev_priv->chipset < 0xa0)
642				cp_ctx(ctx, base + 0x300, 0x4);
643			else
644				cp_ctx(ctx, base + 0x300, 0x5);
645			if (dev_priv->chipset == 0x50)
646				gr_def(ctx, base + 0x304, 0x00007070);
647			else if (dev_priv->chipset < 0xa0)
648				gr_def(ctx, base + 0x304, 0x00027070);
649			else if (!IS_NVA3F(dev_priv->chipset))
650				gr_def(ctx, base + 0x304, 0x01127070);
651			else
652				gr_def(ctx, base + 0x304, 0x05127070);
653
654			if (dev_priv->chipset < 0xa0)
655				cp_ctx(ctx, base + 0x318, 1);
656			else
657				cp_ctx(ctx, base + 0x320, 1);
658			if (dev_priv->chipset == 0x50)
659				gr_def(ctx, base + 0x318, 0x0003ffff);
660			else if (dev_priv->chipset < 0xa0)
661				gr_def(ctx, base + 0x318, 0x03ffffff);
662			else
663				gr_def(ctx, base + 0x320, 0x07ffffff);
664
665			if (dev_priv->chipset < 0xa0)
666				cp_ctx(ctx, base + 0x324, 5);
667			else
668				cp_ctx(ctx, base + 0x328, 4);
669
670			if (dev_priv->chipset < 0xa0) {
671				cp_ctx(ctx, base + 0x340, 9);
672				offset = base + 0x340;
673			} else if (!IS_NVA3F(dev_priv->chipset)) {
674				cp_ctx(ctx, base + 0x33c, 0xb);
675				offset = base + 0x344;
676			} else {
677				cp_ctx(ctx, base + 0x33c, 0xd);
678				offset = base + 0x344;
679			}
680			gr_def(ctx, offset + 0x0, 0x00120407);
681			gr_def(ctx, offset + 0x4, 0x05091507);
682			if (dev_priv->chipset == 0x84)
683				gr_def(ctx, offset + 0x8, 0x05100202);
684			else
685				gr_def(ctx, offset + 0x8, 0x05010202);
686			gr_def(ctx, offset + 0xc, 0x00030201);
687			if (dev_priv->chipset == 0xa3)
688				cp_ctx(ctx, base + 0x36c, 1);
689
690			cp_ctx(ctx, base + 0x400, 2);
691			gr_def(ctx, base + 0x404, 0x00000040);
692			cp_ctx(ctx, base + 0x40c, 2);
693			gr_def(ctx, base + 0x40c, 0x0d0c0b0a);
694			gr_def(ctx, base + 0x410, 0x00141210);
695
696			if (dev_priv->chipset < 0xa0)
697				offset = base + 0x800;
698			else
699				offset = base + 0x500;
700			cp_ctx(ctx, offset, 6);
701			gr_def(ctx, offset + 0x0, 0x000001f0);
702			gr_def(ctx, offset + 0x4, 0x00000001);
703			gr_def(ctx, offset + 0x8, 0x00000003);
704			if (dev_priv->chipset == 0x50 || IS_NVAAF(dev_priv->chipset))
705				gr_def(ctx, offset + 0xc, 0x00008000);
706			gr_def(ctx, offset + 0x14, 0x00039e00);
707			cp_ctx(ctx, offset + 0x1c, 2);
708			if (dev_priv->chipset == 0x50)
709				gr_def(ctx, offset + 0x1c, 0x00000040);
710			else
711				gr_def(ctx, offset + 0x1c, 0x00000100);
712			gr_def(ctx, offset + 0x20, 0x00003800);
713
714			if (dev_priv->chipset >= 0xa0) {
715				cp_ctx(ctx, base + 0x54c, 2);
716				if (!IS_NVA3F(dev_priv->chipset))
717					gr_def(ctx, base + 0x54c, 0x003fe006);
718				else
719					gr_def(ctx, base + 0x54c, 0x003fe007);
720				gr_def(ctx, base + 0x550, 0x003fe000);
721			}
722
723			if (dev_priv->chipset < 0xa0)
724				offset = base + 0xa00;
725			else
726				offset = base + 0x680;
727			cp_ctx(ctx, offset, 1);
728			gr_def(ctx, offset, 0x00404040);
729
730			if (dev_priv->chipset < 0xa0)
731				offset = base + 0xe00;
732			else
733				offset = base + 0x700;
734			cp_ctx(ctx, offset, 2);
735			if (dev_priv->chipset < 0xa0)
736				gr_def(ctx, offset, 0x0077f005);
737			else if (dev_priv->chipset == 0xa5)
738				gr_def(ctx, offset, 0x6cf7f007);
739			else if (dev_priv->chipset == 0xa8)
740				gr_def(ctx, offset, 0x6cfff007);
741			else if (dev_priv->chipset == 0xac)
742				gr_def(ctx, offset, 0x0cfff007);
743			else
744				gr_def(ctx, offset, 0x0cf7f007);
745			if (dev_priv->chipset == 0x50)
746				gr_def(ctx, offset + 0x4, 0x00007fff);
747			else if (dev_priv->chipset < 0xa0)
748				gr_def(ctx, offset + 0x4, 0x003f7fff);
749			else
750				gr_def(ctx, offset + 0x4, 0x02bf7fff);
751			cp_ctx(ctx, offset + 0x2c, 1);
752			if (dev_priv->chipset == 0x50) {
753				cp_ctx(ctx, offset + 0x50, 9);
754				gr_def(ctx, offset + 0x54, 0x000003ff);
755				gr_def(ctx, offset + 0x58, 0x00000003);
756				gr_def(ctx, offset + 0x5c, 0x00000003);
757				gr_def(ctx, offset + 0x60, 0x000001ff);
758				gr_def(ctx, offset + 0x64, 0x0000001f);
759				gr_def(ctx, offset + 0x68, 0x0000000f);
760				gr_def(ctx, offset + 0x6c, 0x0000000f);
761			} else if (dev_priv->chipset < 0xa0) {
762				cp_ctx(ctx, offset + 0x50, 1);
763				cp_ctx(ctx, offset + 0x70, 1);
764			} else {
765				cp_ctx(ctx, offset + 0x50, 1);
766				cp_ctx(ctx, offset + 0x60, 5);
767			}
768		}
769	}
770}
771
772static void
773dd_emit(struct nouveau_grctx *ctx, int num, uint32_t val) {
774	int i;
775	if (val && ctx->mode == NOUVEAU_GRCTX_VALS)
776		for (i = 0; i < num; i++)
777			nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + i), val);
778	ctx->ctxvals_pos += num;
779}
780
781static void
782nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx)
783{
784	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
785	int base, num;
786	base = ctx->ctxvals_pos;
787
788	/* tesla state */
789	dd_emit(ctx, 1, 0);	/* 00000001 UNK0F90 */
790	dd_emit(ctx, 1, 0);	/* 00000001 UNK135C */
791
792	/* SRC_TIC state */
793	dd_emit(ctx, 1, 0);	/* 00000007 SRC_TILE_MODE_Z */
794	dd_emit(ctx, 1, 2);	/* 00000007 SRC_TILE_MODE_Y */
795	dd_emit(ctx, 1, 1);	/* 00000001 SRC_LINEAR #1 */
796	dd_emit(ctx, 1, 0);	/* 000000ff SRC_ADDRESS_HIGH */
797	dd_emit(ctx, 1, 0);	/* 00000001 SRC_SRGB */
798	if (dev_priv->chipset >= 0x94)
799		dd_emit(ctx, 1, 0);	/* 00000003 eng2d UNK0258 */
800	dd_emit(ctx, 1, 1);	/* 00000fff SRC_DEPTH */
801	dd_emit(ctx, 1, 0x100);	/* 0000ffff SRC_HEIGHT */
802
803	/* turing state */
804	dd_emit(ctx, 1, 0);		/* 0000000f TEXTURES_LOG2 */
805	dd_emit(ctx, 1, 0);		/* 0000000f SAMPLERS_LOG2 */
806	dd_emit(ctx, 1, 0);		/* 000000ff CB_DEF_ADDRESS_HIGH */
807	dd_emit(ctx, 1, 0);		/* ffffffff CB_DEF_ADDRESS_LOW */
808	dd_emit(ctx, 1, 0);		/* ffffffff SHARED_SIZE */
809	dd_emit(ctx, 1, 2);		/* ffffffff REG_MODE */
810	dd_emit(ctx, 1, 1);		/* 0000ffff BLOCK_ALLOC_THREADS */
811	dd_emit(ctx, 1, 1);		/* 00000001 LANES32 */
812	dd_emit(ctx, 1, 0);		/* 000000ff UNK370 */
813	dd_emit(ctx, 1, 0);		/* 000000ff USER_PARAM_UNK */
814	dd_emit(ctx, 1, 0);		/* 000000ff USER_PARAM_COUNT */
815	dd_emit(ctx, 1, 1);		/* 000000ff UNK384 bits 8-15 */
816	dd_emit(ctx, 1, 0x3fffff);	/* 003fffff TIC_LIMIT */
817	dd_emit(ctx, 1, 0x1fff);	/* 000fffff TSC_LIMIT */
818	dd_emit(ctx, 1, 0);		/* 0000ffff CB_ADDR_INDEX */
819	dd_emit(ctx, 1, 1);		/* 000007ff BLOCKDIM_X */
820	dd_emit(ctx, 1, 1);		/* 000007ff BLOCKDIM_XMY */
821	dd_emit(ctx, 1, 0);		/* 00000001 BLOCKDIM_XMY_OVERFLOW */
822	dd_emit(ctx, 1, 1);		/* 0003ffff BLOCKDIM_XMYMZ */
823	dd_emit(ctx, 1, 1);		/* 000007ff BLOCKDIM_Y */
824	dd_emit(ctx, 1, 1);		/* 0000007f BLOCKDIM_Z */
825	dd_emit(ctx, 1, 4);		/* 000000ff CP_REG_ALLOC_TEMP */
826	dd_emit(ctx, 1, 1);		/* 00000001 BLOCKDIM_DIRTY */
827	if (IS_NVA3F(dev_priv->chipset))
828		dd_emit(ctx, 1, 0);	/* 00000003 UNK03E8 */
829	dd_emit(ctx, 1, 1);		/* 0000007f BLOCK_ALLOC_HALFWARPS */
830	dd_emit(ctx, 1, 1);		/* 00000007 LOCAL_WARPS_NO_CLAMP */
831	dd_emit(ctx, 1, 7);		/* 00000007 LOCAL_WARPS_LOG_ALLOC */
832	dd_emit(ctx, 1, 1);		/* 00000007 STACK_WARPS_NO_CLAMP */
833	dd_emit(ctx, 1, 7);		/* 00000007 STACK_WARPS_LOG_ALLOC */
834	dd_emit(ctx, 1, 1);		/* 00001fff BLOCK_ALLOC_REGSLOTS_PACKED */
835	dd_emit(ctx, 1, 1);		/* 00001fff BLOCK_ALLOC_REGSLOTS_STRIDED */
836	dd_emit(ctx, 1, 1);		/* 000007ff BLOCK_ALLOC_THREADS */
837
838	/* compat 2d state */
839	if (dev_priv->chipset == 0x50) {
840		dd_emit(ctx, 4, 0);		/* 0000ffff clip X, Y, W, H */
841
842		dd_emit(ctx, 1, 1);		/* ffffffff chroma COLOR_FORMAT */
843
844		dd_emit(ctx, 1, 1);		/* ffffffff pattern COLOR_FORMAT */
845		dd_emit(ctx, 1, 0);		/* ffffffff pattern SHAPE */
846		dd_emit(ctx, 1, 1);		/* ffffffff pattern PATTERN_SELECT */
847
848		dd_emit(ctx, 1, 0xa);		/* ffffffff surf2d SRC_FORMAT */
849		dd_emit(ctx, 1, 0);		/* ffffffff surf2d DMA_SRC */
850		dd_emit(ctx, 1, 0);		/* 000000ff surf2d SRC_ADDRESS_HIGH */
851		dd_emit(ctx, 1, 0);		/* ffffffff surf2d SRC_ADDRESS_LOW */
852		dd_emit(ctx, 1, 0x40);		/* 0000ffff surf2d SRC_PITCH */
853		dd_emit(ctx, 1, 0);		/* 0000000f surf2d SRC_TILE_MODE_Z */
854		dd_emit(ctx, 1, 2);		/* 0000000f surf2d SRC_TILE_MODE_Y */
855		dd_emit(ctx, 1, 0x100);		/* ffffffff surf2d SRC_HEIGHT */
856		dd_emit(ctx, 1, 1);		/* 00000001 surf2d SRC_LINEAR */
857		dd_emit(ctx, 1, 0x100);		/* ffffffff surf2d SRC_WIDTH */
858
859		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect CLIP_B_X */
860		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect CLIP_B_Y */
861		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect CLIP_C_X */
862		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect CLIP_C_Y */
863		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect CLIP_D_X */
864		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect CLIP_D_Y */
865		dd_emit(ctx, 1, 1);		/* ffffffff gdirect COLOR_FORMAT */
866		dd_emit(ctx, 1, 0);		/* ffffffff gdirect OPERATION */
867		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect POINT_X */
868		dd_emit(ctx, 1, 0);		/* 0000ffff gdirect POINT_Y */
869
870		dd_emit(ctx, 1, 0);		/* 0000ffff blit SRC_Y */
871		dd_emit(ctx, 1, 0);		/* ffffffff blit OPERATION */
872
873		dd_emit(ctx, 1, 0);		/* ffffffff ifc OPERATION */
874
875		dd_emit(ctx, 1, 0);		/* ffffffff iifc INDEX_FORMAT */
876		dd_emit(ctx, 1, 0);		/* ffffffff iifc LUT_OFFSET */
877		dd_emit(ctx, 1, 4);		/* ffffffff iifc COLOR_FORMAT */
878		dd_emit(ctx, 1, 0);		/* ffffffff iifc OPERATION */
879	}
880
881	/* m2mf state */
882	dd_emit(ctx, 1, 0);		/* ffffffff m2mf LINE_COUNT */
883	dd_emit(ctx, 1, 0);		/* ffffffff m2mf LINE_LENGTH_IN */
884	dd_emit(ctx, 2, 0);		/* ffffffff m2mf OFFSET_IN, OFFSET_OUT */
885	dd_emit(ctx, 1, 1);		/* ffffffff m2mf TILING_DEPTH_OUT */
886	dd_emit(ctx, 1, 0x100);		/* ffffffff m2mf TILING_HEIGHT_OUT */
887	dd_emit(ctx, 1, 0);		/* ffffffff m2mf TILING_POSITION_OUT_Z */
888	dd_emit(ctx, 1, 1);		/* 00000001 m2mf LINEAR_OUT */
889	dd_emit(ctx, 2, 0);		/* 0000ffff m2mf TILING_POSITION_OUT_X, Y */
890	dd_emit(ctx, 1, 0x100);		/* ffffffff m2mf TILING_PITCH_OUT */
891	dd_emit(ctx, 1, 1);		/* ffffffff m2mf TILING_DEPTH_IN */
892	dd_emit(ctx, 1, 0x100);		/* ffffffff m2mf TILING_HEIGHT_IN */
893	dd_emit(ctx, 1, 0);		/* ffffffff m2mf TILING_POSITION_IN_Z */
894	dd_emit(ctx, 1, 1);		/* 00000001 m2mf LINEAR_IN */
895	dd_emit(ctx, 2, 0);		/* 0000ffff m2mf TILING_POSITION_IN_X, Y */
896	dd_emit(ctx, 1, 0x100);		/* ffffffff m2mf TILING_PITCH_IN */
897
898	/* more compat 2d state */
899	if (dev_priv->chipset == 0x50) {
900		dd_emit(ctx, 1, 1);		/* ffffffff line COLOR_FORMAT */
901		dd_emit(ctx, 1, 0);		/* ffffffff line OPERATION */
902
903		dd_emit(ctx, 1, 1);		/* ffffffff triangle COLOR_FORMAT */
904		dd_emit(ctx, 1, 0);		/* ffffffff triangle OPERATION */
905
906		dd_emit(ctx, 1, 0);		/* 0000000f sifm TILE_MODE_Z */
907		dd_emit(ctx, 1, 2);		/* 0000000f sifm TILE_MODE_Y */
908		dd_emit(ctx, 1, 0);		/* 000000ff sifm FORMAT_FILTER */
909		dd_emit(ctx, 1, 1);		/* 000000ff sifm FORMAT_ORIGIN */
910		dd_emit(ctx, 1, 0);		/* 0000ffff sifm SRC_PITCH */
911		dd_emit(ctx, 1, 1);		/* 00000001 sifm SRC_LINEAR */
912		dd_emit(ctx, 1, 0);		/* 000000ff sifm SRC_OFFSET_HIGH */
913		dd_emit(ctx, 1, 0);		/* ffffffff sifm SRC_OFFSET */
914		dd_emit(ctx, 1, 0);		/* 0000ffff sifm SRC_HEIGHT */
915		dd_emit(ctx, 1, 0);		/* 0000ffff sifm SRC_WIDTH */
916		dd_emit(ctx, 1, 3);		/* ffffffff sifm COLOR_FORMAT */
917		dd_emit(ctx, 1, 0);		/* ffffffff sifm OPERATION */
918
919		dd_emit(ctx, 1, 0);		/* ffffffff sifc OPERATION */
920	}
921
922	/* tesla state */
923	dd_emit(ctx, 1, 0);		/* 0000000f GP_TEXTURES_LOG2 */
924	dd_emit(ctx, 1, 0);		/* 0000000f GP_SAMPLERS_LOG2 */
925	dd_emit(ctx, 1, 0);		/* 000000ff */
926	dd_emit(ctx, 1, 0);		/* ffffffff */
927	dd_emit(ctx, 1, 4);		/* 000000ff UNK12B0_0 */
928	dd_emit(ctx, 1, 0x70);		/* 000000ff UNK12B0_1 */
929	dd_emit(ctx, 1, 0x80);		/* 000000ff UNK12B0_3 */
930	dd_emit(ctx, 1, 0);		/* 000000ff UNK12B0_2 */
931	dd_emit(ctx, 1, 0);		/* 0000000f FP_TEXTURES_LOG2 */
932	dd_emit(ctx, 1, 0);		/* 0000000f FP_SAMPLERS_LOG2 */
933	if (IS_NVA3F(dev_priv->chipset)) {
934		dd_emit(ctx, 1, 0);	/* ffffffff */
935		dd_emit(ctx, 1, 0);	/* 0000007f MULTISAMPLE_SAMPLES_LOG2 */
936	} else {
937		dd_emit(ctx, 1, 0);	/* 0000000f MULTISAMPLE_SAMPLES_LOG2 */
938	}
939	dd_emit(ctx, 1, 0xc);		/* 000000ff SEMANTIC_COLOR.BFC0_ID */
940	if (dev_priv->chipset != 0x50)
941		dd_emit(ctx, 1, 0);	/* 00000001 SEMANTIC_COLOR.CLMP_EN */
942	dd_emit(ctx, 1, 8);		/* 000000ff SEMANTIC_COLOR.COLR_NR */
943	dd_emit(ctx, 1, 0x14);		/* 000000ff SEMANTIC_COLOR.FFC0_ID */
944	if (dev_priv->chipset == 0x50) {
945		dd_emit(ctx, 1, 0);	/* 000000ff SEMANTIC_LAYER */
946		dd_emit(ctx, 1, 0);	/* 00000001 */
947	} else {
948		dd_emit(ctx, 1, 0);	/* 00000001 SEMANTIC_PTSZ.ENABLE */
949		dd_emit(ctx, 1, 0x29);	/* 000000ff SEMANTIC_PTSZ.PTSZ_ID */
950		dd_emit(ctx, 1, 0x27);	/* 000000ff SEMANTIC_PRIM */
951		dd_emit(ctx, 1, 0x26);	/* 000000ff SEMANTIC_LAYER */
952		dd_emit(ctx, 1, 8);	/* 0000000f SMENATIC_CLIP.CLIP_HIGH */
953		dd_emit(ctx, 1, 4);	/* 000000ff SEMANTIC_CLIP.CLIP_LO */
954		dd_emit(ctx, 1, 0x27);	/* 000000ff UNK0FD4 */
955		dd_emit(ctx, 1, 0);	/* 00000001 UNK1900 */
956	}
957	dd_emit(ctx, 1, 0);		/* 00000007 RT_CONTROL_MAP0 */
958	dd_emit(ctx, 1, 1);		/* 00000007 RT_CONTROL_MAP1 */
959	dd_emit(ctx, 1, 2);		/* 00000007 RT_CONTROL_MAP2 */
960	dd_emit(ctx, 1, 3);		/* 00000007 RT_CONTROL_MAP3 */
961	dd_emit(ctx, 1, 4);		/* 00000007 RT_CONTROL_MAP4 */
962	dd_emit(ctx, 1, 5);		/* 00000007 RT_CONTROL_MAP5 */
963	dd_emit(ctx, 1, 6);		/* 00000007 RT_CONTROL_MAP6 */
964	dd_emit(ctx, 1, 7);		/* 00000007 RT_CONTROL_MAP7 */
965	dd_emit(ctx, 1, 1);		/* 0000000f RT_CONTROL_COUNT */
966	dd_emit(ctx, 8, 0);		/* 00000001 RT_HORIZ_UNK */
967	dd_emit(ctx, 8, 0);		/* ffffffff RT_ADDRESS_LOW */
968	dd_emit(ctx, 1, 0xcf);		/* 000000ff RT_FORMAT */
969	dd_emit(ctx, 7, 0);		/* 000000ff RT_FORMAT */
970	if (dev_priv->chipset != 0x50)
971		dd_emit(ctx, 3, 0);	/* 1, 1, 1 */
972	else
973		dd_emit(ctx, 2, 0);	/* 1, 1 */
974	dd_emit(ctx, 1, 0);		/* ffffffff GP_ENABLE */
975	dd_emit(ctx, 1, 0x80);		/* 0000ffff GP_VERTEX_OUTPUT_COUNT*/
976	dd_emit(ctx, 1, 4);		/* 000000ff GP_REG_ALLOC_RESULT */
977	dd_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
978	if (IS_NVA3F(dev_priv->chipset)) {
979		dd_emit(ctx, 1, 3);	/* 00000003 */
980		dd_emit(ctx, 1, 0);	/* 00000001 UNK1418. Alone. */
981	}
982	if (dev_priv->chipset != 0x50)
983		dd_emit(ctx, 1, 3);	/* 00000003 UNK15AC */
984	dd_emit(ctx, 1, 1);		/* ffffffff RASTERIZE_ENABLE */
985	dd_emit(ctx, 1, 0);		/* 00000001 FP_CONTROL.EXPORTS_Z */
986	if (dev_priv->chipset != 0x50)
987		dd_emit(ctx, 1, 0);	/* 00000001 FP_CONTROL.MULTIPLE_RESULTS */
988	dd_emit(ctx, 1, 0x12);		/* 000000ff FP_INTERPOLANT_CTRL.COUNT */
989	dd_emit(ctx, 1, 0x10);		/* 000000ff FP_INTERPOLANT_CTRL.COUNT_NONFLAT */
990	dd_emit(ctx, 1, 0xc);		/* 000000ff FP_INTERPOLANT_CTRL.OFFSET */
991	dd_emit(ctx, 1, 1);		/* 00000001 FP_INTERPOLANT_CTRL.UMASK.W */
992	dd_emit(ctx, 1, 0);		/* 00000001 FP_INTERPOLANT_CTRL.UMASK.X */
993	dd_emit(ctx, 1, 0);		/* 00000001 FP_INTERPOLANT_CTRL.UMASK.Y */
994	dd_emit(ctx, 1, 0);		/* 00000001 FP_INTERPOLANT_CTRL.UMASK.Z */
995	dd_emit(ctx, 1, 4);		/* 000000ff FP_RESULT_COUNT */
996	dd_emit(ctx, 1, 2);		/* ffffffff REG_MODE */
997	dd_emit(ctx, 1, 4);		/* 000000ff FP_REG_ALLOC_TEMP */
998	if (dev_priv->chipset >= 0xa0)
999		dd_emit(ctx, 1, 0);	/* ffffffff */
1000	dd_emit(ctx, 1, 0);		/* 00000001 GP_BUILTIN_RESULT_EN.LAYER_IDX */
1001	dd_emit(ctx, 1, 0);		/* ffffffff STRMOUT_ENABLE */
1002	dd_emit(ctx, 1, 0x3fffff);	/* 003fffff TIC_LIMIT */
1003	dd_emit(ctx, 1, 0x1fff);	/* 000fffff TSC_LIMIT */
1004	dd_emit(ctx, 1, 0);		/* 00000001 VERTEX_TWO_SIDE_ENABLE*/
1005	if (dev_priv->chipset != 0x50)
1006		dd_emit(ctx, 8, 0);	/* 00000001 */
1007	if (dev_priv->chipset >= 0xa0) {
1008		dd_emit(ctx, 1, 1);	/* 00000007 VTX_ATTR_DEFINE.COMP */
1009		dd_emit(ctx, 1, 1);	/* 00000007 VTX_ATTR_DEFINE.SIZE */
1010		dd_emit(ctx, 1, 2);	/* 00000007 VTX_ATTR_DEFINE.TYPE */
1011		dd_emit(ctx, 1, 0);	/* 000000ff VTX_ATTR_DEFINE.ATTR */
1012	}
1013	dd_emit(ctx, 1, 4);		/* 0000007f VP_RESULT_MAP_SIZE */
1014	dd_emit(ctx, 1, 0x14);		/* 0000001f ZETA_FORMAT */
1015	dd_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
1016	dd_emit(ctx, 1, 0);		/* 0000000f VP_TEXTURES_LOG2 */
1017	dd_emit(ctx, 1, 0);		/* 0000000f VP_SAMPLERS_LOG2 */
1018	if (IS_NVA3F(dev_priv->chipset))
1019		dd_emit(ctx, 1, 0);	/* 00000001 */
1020	dd_emit(ctx, 1, 2);		/* 00000003 POLYGON_MODE_BACK */
1021	if (dev_priv->chipset >= 0xa0)
1022		dd_emit(ctx, 1, 0);	/* 00000003 VTX_ATTR_DEFINE.SIZE - 1 */
1023	dd_emit(ctx, 1, 0);		/* 0000ffff CB_ADDR_INDEX */
1024	if (dev_priv->chipset >= 0xa0)
1025		dd_emit(ctx, 1, 0);	/* 00000003 */
1026	dd_emit(ctx, 1, 0);		/* 00000001 CULL_FACE_ENABLE */
1027	dd_emit(ctx, 1, 1);		/* 00000003 CULL_FACE */
1028	dd_emit(ctx, 1, 0);		/* 00000001 FRONT_FACE */
1029	dd_emit(ctx, 1, 2);		/* 00000003 POLYGON_MODE_FRONT */
1030	dd_emit(ctx, 1, 0x1000);	/* 00007fff UNK141C */
1031	if (dev_priv->chipset != 0x50) {
1032		dd_emit(ctx, 1, 0xe00);		/* 7fff */
1033		dd_emit(ctx, 1, 0x1000);	/* 7fff */
1034		dd_emit(ctx, 1, 0x1e00);	/* 7fff */
1035	}
1036	dd_emit(ctx, 1, 0);		/* 00000001 BEGIN_END_ACTIVE */
1037	dd_emit(ctx, 1, 1);		/* 00000001 POLYGON_MODE_??? */
1038	dd_emit(ctx, 1, 1);		/* 000000ff GP_REG_ALLOC_TEMP / 4 rounded up */
1039	dd_emit(ctx, 1, 1);		/* 000000ff FP_REG_ALLOC_TEMP... without /4? */
1040	dd_emit(ctx, 1, 1);		/* 000000ff VP_REG_ALLOC_TEMP / 4 rounded up */
1041	dd_emit(ctx, 1, 1);		/* 00000001 */
1042	dd_emit(ctx, 1, 0);		/* 00000001 */
1043	dd_emit(ctx, 1, 0);		/* 00000001 VTX_ATTR_MASK_UNK0 nonempty */
1044	dd_emit(ctx, 1, 0);		/* 00000001 VTX_ATTR_MASK_UNK1 nonempty */
1045	dd_emit(ctx, 1, 0x200);		/* 0003ffff GP_VERTEX_OUTPUT_COUNT*GP_REG_ALLOC_RESULT */
1046	if (IS_NVA3F(dev_priv->chipset))
1047		dd_emit(ctx, 1, 0x200);
1048	dd_emit(ctx, 1, 0);		/* 00000001 */
1049	if (dev_priv->chipset < 0xa0) {
1050		dd_emit(ctx, 1, 1);	/* 00000001 */
1051		dd_emit(ctx, 1, 0x70);	/* 000000ff */
1052		dd_emit(ctx, 1, 0x80);	/* 000000ff */
1053		dd_emit(ctx, 1, 0);	/* 000000ff */
1054		dd_emit(ctx, 1, 0);	/* 00000001 */
1055		dd_emit(ctx, 1, 1);	/* 00000001 */
1056		dd_emit(ctx, 1, 0x70);	/* 000000ff */
1057		dd_emit(ctx, 1, 0x80);	/* 000000ff */
1058		dd_emit(ctx, 1, 0);	/* 000000ff */
1059	} else {
1060		dd_emit(ctx, 1, 1);	/* 00000001 */
1061		dd_emit(ctx, 1, 0xf0);	/* 000000ff */
1062		dd_emit(ctx, 1, 0xff);	/* 000000ff */
1063		dd_emit(ctx, 1, 0);	/* 000000ff */
1064		dd_emit(ctx, 1, 0);	/* 00000001 */
1065		dd_emit(ctx, 1, 1);	/* 00000001 */
1066		dd_emit(ctx, 1, 0xf0);	/* 000000ff */
1067		dd_emit(ctx, 1, 0xff);	/* 000000ff */
1068		dd_emit(ctx, 1, 0);	/* 000000ff */
1069		dd_emit(ctx, 1, 9);	/* 0000003f UNK114C.COMP,SIZE */
1070	}
1071
1072	/* eng2d state */
1073	dd_emit(ctx, 1, 0);		/* 00000001 eng2d COLOR_KEY_ENABLE */
1074	dd_emit(ctx, 1, 0);		/* 00000007 eng2d COLOR_KEY_FORMAT */
1075	dd_emit(ctx, 1, 1);		/* ffffffff eng2d DST_DEPTH */
1076	dd_emit(ctx, 1, 0xcf);		/* 000000ff eng2d DST_FORMAT */
1077	dd_emit(ctx, 1, 0);		/* ffffffff eng2d DST_LAYER */
1078	dd_emit(ctx, 1, 1);		/* 00000001 eng2d DST_LINEAR */
1079	dd_emit(ctx, 1, 0);		/* 00000007 eng2d PATTERN_COLOR_FORMAT */
1080	dd_emit(ctx, 1, 0);		/* 00000007 eng2d OPERATION */
1081	dd_emit(ctx, 1, 0);		/* 00000003 eng2d PATTERN_SELECT */
1082	dd_emit(ctx, 1, 0xcf);		/* 000000ff eng2d SIFC_FORMAT */
1083	dd_emit(ctx, 1, 0);		/* 00000001 eng2d SIFC_BITMAP_ENABLE */
1084	dd_emit(ctx, 1, 2);		/* 00000003 eng2d SIFC_BITMAP_UNK808 */
1085	dd_emit(ctx, 1, 0);		/* ffffffff eng2d BLIT_DU_DX_FRACT */
1086	dd_emit(ctx, 1, 1);		/* ffffffff eng2d BLIT_DU_DX_INT */
1087	dd_emit(ctx, 1, 0);		/* ffffffff eng2d BLIT_DV_DY_FRACT */
1088	dd_emit(ctx, 1, 1);		/* ffffffff eng2d BLIT_DV_DY_INT */
1089	dd_emit(ctx, 1, 0);		/* 00000001 eng2d BLIT_CONTROL_FILTER */
1090	dd_emit(ctx, 1, 0xcf);		/* 000000ff eng2d DRAW_COLOR_FORMAT */
1091	dd_emit(ctx, 1, 0xcf);		/* 000000ff eng2d SRC_FORMAT */
1092	dd_emit(ctx, 1, 1);		/* 00000001 eng2d SRC_LINEAR #2 */
1093
1094	num = ctx->ctxvals_pos - base;
1095	ctx->ctxvals_pos = base;
1096	if (IS_NVA3F(dev_priv->chipset))
1097		cp_ctx(ctx, 0x404800, num);
1098	else
1099		cp_ctx(ctx, 0x405400, num);
1100}
1101
1102/*
1103 * xfer areas. These are a pain.
1104 *
1105 * There are 2 xfer areas: the first one is big and contains all sorts of
1106 * stuff, the second is small and contains some per-TP context.
1107 *
1108 * Each area is split into 8 "strands". The areas, when saved to grctx,
1109 * are made of 8-word blocks. Each block contains a single word from
1110 * each strand. The strands are independent of each other, their
1111 * addresses are unrelated to each other, and data in them is closely
1112 * packed together. The strand layout varies a bit between cards: here
1113 * and there, a single word is thrown out in the middle and the whole
1114 * strand is offset by a bit from corresponding one on another chipset.
1115 * For this reason, addresses of stuff in strands are almost useless.
1116 * Knowing sequence of stuff and size of gaps between them is much more
1117 * useful, and that's how we build the strands in our generator.
1118 *
1119 * NVA0 takes this mess to a whole new level by cutting the old strands
1120 * into a few dozen pieces [known as genes], rearranging them randomly,
1121 * and putting them back together to make new strands. Hopefully these
1122 * genes correspond more or less directly to the same PGRAPH subunits
1123 * as in 400040 register.
1124 *
1125 * The most common value in default context is 0, and when the genes
1126 * are separated by 0's, gene bounduaries are quite speculative...
1127 * some of them can be clearly deduced, others can be guessed, and yet
1128 * others won't be resolved without figuring out the real meaning of
1129 * given ctxval. For the same reason, ending point of each strand
1130 * is unknown. Except for strand 0, which is the longest strand and
1131 * its end corresponds to end of the whole xfer.
1132 *
1133 * An unsolved mystery is the seek instruction: it takes an argument
1134 * in bits 8-18, and that argument is clearly the place in strands to
1135 * seek to... but the offsets don't seem to correspond to offsets as
1136 * seen in grctx. Perhaps there's another, real, not randomly-changing
1137 * addressing in strands, and the xfer insn just happens to skip over
1138 * the unused bits? NV10-NV30 PIPE comes to mind...
1139 *
1140 * As far as I know, there's no way to access the xfer areas directly
1141 * without the help of ctxprog.
1142 */
1143
1144static void
1145xf_emit(struct nouveau_grctx *ctx, int num, uint32_t val) {
1146	int i;
1147	if (val && ctx->mode == NOUVEAU_GRCTX_VALS)
1148		for (i = 0; i < num; i++)
1149			nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + (i << 3)), val);
1150	ctx->ctxvals_pos += num << 3;
1151}
1152
1153/* Gene declarations... */
1154
1155static void nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx);
1156static void nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx);
1157static void nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx);
1158static void nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx);
1159static void nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx);
1160static void nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx);
1161static void nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx);
1162static void nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx);
1163static void nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx);
1164static void nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx);
1165static void nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx);
1166static void nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx);
1167static void nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx);
1168static void nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx);
1169static void nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx);
1170static void nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx);
1171static void nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx);
1172static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx);
1173
1174static void
1175nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
1176{
1177	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1178	int i;
1179	int offset;
1180	int size = 0;
1181	uint32_t units = nv_rd32 (ctx->dev, 0x1540);
1182
1183	offset = (ctx->ctxvals_pos+0x3f)&~0x3f;
1184	ctx->ctxvals_base = offset;
1185
1186	if (dev_priv->chipset < 0xa0) {
1187		/* Strand 0 */
1188		ctx->ctxvals_pos = offset;
1189		nv50_graph_construct_gene_dispatch(ctx);
1190		nv50_graph_construct_gene_m2mf(ctx);
1191		nv50_graph_construct_gene_unk24xx(ctx);
1192		nv50_graph_construct_gene_clipid(ctx);
1193		nv50_graph_construct_gene_zcull(ctx);
1194		if ((ctx->ctxvals_pos-offset)/8 > size)
1195			size = (ctx->ctxvals_pos-offset)/8;
1196
1197		/* Strand 1 */
1198		ctx->ctxvals_pos = offset + 0x1;
1199		nv50_graph_construct_gene_vfetch(ctx);
1200		nv50_graph_construct_gene_eng2d(ctx);
1201		nv50_graph_construct_gene_csched(ctx);
1202		nv50_graph_construct_gene_ropm1(ctx);
1203		nv50_graph_construct_gene_ropm2(ctx);
1204		if ((ctx->ctxvals_pos-offset)/8 > size)
1205			size = (ctx->ctxvals_pos-offset)/8;
1206
1207		/* Strand 2 */
1208		ctx->ctxvals_pos = offset + 0x2;
1209		nv50_graph_construct_gene_ccache(ctx);
1210		nv50_graph_construct_gene_unk1cxx(ctx);
1211		nv50_graph_construct_gene_strmout(ctx);
1212		nv50_graph_construct_gene_unk14xx(ctx);
1213		nv50_graph_construct_gene_unk10xx(ctx);
1214		nv50_graph_construct_gene_unk34xx(ctx);
1215		if ((ctx->ctxvals_pos-offset)/8 > size)
1216			size = (ctx->ctxvals_pos-offset)/8;
1217
1218		/* Strand 3: per-ROP group state */
1219		ctx->ctxvals_pos = offset + 3;
1220		for (i = 0; i < 6; i++)
1221			if (units & (1 << (i + 16)))
1222				nv50_graph_construct_gene_ropc(ctx);
1223		if ((ctx->ctxvals_pos-offset)/8 > size)
1224			size = (ctx->ctxvals_pos-offset)/8;
1225
1226		/* Strands 4-7: per-TP state */
1227		for (i = 0; i < 4; i++) {
1228			ctx->ctxvals_pos = offset + 4 + i;
1229			if (units & (1 << (2 * i)))
1230				nv50_graph_construct_xfer_tp(ctx);
1231			if (units & (1 << (2 * i + 1)))
1232				nv50_graph_construct_xfer_tp(ctx);
1233			if ((ctx->ctxvals_pos-offset)/8 > size)
1234				size = (ctx->ctxvals_pos-offset)/8;
1235		}
1236	} else {
1237		/* Strand 0 */
1238		ctx->ctxvals_pos = offset;
1239		nv50_graph_construct_gene_dispatch(ctx);
1240		nv50_graph_construct_gene_m2mf(ctx);
1241		nv50_graph_construct_gene_unk34xx(ctx);
1242		nv50_graph_construct_gene_csched(ctx);
1243		nv50_graph_construct_gene_unk1cxx(ctx);
1244		nv50_graph_construct_gene_strmout(ctx);
1245		if ((ctx->ctxvals_pos-offset)/8 > size)
1246			size = (ctx->ctxvals_pos-offset)/8;
1247
1248		/* Strand 1 */
1249		ctx->ctxvals_pos = offset + 1;
1250		nv50_graph_construct_gene_unk10xx(ctx);
1251		if ((ctx->ctxvals_pos-offset)/8 > size)
1252			size = (ctx->ctxvals_pos-offset)/8;
1253
1254		/* Strand 2 */
1255		ctx->ctxvals_pos = offset + 2;
1256		if (dev_priv->chipset == 0xa0)
1257			nv50_graph_construct_gene_unk14xx(ctx);
1258		nv50_graph_construct_gene_unk24xx(ctx);
1259		if ((ctx->ctxvals_pos-offset)/8 > size)
1260			size = (ctx->ctxvals_pos-offset)/8;
1261
1262		/* Strand 3 */
1263		ctx->ctxvals_pos = offset + 3;
1264		nv50_graph_construct_gene_vfetch(ctx);
1265		if ((ctx->ctxvals_pos-offset)/8 > size)
1266			size = (ctx->ctxvals_pos-offset)/8;
1267
1268		/* Strand 4 */
1269		ctx->ctxvals_pos = offset + 4;
1270		nv50_graph_construct_gene_ccache(ctx);
1271		if ((ctx->ctxvals_pos-offset)/8 > size)
1272			size = (ctx->ctxvals_pos-offset)/8;
1273
1274		/* Strand 5 */
1275		ctx->ctxvals_pos = offset + 5;
1276		nv50_graph_construct_gene_ropm2(ctx);
1277		nv50_graph_construct_gene_ropm1(ctx);
1278		/* per-ROP context */
1279		for (i = 0; i < 8; i++)
1280			if (units & (1<<(i+16)))
1281				nv50_graph_construct_gene_ropc(ctx);
1282		if ((ctx->ctxvals_pos-offset)/8 > size)
1283			size = (ctx->ctxvals_pos-offset)/8;
1284
1285		/* Strand 6 */
1286		ctx->ctxvals_pos = offset + 6;
1287		nv50_graph_construct_gene_zcull(ctx);
1288		nv50_graph_construct_gene_clipid(ctx);
1289		nv50_graph_construct_gene_eng2d(ctx);
1290		if (units & (1 << 0))
1291			nv50_graph_construct_xfer_tp(ctx);
1292		if (units & (1 << 1))
1293			nv50_graph_construct_xfer_tp(ctx);
1294		if (units & (1 << 2))
1295			nv50_graph_construct_xfer_tp(ctx);
1296		if (units & (1 << 3))
1297			nv50_graph_construct_xfer_tp(ctx);
1298		if ((ctx->ctxvals_pos-offset)/8 > size)
1299			size = (ctx->ctxvals_pos-offset)/8;
1300
1301		/* Strand 7 */
1302		ctx->ctxvals_pos = offset + 7;
1303		if (dev_priv->chipset == 0xa0) {
1304			if (units & (1 << 4))
1305				nv50_graph_construct_xfer_tp(ctx);
1306			if (units & (1 << 5))
1307				nv50_graph_construct_xfer_tp(ctx);
1308			if (units & (1 << 6))
1309				nv50_graph_construct_xfer_tp(ctx);
1310			if (units & (1 << 7))
1311				nv50_graph_construct_xfer_tp(ctx);
1312			if (units & (1 << 8))
1313				nv50_graph_construct_xfer_tp(ctx);
1314			if (units & (1 << 9))
1315				nv50_graph_construct_xfer_tp(ctx);
1316		} else {
1317			nv50_graph_construct_gene_unk14xx(ctx);
1318		}
1319		if ((ctx->ctxvals_pos-offset)/8 > size)
1320			size = (ctx->ctxvals_pos-offset)/8;
1321	}
1322
1323	ctx->ctxvals_pos = offset + size * 8;
1324	ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f;
1325	cp_lsr (ctx, offset);
1326	cp_out (ctx, CP_SET_XFER_POINTER);
1327	cp_lsr (ctx, size);
1328	cp_out (ctx, CP_SEEK_1);
1329	cp_out (ctx, CP_XFER_1);
1330	cp_wait(ctx, XFER, BUSY);
1331}
1332
1333/*
1334 * non-trivial demagiced parts of ctx init go here
1335 */
1336
1337static void
1338nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx)
1339{
1340	/* start of strand 0 */
1341	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1342	/* SEEK */
1343	if (dev_priv->chipset == 0x50)
1344		xf_emit(ctx, 5, 0);
1345	else if (!IS_NVA3F(dev_priv->chipset))
1346		xf_emit(ctx, 6, 0);
1347	else
1348		xf_emit(ctx, 4, 0);
1349	/* SEEK */
1350	/* the PGRAPH's internal FIFO */
1351	if (dev_priv->chipset == 0x50)
1352		xf_emit(ctx, 8*3, 0);
1353	else
1354		xf_emit(ctx, 0x100*3, 0);
1355	/* and another bonus slot?!? */
1356	xf_emit(ctx, 3, 0);
1357	/* and YET ANOTHER bonus slot? */
1358	if (IS_NVA3F(dev_priv->chipset))
1359		xf_emit(ctx, 3, 0);
1360	/* SEEK */
1361	/* CTX_SWITCH: caches of gr objects bound to subchannels. 8 values, last used index */
1362	xf_emit(ctx, 9, 0);
1363	/* SEEK */
1364	xf_emit(ctx, 9, 0);
1365	/* SEEK */
1366	xf_emit(ctx, 9, 0);
1367	/* SEEK */
1368	xf_emit(ctx, 9, 0);
1369	/* SEEK */
1370	if (dev_priv->chipset < 0x90)
1371		xf_emit(ctx, 4, 0);
1372	/* SEEK */
1373	xf_emit(ctx, 2, 0);
1374	/* SEEK */
1375	xf_emit(ctx, 6*2, 0);
1376	xf_emit(ctx, 2, 0);
1377	/* SEEK */
1378	xf_emit(ctx, 2, 0);
1379	/* SEEK */
1380	xf_emit(ctx, 6*2, 0);
1381	xf_emit(ctx, 2, 0);
1382	/* SEEK */
1383	if (dev_priv->chipset == 0x50)
1384		xf_emit(ctx, 0x1c, 0);
1385	else if (dev_priv->chipset < 0xa0)
1386		xf_emit(ctx, 0x1e, 0);
1387	else
1388		xf_emit(ctx, 0x22, 0);
1389	/* SEEK */
1390	xf_emit(ctx, 0x15, 0);
1391}
1392
1393static void
1394nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx)
1395{
1396	/* Strand 0, right after dispatch */
1397	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1398	int smallm2mf = 0;
1399	if (dev_priv->chipset < 0x92 || dev_priv->chipset == 0x98)
1400		smallm2mf = 1;
1401	/* SEEK */
1402	xf_emit (ctx, 1, 0);		/* DMA_NOTIFY instance >> 4 */
1403	xf_emit (ctx, 1, 0);		/* DMA_BUFFER_IN instance >> 4 */
1404	xf_emit (ctx, 1, 0);		/* DMA_BUFFER_OUT instance >> 4 */
1405	xf_emit (ctx, 1, 0);		/* OFFSET_IN */
1406	xf_emit (ctx, 1, 0);		/* OFFSET_OUT */
1407	xf_emit (ctx, 1, 0);		/* PITCH_IN */
1408	xf_emit (ctx, 1, 0);		/* PITCH_OUT */
1409	xf_emit (ctx, 1, 0);		/* LINE_LENGTH */
1410	xf_emit (ctx, 1, 0);		/* LINE_COUNT */
1411	xf_emit (ctx, 1, 0x21);		/* FORMAT: bits 0-4 INPUT_INC, bits 5-9 OUTPUT_INC */
1412	xf_emit (ctx, 1, 1);		/* LINEAR_IN */
1413	xf_emit (ctx, 1, 0x2);		/* TILING_MODE_IN: bits 0-2 y tiling, bits 3-5 z tiling */
1414	xf_emit (ctx, 1, 0x100);	/* TILING_PITCH_IN */
1415	xf_emit (ctx, 1, 0x100);	/* TILING_HEIGHT_IN */
1416	xf_emit (ctx, 1, 1);		/* TILING_DEPTH_IN */
1417	xf_emit (ctx, 1, 0);		/* TILING_POSITION_IN_Z */
1418	xf_emit (ctx, 1, 0);		/* TILING_POSITION_IN */
1419	xf_emit (ctx, 1, 1);		/* LINEAR_OUT */
1420	xf_emit (ctx, 1, 0x2);		/* TILING_MODE_OUT: bits 0-2 y tiling, bits 3-5 z tiling */
1421	xf_emit (ctx, 1, 0x100);	/* TILING_PITCH_OUT */
1422	xf_emit (ctx, 1, 0x100);	/* TILING_HEIGHT_OUT */
1423	xf_emit (ctx, 1, 1);		/* TILING_DEPTH_OUT */
1424	xf_emit (ctx, 1, 0);		/* TILING_POSITION_OUT_Z */
1425	xf_emit (ctx, 1, 0);		/* TILING_POSITION_OUT */
1426	xf_emit (ctx, 1, 0);		/* OFFSET_IN_HIGH */
1427	xf_emit (ctx, 1, 0);		/* OFFSET_OUT_HIGH */
1428	/* SEEK */
1429	if (smallm2mf)
1430		xf_emit(ctx, 0x40, 0);	/* 20 * ffffffff, 3ffff */
1431	else
1432		xf_emit(ctx, 0x100, 0);	/* 80 * ffffffff, 3ffff */
1433	xf_emit(ctx, 4, 0);		/* 1f/7f, 0, 1f/7f, 0 [1f for smallm2mf, 7f otherwise] */
1434	/* SEEK */
1435	if (smallm2mf)
1436		xf_emit(ctx, 0x400, 0);	/* ffffffff */
1437	else
1438		xf_emit(ctx, 0x800, 0);	/* ffffffff */
1439	xf_emit(ctx, 4, 0);		/* ff/1ff, 0, 0, 0 [ff for smallm2mf, 1ff otherwise] */
1440	/* SEEK */
1441	xf_emit(ctx, 0x40, 0);		/* 20 * bits ffffffff, 3ffff */
1442	xf_emit(ctx, 0x6, 0);		/* 1f, 0, 1f, 0, 1f, 0 */
1443}
1444
1445static void
1446nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx)
1447{
1448	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1449	xf_emit(ctx, 2, 0);		/* RO */
1450	xf_emit(ctx, 0x800, 0);		/* ffffffff */
1451	switch (dev_priv->chipset) {
1452	case 0x50:
1453	case 0x92:
1454	case 0xa0:
1455		xf_emit(ctx, 0x2b, 0);
1456		break;
1457	case 0x84:
1458		xf_emit(ctx, 0x29, 0);
1459		break;
1460	case 0x94:
1461	case 0x96:
1462	case 0xa3:
1463		xf_emit(ctx, 0x27, 0);
1464		break;
1465	case 0x86:
1466	case 0x98:
1467	case 0xa5:
1468	case 0xa8:
1469	case 0xaa:
1470	case 0xac:
1471	case 0xaf:
1472		xf_emit(ctx, 0x25, 0);
1473		break;
1474	}
1475	/* CB bindings, 0x80 of them. first word is address >> 8, second is
1476	 * size >> 4 | valid << 24 */
1477	xf_emit(ctx, 0x100, 0);		/* ffffffff CB_DEF */
1478	xf_emit(ctx, 1, 0);		/* 0000007f CB_ADDR_BUFFER */
1479	xf_emit(ctx, 1, 0);		/* 0 */
1480	xf_emit(ctx, 0x30, 0);		/* ff SET_PROGRAM_CB */
1481	xf_emit(ctx, 1, 0);		/* 3f last SET_PROGRAM_CB */
1482	xf_emit(ctx, 4, 0);		/* RO */
1483	xf_emit(ctx, 0x100, 0);		/* ffffffff */
1484	xf_emit(ctx, 8, 0);		/* 1f, 0, 0, ... */
1485	xf_emit(ctx, 8, 0);		/* ffffffff */
1486	xf_emit(ctx, 4, 0);		/* ffffffff */
1487	xf_emit(ctx, 1, 0);		/* 3 */
1488	xf_emit(ctx, 1, 0);		/* ffffffff */
1489	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_CODE_CB */
1490	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_TIC */
1491	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_TSC */
1492	xf_emit(ctx, 1, 0);		/* 00000001 LINKED_TSC */
1493	xf_emit(ctx, 1, 0);		/* 000000ff TIC_ADDRESS_HIGH */
1494	xf_emit(ctx, 1, 0);		/* ffffffff TIC_ADDRESS_LOW */
1495	xf_emit(ctx, 1, 0x3fffff);	/* 003fffff TIC_LIMIT */
1496	xf_emit(ctx, 1, 0);		/* 000000ff TSC_ADDRESS_HIGH */
1497	xf_emit(ctx, 1, 0);		/* ffffffff TSC_ADDRESS_LOW */
1498	xf_emit(ctx, 1, 0x1fff);	/* 000fffff TSC_LIMIT */
1499	xf_emit(ctx, 1, 0);		/* 000000ff VP_ADDRESS_HIGH */
1500	xf_emit(ctx, 1, 0);		/* ffffffff VP_ADDRESS_LOW */
1501	xf_emit(ctx, 1, 0);		/* 00ffffff VP_START_ID */
1502	xf_emit(ctx, 1, 0);		/* 000000ff CB_DEF_ADDRESS_HIGH */
1503	xf_emit(ctx, 1, 0);		/* ffffffff CB_DEF_ADDRESS_LOW */
1504	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1505	xf_emit(ctx, 1, 0);		/* 000000ff GP_ADDRESS_HIGH */
1506	xf_emit(ctx, 1, 0);		/* ffffffff GP_ADDRESS_LOW */
1507	xf_emit(ctx, 1, 0);		/* 00ffffff GP_START_ID */
1508	xf_emit(ctx, 1, 0);		/* 000000ff FP_ADDRESS_HIGH */
1509	xf_emit(ctx, 1, 0);		/* ffffffff FP_ADDRESS_LOW */
1510	xf_emit(ctx, 1, 0);		/* 00ffffff FP_START_ID */
1511}
1512
1513static void
1514nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx)
1515{
1516	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1517	int i;
1518	/* end of area 2 on pre-NVA0, area 1 on NVAx */
1519	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
1520	xf_emit(ctx, 1, 4);		/* 0000007f VP_RESULT_MAP_SIZE */
1521	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1522	xf_emit(ctx, 1, 0x80);		/* 0000ffff GP_VERTEX_OUTPUT_COUNT */
1523	xf_emit(ctx, 1, 4);		/* 000000ff GP_REG_ALLOC_RESULT */
1524	xf_emit(ctx, 1, 0x80c14);	/* 01ffffff SEMANTIC_COLOR */
1525	xf_emit(ctx, 1, 0);		/* 00000001 VERTEX_TWO_SIDE_ENABLE */
1526	if (dev_priv->chipset == 0x50)
1527		xf_emit(ctx, 1, 0x3ff);
1528	else
1529		xf_emit(ctx, 1, 0x7ff);	/* 000007ff */
1530	xf_emit(ctx, 1, 0);		/* 111/113 */
1531	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
1532	for (i = 0; i < 8; i++) {
1533		switch (dev_priv->chipset) {
1534		case 0x50:
1535		case 0x86:
1536		case 0x98:
1537		case 0xaa:
1538		case 0xac:
1539			xf_emit(ctx, 0xa0, 0);	/* ffffffff */
1540			break;
1541		case 0x84:
1542		case 0x92:
1543		case 0x94:
1544		case 0x96:
1545			xf_emit(ctx, 0x120, 0);
1546			break;
1547		case 0xa5:
1548		case 0xa8:
1549			xf_emit(ctx, 0x100, 0);	/* ffffffff */
1550			break;
1551		case 0xa0:
1552		case 0xa3:
1553		case 0xaf:
1554			xf_emit(ctx, 0x400, 0);	/* ffffffff */
1555			break;
1556		}
1557		xf_emit(ctx, 4, 0);	/* 3f, 0, 0, 0 */
1558		xf_emit(ctx, 4, 0);	/* ffffffff */
1559	}
1560	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
1561	xf_emit(ctx, 1, 4);		/* 0000007f VP_RESULT_MAP_SIZE */
1562	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1563	xf_emit(ctx, 1, 0x80);		/* 0000ffff GP_VERTEX_OUTPUT_COUNT */
1564	xf_emit(ctx, 1, 4);		/* 000000ff GP_REG_ALLOC_TEMP */
1565	xf_emit(ctx, 1, 1);		/* 00000001 RASTERIZE_ENABLE */
1566	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1900 */
1567	xf_emit(ctx, 1, 0x27);		/* 000000ff UNK0FD4 */
1568	xf_emit(ctx, 1, 0);		/* 0001ffff GP_BUILTIN_RESULT_EN */
1569	xf_emit(ctx, 1, 0x26);		/* 000000ff SEMANTIC_LAYER */
1570	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
1571}
1572
1573static void
1574nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx)
1575{
1576	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1577	/* end of area 2 on pre-NVA0, area 1 on NVAx */
1578	xf_emit(ctx, 1, 0);		/* 00000001 VIEWPORT_CLIP_RECTS_EN */
1579	xf_emit(ctx, 1, 0);		/* 00000003 VIEWPORT_CLIP_MODE */
1580	xf_emit(ctx, 0x10, 0x04000000);	/* 07ffffff VIEWPORT_CLIP_HORIZ*8, VIEWPORT_CLIP_VERT*8 */
1581	xf_emit(ctx, 1, 0);		/* 00000001 POLYGON_STIPPLE_ENABLE */
1582	xf_emit(ctx, 0x20, 0);		/* ffffffff POLYGON_STIPPLE */
1583	xf_emit(ctx, 2, 0);		/* 00007fff WINDOW_OFFSET_XY */
1584	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
1585	xf_emit(ctx, 1, 0x04e3bfdf);	/* ffffffff UNK0D64 */
1586	xf_emit(ctx, 1, 0x04e3bfdf);	/* ffffffff UNK0DF4 */
1587	xf_emit(ctx, 1, 0);		/* 00000003 WINDOW_ORIGIN */
1588	xf_emit(ctx, 1, 0);		/* 00000007 */
1589	xf_emit(ctx, 1, 0x1fe21);	/* 0001ffff tesla UNK0FAC */
1590	if (dev_priv->chipset >= 0xa0)
1591		xf_emit(ctx, 1, 0x0fac6881);
1592	if (IS_NVA3F(dev_priv->chipset)) {
1593		xf_emit(ctx, 1, 1);
1594		xf_emit(ctx, 3, 0);
1595	}
1596}
1597
1598static void
1599nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx)
1600{
1601	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1602	/* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */
1603	if (dev_priv->chipset != 0x50) {
1604		xf_emit(ctx, 5, 0);		/* ffffffff */
1605		xf_emit(ctx, 1, 0x80c14);	/* 01ffffff SEMANTIC_COLOR */
1606		xf_emit(ctx, 1, 0);		/* 00000001 */
1607		xf_emit(ctx, 1, 0);		/* 000003ff */
1608		xf_emit(ctx, 1, 0x804);		/* 00000fff SEMANTIC_CLIP */
1609		xf_emit(ctx, 1, 0);		/* 00000001 */
1610		xf_emit(ctx, 2, 4);		/* 7f, ff */
1611		xf_emit(ctx, 1, 0x8100c12);	/* 1fffffff FP_INTERPOLANT_CTRL */
1612	}
1613	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A30 */
1614	xf_emit(ctx, 1, 4);			/* 0000007f VP_RESULT_MAP_SIZE */
1615	xf_emit(ctx, 1, 4);			/* 000000ff GP_RESULT_MAP_SIZE */
1616	xf_emit(ctx, 1, 0);			/* 00000001 GP_ENABLE */
1617	xf_emit(ctx, 1, 0x10);			/* 7f/ff VIEW_VOLUME_CLIP_CTRL */
1618	xf_emit(ctx, 1, 0);			/* 000000ff VP_CLIP_DISTANCE_ENABLE */
1619	if (dev_priv->chipset != 0x50)
1620		xf_emit(ctx, 1, 0);		/* 3ff */
1621	xf_emit(ctx, 1, 0);			/* 000000ff tesla UNK1940 */
1622	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK0D7C */
1623	xf_emit(ctx, 1, 0x804);			/* 00000fff SEMANTIC_CLIP */
1624	xf_emit(ctx, 1, 1);			/* 00000001 VIEWPORT_TRANSFORM_EN */
1625	xf_emit(ctx, 1, 0x1a);			/* 0000001f POLYGON_MODE */
1626	if (dev_priv->chipset != 0x50)
1627		xf_emit(ctx, 1, 0x7f);		/* 000000ff tesla UNK0FFC */
1628	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A30 */
1629	xf_emit(ctx, 1, 1);			/* 00000001 SHADE_MODEL */
1630	xf_emit(ctx, 1, 0x80c14);		/* 01ffffff SEMANTIC_COLOR */
1631	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1900 */
1632	xf_emit(ctx, 1, 0x8100c12);		/* 1fffffff FP_INTERPOLANT_CTRL */
1633	xf_emit(ctx, 1, 4);			/* 0000007f VP_RESULT_MAP_SIZE */
1634	xf_emit(ctx, 1, 4);			/* 000000ff GP_RESULT_MAP_SIZE */
1635	xf_emit(ctx, 1, 0);			/* 00000001 GP_ENABLE */
1636	xf_emit(ctx, 1, 0x10);			/* 7f/ff VIEW_VOLUME_CLIP_CTRL */
1637	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK0D7C */
1638	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK0F8C */
1639	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A30 */
1640	xf_emit(ctx, 1, 1);			/* 00000001 VIEWPORT_TRANSFORM_EN */
1641	xf_emit(ctx, 1, 0x8100c12);		/* 1fffffff FP_INTERPOLANT_CTRL */
1642	xf_emit(ctx, 4, 0);			/* ffffffff NOPERSPECTIVE_BITMAP */
1643	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1900 */
1644	xf_emit(ctx, 1, 0);			/* 0000000f */
1645	if (dev_priv->chipset == 0x50)
1646		xf_emit(ctx, 1, 0x3ff);		/* 000003ff tesla UNK0D68 */
1647	else
1648		xf_emit(ctx, 1, 0x7ff);		/* 000007ff tesla UNK0D68 */
1649	xf_emit(ctx, 1, 0x80c14);		/* 01ffffff SEMANTIC_COLOR */
1650	xf_emit(ctx, 1, 0);			/* 00000001 VERTEX_TWO_SIDE_ENABLE */
1651	xf_emit(ctx, 0x30, 0);			/* ffffffff VIEWPORT_SCALE: X0, Y0, Z0, X1, Y1, ... */
1652	xf_emit(ctx, 3, 0);			/* f, 0, 0 */
1653	xf_emit(ctx, 3, 0);			/* ffffffff last VIEWPORT_SCALE? */
1654	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A30 */
1655	xf_emit(ctx, 1, 1);			/* 00000001 VIEWPORT_TRANSFORM_EN */
1656	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1900 */
1657	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1924 */
1658	xf_emit(ctx, 1, 0x10);			/* 000000ff VIEW_VOLUME_CLIP_CTRL */
1659	xf_emit(ctx, 1, 0);			/* 00000001 */
1660	xf_emit(ctx, 0x30, 0);			/* ffffffff VIEWPORT_TRANSLATE */
1661	xf_emit(ctx, 3, 0);			/* f, 0, 0 */
1662	xf_emit(ctx, 3, 0);			/* ffffffff */
1663	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A30 */
1664	xf_emit(ctx, 2, 0x88);			/* 000001ff tesla UNK19D8 */
1665	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1924 */
1666	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A30 */
1667	xf_emit(ctx, 1, 4);			/* 0000000f CULL_MODE */
1668	xf_emit(ctx, 2, 0);			/* 07ffffff SCREEN_SCISSOR */
1669	xf_emit(ctx, 2, 0);			/* 00007fff WINDOW_OFFSET_XY */
1670	xf_emit(ctx, 1, 0);			/* 00000003 WINDOW_ORIGIN */
1671	xf_emit(ctx, 0x10, 0);			/* 00000001 SCISSOR_ENABLE */
1672	xf_emit(ctx, 1, 0);			/* 0001ffff GP_BUILTIN_RESULT_EN */
1673	xf_emit(ctx, 1, 0x26);			/* 000000ff SEMANTIC_LAYER */
1674	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1900 */
1675	xf_emit(ctx, 1, 0);			/* 0000000f */
1676	xf_emit(ctx, 1, 0x3f800000);		/* ffffffff LINE_WIDTH */
1677	xf_emit(ctx, 1, 0);			/* 00000001 LINE_STIPPLE_ENABLE */
1678	xf_emit(ctx, 1, 0);			/* 00000001 LINE_SMOOTH_ENABLE */
1679	xf_emit(ctx, 1, 0);			/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
1680	if (IS_NVA3F(dev_priv->chipset))
1681		xf_emit(ctx, 1, 0);		/* 00000001 */
1682	xf_emit(ctx, 1, 0x1a);			/* 0000001f POLYGON_MODE */
1683	xf_emit(ctx, 1, 0x10);			/* 000000ff VIEW_VOLUME_CLIP_CTRL */
1684	if (dev_priv->chipset != 0x50) {
1685		xf_emit(ctx, 1, 0);		/* ffffffff */
1686		xf_emit(ctx, 1, 0);		/* 00000001 */
1687		xf_emit(ctx, 1, 0);		/* 000003ff */
1688	}
1689	xf_emit(ctx, 0x20, 0);			/* 10xbits ffffffff, 3fffff. SCISSOR_* */
1690	xf_emit(ctx, 1, 0);			/* f */
1691	xf_emit(ctx, 1, 0);			/* 0? */
1692	xf_emit(ctx, 1, 0);			/* ffffffff */
1693	xf_emit(ctx, 1, 0);			/* 003fffff */
1694	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A30 */
1695	xf_emit(ctx, 1, 0x52);			/* 000001ff SEMANTIC_PTSZ */
1696	xf_emit(ctx, 1, 0);			/* 0001ffff GP_BUILTIN_RESULT_EN */
1697	xf_emit(ctx, 1, 0x26);			/* 000000ff SEMANTIC_LAYER */
1698	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1900 */
1699	xf_emit(ctx, 1, 4);			/* 0000007f VP_RESULT_MAP_SIZE */
1700	xf_emit(ctx, 1, 4);			/* 000000ff GP_RESULT_MAP_SIZE */
1701	xf_emit(ctx, 1, 0);			/* 00000001 GP_ENABLE */
1702	xf_emit(ctx, 1, 0x1a);			/* 0000001f POLYGON_MODE */
1703	xf_emit(ctx, 1, 0);			/* 00000001 LINE_SMOOTH_ENABLE */
1704	xf_emit(ctx, 1, 0);			/* 00000001 LINE_STIPPLE_ENABLE */
1705	xf_emit(ctx, 1, 0x00ffff00);		/* 00ffffff LINE_STIPPLE_PATTERN */
1706	xf_emit(ctx, 1, 0);			/* 0000000f */
1707}
1708
1709static void
1710nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx)
1711{
1712	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1713	/* end of strand 0 on pre-NVA0, beginning of strand 6 on NVAx */
1714	/* SEEK */
1715	xf_emit(ctx, 1, 0x3f);		/* 0000003f UNK1590 */
1716	xf_emit(ctx, 1, 0);		/* 00000001 ALPHA_TEST_ENABLE */
1717	xf_emit(ctx, 1, 0);		/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
1718	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
1719	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_BACK_FUNC_FUNC */
1720	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_MASK */
1721	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_REF */
1722	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_MASK */
1723	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */
1724	xf_emit(ctx, 1, 2);		/* 00000003 tesla UNK143C */
1725	xf_emit(ctx, 2, 0x04000000);	/* 07ffffff tesla UNK0D6C */
1726	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
1727	xf_emit(ctx, 1, 0);		/* 00000001 CLIPID_ENABLE */
1728	xf_emit(ctx, 2, 0);		/* ffffffff DEPTH_BOUNDS */
1729	xf_emit(ctx, 1, 0);		/* 00000001 */
1730	xf_emit(ctx, 1, 0);		/* 00000007 DEPTH_TEST_FUNC */
1731	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
1732	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
1733	xf_emit(ctx, 1, 4);		/* 0000000f CULL_MODE */
1734	xf_emit(ctx, 1, 0);		/* 0000ffff */
1735	xf_emit(ctx, 1, 0);		/* 00000001 UNK0FB0 */
1736	xf_emit(ctx, 1, 0);		/* 00000001 POLYGON_STIPPLE_ENABLE */
1737	xf_emit(ctx, 1, 4);		/* 00000007 FP_CONTROL */
1738	xf_emit(ctx, 1, 0);		/* ffffffff */
1739	xf_emit(ctx, 1, 0);		/* 0001ffff GP_BUILTIN_RESULT_EN */
1740	xf_emit(ctx, 1, 0);		/* 000000ff CLEAR_STENCIL */
1741	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_FRONT_FUNC_FUNC */
1742	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_MASK */
1743	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_REF */
1744	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_MASK */
1745	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */
1746	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
1747	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_BACK_ENABLE */
1748	xf_emit(ctx, 1, 0);		/* ffffffff CLEAR_DEPTH */
1749	xf_emit(ctx, 1, 0);		/* 00000007 */
1750	if (dev_priv->chipset != 0x50)
1751		xf_emit(ctx, 1, 0);	/* 00000003 tesla UNK1108 */
1752	xf_emit(ctx, 1, 0);		/* 00000001 SAMPLECNT_ENABLE */
1753	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
1754	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
1755	xf_emit(ctx, 1, 0x1001);	/* 00001fff ZETA_ARRAY_MODE */
1756	/* SEEK */
1757	xf_emit(ctx, 4, 0xffff);	/* 0000ffff MSAA_MASK */
1758	xf_emit(ctx, 0x10, 0);		/* 00000001 SCISSOR_ENABLE */
1759	xf_emit(ctx, 0x10, 0);		/* ffffffff DEPTH_RANGE_NEAR */
1760	xf_emit(ctx, 0x10, 0x3f800000);	/* ffffffff DEPTH_RANGE_FAR */
1761	xf_emit(ctx, 1, 0x10);		/* 7f/ff/3ff VIEW_VOLUME_CLIP_CTRL */
1762	xf_emit(ctx, 1, 0);		/* 00000001 VIEWPORT_CLIP_RECTS_EN */
1763	xf_emit(ctx, 1, 3);		/* 00000003 FP_CTRL_UNK196C */
1764	xf_emit(ctx, 1, 0);		/* 00000003 tesla UNK1968 */
1765	if (dev_priv->chipset != 0x50)
1766		xf_emit(ctx, 1, 0);	/* 0fffffff tesla UNK1104 */
1767	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK151C */
1768}
1769
1770static void
1771nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx)
1772{
1773	/* middle of strand 0 on pre-NVA0 [after 24xx], middle of area 6 on NVAx */
1774	/* SEEK */
1775	xf_emit(ctx, 1, 0);		/* 00000007 UNK0FB4 */
1776	/* SEEK */
1777	xf_emit(ctx, 4, 0);		/* 07ffffff CLIPID_REGION_HORIZ */
1778	xf_emit(ctx, 4, 0);		/* 07ffffff CLIPID_REGION_VERT */
1779	xf_emit(ctx, 2, 0);		/* 07ffffff SCREEN_SCISSOR */
1780	xf_emit(ctx, 2, 0x04000000);	/* 07ffffff UNK1508 */
1781	xf_emit(ctx, 1, 0);		/* 00000001 CLIPID_ENABLE */
1782	xf_emit(ctx, 1, 0x80);		/* 00003fff CLIPID_WIDTH */
1783	xf_emit(ctx, 1, 0);		/* 000000ff CLIPID_ID */
1784	xf_emit(ctx, 1, 0);		/* 000000ff CLIPID_ADDRESS_HIGH */
1785	xf_emit(ctx, 1, 0);		/* ffffffff CLIPID_ADDRESS_LOW */
1786	xf_emit(ctx, 1, 0x80);		/* 00003fff CLIPID_HEIGHT */
1787	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_CLIPID */
1788}
1789
1790static void
1791nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx)
1792{
1793	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1794	int i;
1795	/* middle of strand 0 on pre-NVA0 [after m2mf], end of strand 2 on NVAx */
1796	/* SEEK */
1797	xf_emit(ctx, 0x33, 0);
1798	/* SEEK */
1799	xf_emit(ctx, 2, 0);
1800	/* SEEK */
1801	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1802	xf_emit(ctx, 1, 4);		/* 0000007f VP_RESULT_MAP_SIZE */
1803	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
1804	/* SEEK */
1805	if (IS_NVA3F(dev_priv->chipset)) {
1806		xf_emit(ctx, 4, 0);	/* RO */
1807		xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */
1808		xf_emit(ctx, 1, 0);	/* 1ff */
1809		xf_emit(ctx, 8, 0);	/* 0? */
1810		xf_emit(ctx, 9, 0);	/* ffffffff, 7ff */
1811
1812		xf_emit(ctx, 4, 0);	/* RO */
1813		xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */
1814		xf_emit(ctx, 1, 0);	/* 1ff */
1815		xf_emit(ctx, 8, 0);	/* 0? */
1816		xf_emit(ctx, 9, 0);	/* ffffffff, 7ff */
1817	} else {
1818		xf_emit(ctx, 0xc, 0);	/* RO */
1819		/* SEEK */
1820		xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */
1821		xf_emit(ctx, 1, 0);	/* 1ff */
1822		xf_emit(ctx, 8, 0);	/* 0? */
1823
1824		/* SEEK */
1825		xf_emit(ctx, 0xc, 0);	/* RO */
1826		/* SEEK */
1827		xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */
1828		xf_emit(ctx, 1, 0);	/* 1ff */
1829		xf_emit(ctx, 8, 0);	/* 0? */
1830	}
1831	/* SEEK */
1832	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1833	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
1834	xf_emit(ctx, 1, 4);		/* 0000007f VP_RESULT_MAP_SIZE */
1835	xf_emit(ctx, 1, 0x8100c12);	/* 1fffffff FP_INTERPOLANT_CTRL */
1836	if (dev_priv->chipset != 0x50)
1837		xf_emit(ctx, 1, 3);	/* 00000003 tesla UNK1100 */
1838	/* SEEK */
1839	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1840	xf_emit(ctx, 1, 0x8100c12);	/* 1fffffff FP_INTERPOLANT_CTRL */
1841	xf_emit(ctx, 1, 0);		/* 0000000f VP_GP_BUILTIN_ATTR_EN */
1842	xf_emit(ctx, 1, 0x80c14);	/* 01ffffff SEMANTIC_COLOR */
1843	xf_emit(ctx, 1, 1);		/* 00000001 */
1844	/* SEEK */
1845	if (dev_priv->chipset >= 0xa0)
1846		xf_emit(ctx, 2, 4);	/* 000000ff */
1847	xf_emit(ctx, 1, 0x80c14);	/* 01ffffff SEMANTIC_COLOR */
1848	xf_emit(ctx, 1, 0);		/* 00000001 VERTEX_TWO_SIDE_ENABLE */
1849	xf_emit(ctx, 1, 0);		/* 00000001 POINT_SPRITE_ENABLE */
1850	xf_emit(ctx, 1, 0x8100c12);	/* 1fffffff FP_INTERPOLANT_CTRL */
1851	xf_emit(ctx, 1, 0x27);		/* 000000ff SEMANTIC_PRIM_ID */
1852	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1853	xf_emit(ctx, 1, 0);		/* 0000000f */
1854	xf_emit(ctx, 1, 1);		/* 00000001 */
1855	for (i = 0; i < 10; i++) {
1856		/* SEEK */
1857		xf_emit(ctx, 0x40, 0);		/* ffffffff */
1858		xf_emit(ctx, 0x10, 0);		/* 3, 0, 0.... */
1859		xf_emit(ctx, 0x10, 0);		/* ffffffff */
1860	}
1861	/* SEEK */
1862	xf_emit(ctx, 1, 0);		/* 00000001 POINT_SPRITE_CTRL */
1863	xf_emit(ctx, 1, 1);		/* 00000001 */
1864	xf_emit(ctx, 1, 0);		/* ffffffff */
1865	xf_emit(ctx, 4, 0);		/* ffffffff NOPERSPECTIVE_BITMAP */
1866	xf_emit(ctx, 0x10, 0);		/* 00ffffff POINT_COORD_REPLACE_MAP */
1867	xf_emit(ctx, 1, 0);		/* 00000003 WINDOW_ORIGIN */
1868	xf_emit(ctx, 1, 0x8100c12);	/* 1fffffff FP_INTERPOLANT_CTRL */
1869	if (dev_priv->chipset != 0x50)
1870		xf_emit(ctx, 1, 0);	/* 000003ff */
1871}
1872
1873static void
1874nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx)
1875{
1876	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
1877	int acnt = 0x10, rep, i;
1878	/* beginning of strand 1 on pre-NVA0, strand 3 on NVAx */
1879	if (IS_NVA3F(dev_priv->chipset))
1880		acnt = 0x20;
1881	/* SEEK */
1882	if (dev_priv->chipset >= 0xa0) {
1883		xf_emit(ctx, 1, 0);	/* ffffffff tesla UNK13A4 */
1884		xf_emit(ctx, 1, 1);	/* 00000fff tesla UNK1318 */
1885	}
1886	xf_emit(ctx, 1, 0);		/* ffffffff VERTEX_BUFFER_FIRST */
1887	xf_emit(ctx, 1, 0);		/* 00000001 PRIMITIVE_RESTART_ENABLE */
1888	xf_emit(ctx, 1, 0);		/* 00000001 UNK0DE8 */
1889	xf_emit(ctx, 1, 0);		/* ffffffff PRIMITIVE_RESTART_INDEX */
1890	xf_emit(ctx, 1, 0xf);		/* ffffffff VP_ATTR_EN */
1891	xf_emit(ctx, (acnt/8)-1, 0);	/* ffffffff VP_ATTR_EN */
1892	xf_emit(ctx, acnt/8, 0);	/* ffffffff VTX_ATR_MASK_UNK0DD0 */
1893	xf_emit(ctx, 1, 0);		/* 0000000f VP_GP_BUILTIN_ATTR_EN */
1894	xf_emit(ctx, 1, 0x20);		/* 0000ffff tesla UNK129C */
1895	xf_emit(ctx, 1, 0);		/* 000000ff turing UNK370??? */
1896	xf_emit(ctx, 1, 0);		/* 0000ffff turing USER_PARAM_COUNT */
1897	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
1898	/* SEEK */
1899	if (IS_NVA3F(dev_priv->chipset))
1900		xf_emit(ctx, 0xb, 0);	/* RO */
1901	else if (dev_priv->chipset >= 0xa0)
1902		xf_emit(ctx, 0x9, 0);	/* RO */
1903	else
1904		xf_emit(ctx, 0x8, 0);	/* RO */
1905	/* SEEK */
1906	xf_emit(ctx, 1, 0);		/* 00000001 EDGE_FLAG */
1907	xf_emit(ctx, 1, 0);		/* 00000001 PROVOKING_VERTEX_LAST */
1908	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1909	xf_emit(ctx, 1, 0x1a);		/* 0000001f POLYGON_MODE */
1910	/* SEEK */
1911	xf_emit(ctx, 0xc, 0);		/* RO */
1912	/* SEEK */
1913	xf_emit(ctx, 1, 0);		/* 7f/ff */
1914	xf_emit(ctx, 1, 4);		/* 7f/ff VP_REG_ALLOC_RESULT */
1915	xf_emit(ctx, 1, 4);		/* 7f/ff VP_RESULT_MAP_SIZE */
1916	xf_emit(ctx, 1, 0);		/* 0000000f VP_GP_BUILTIN_ATTR_EN */
1917	xf_emit(ctx, 1, 4);		/* 000001ff UNK1A28 */
1918	xf_emit(ctx, 1, 8);		/* 000001ff UNK0DF0 */
1919	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
1920	if (dev_priv->chipset == 0x50)
1921		xf_emit(ctx, 1, 0x3ff);	/* 3ff tesla UNK0D68 */
1922	else
1923		xf_emit(ctx, 1, 0x7ff);	/* 7ff tesla UNK0D68 */
1924	if (dev_priv->chipset == 0xa8)
1925		xf_emit(ctx, 1, 0x1e00);	/* 7fff */
1926	/* SEEK */
1927	xf_emit(ctx, 0xc, 0);		/* RO or close */
1928	/* SEEK */
1929	xf_emit(ctx, 1, 0xf);		/* ffffffff VP_ATTR_EN */
1930	xf_emit(ctx, (acnt/8)-1, 0);	/* ffffffff VP_ATTR_EN */
1931	xf_emit(ctx, 1, 0);		/* 0000000f VP_GP_BUILTIN_ATTR_EN */
1932	if (dev_priv->chipset > 0x50 && dev_priv->chipset < 0xa0)
1933		xf_emit(ctx, 2, 0);	/* ffffffff */
1934	else
1935		xf_emit(ctx, 1, 0);	/* ffffffff */
1936	xf_emit(ctx, 1, 0);		/* 00000003 tesla UNK0FD8 */
1937	/* SEEK */
1938	if (IS_NVA3F(dev_priv->chipset)) {
1939		xf_emit(ctx, 0x10, 0);	/* 0? */
1940		xf_emit(ctx, 2, 0);	/* weird... */
1941		xf_emit(ctx, 2, 0);	/* RO */
1942	} else {
1943		xf_emit(ctx, 8, 0);	/* 0? */
1944		xf_emit(ctx, 1, 0);	/* weird... */
1945		xf_emit(ctx, 2, 0);	/* RO */
1946	}
1947	/* SEEK */
1948	xf_emit(ctx, 1, 0);		/* ffffffff VB_ELEMENT_BASE */
1949	xf_emit(ctx, 1, 0);		/* ffffffff UNK1438 */
1950	xf_emit(ctx, acnt, 0);		/* 1 tesla UNK1000 */
1951	if (dev_priv->chipset >= 0xa0)
1952		xf_emit(ctx, 1, 0);	/* ffffffff tesla UNK1118? */
1953	/* SEEK */
1954	xf_emit(ctx, acnt, 0);		/* ffffffff VERTEX_ARRAY_UNK90C */
1955	xf_emit(ctx, 1, 0);		/* f/1f */
1956	/* SEEK */
1957	xf_emit(ctx, acnt, 0);		/* ffffffff VERTEX_ARRAY_UNK90C */
1958	xf_emit(ctx, 1, 0);		/* f/1f */
1959	/* SEEK */
1960	xf_emit(ctx, acnt, 0);		/* RO */
1961	xf_emit(ctx, 2, 0);		/* RO */
1962	/* SEEK */
1963	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK111C? */
1964	xf_emit(ctx, 1, 0);		/* RO */
1965	/* SEEK */
1966	xf_emit(ctx, 1, 0);		/* 000000ff UNK15F4_ADDRESS_HIGH */
1967	xf_emit(ctx, 1, 0);		/* ffffffff UNK15F4_ADDRESS_LOW */
1968	xf_emit(ctx, 1, 0);		/* 000000ff UNK0F84_ADDRESS_HIGH */
1969	xf_emit(ctx, 1, 0);		/* ffffffff UNK0F84_ADDRESS_LOW */
1970	/* SEEK */
1971	xf_emit(ctx, acnt, 0);		/* 00003fff VERTEX_ARRAY_ATTRIB_OFFSET */
1972	xf_emit(ctx, 3, 0);		/* f/1f */
1973	/* SEEK */
1974	xf_emit(ctx, acnt, 0);		/* 00000fff VERTEX_ARRAY_STRIDE */
1975	xf_emit(ctx, 3, 0);		/* f/1f */
1976	/* SEEK */
1977	xf_emit(ctx, acnt, 0);		/* ffffffff VERTEX_ARRAY_LOW */
1978	xf_emit(ctx, 3, 0);		/* f/1f */
1979	/* SEEK */
1980	xf_emit(ctx, acnt, 0);		/* 000000ff VERTEX_ARRAY_HIGH */
1981	xf_emit(ctx, 3, 0);		/* f/1f */
1982	/* SEEK */
1983	xf_emit(ctx, acnt, 0);		/* ffffffff VERTEX_LIMIT_LOW */
1984	xf_emit(ctx, 3, 0);		/* f/1f */
1985	/* SEEK */
1986	xf_emit(ctx, acnt, 0);		/* 000000ff VERTEX_LIMIT_HIGH */
1987	xf_emit(ctx, 3, 0);		/* f/1f */
1988	/* SEEK */
1989	if (IS_NVA3F(dev_priv->chipset)) {
1990		xf_emit(ctx, acnt, 0);		/* f */
1991		xf_emit(ctx, 3, 0);		/* f/1f */
1992	}
1993	/* SEEK */
1994	if (IS_NVA3F(dev_priv->chipset))
1995		xf_emit(ctx, 2, 0);	/* RO */
1996	else
1997		xf_emit(ctx, 5, 0);	/* RO */
1998	/* SEEK */
1999	xf_emit(ctx, 1, 0);		/* ffff DMA_VTXBUF */
2000	/* SEEK */
2001	if (dev_priv->chipset < 0xa0) {
2002		xf_emit(ctx, 0x41, 0);	/* RO */
2003		/* SEEK */
2004		xf_emit(ctx, 0x11, 0);	/* RO */
2005	} else if (!IS_NVA3F(dev_priv->chipset))
2006		xf_emit(ctx, 0x50, 0);	/* RO */
2007	else
2008		xf_emit(ctx, 0x58, 0);	/* RO */
2009	/* SEEK */
2010	xf_emit(ctx, 1, 0xf);		/* ffffffff VP_ATTR_EN */
2011	xf_emit(ctx, (acnt/8)-1, 0);	/* ffffffff VP_ATTR_EN */
2012	xf_emit(ctx, 1, 1);		/* 1 UNK0DEC */
2013	/* SEEK */
2014	xf_emit(ctx, acnt*4, 0);	/* ffffffff VTX_ATTR */
2015	xf_emit(ctx, 4, 0);		/* f/1f, 0, 0, 0 */
2016	/* SEEK */
2017	if (IS_NVA3F(dev_priv->chipset))
2018		xf_emit(ctx, 0x1d, 0);	/* RO */
2019	else
2020		xf_emit(ctx, 0x16, 0);	/* RO */
2021	/* SEEK */
2022	xf_emit(ctx, 1, 0xf);		/* ffffffff VP_ATTR_EN */
2023	xf_emit(ctx, (acnt/8)-1, 0);	/* ffffffff VP_ATTR_EN */
2024	/* SEEK */
2025	if (dev_priv->chipset < 0xa0)
2026		xf_emit(ctx, 8, 0);	/* RO */
2027	else if (IS_NVA3F(dev_priv->chipset))
2028		xf_emit(ctx, 0xc, 0);	/* RO */
2029	else
2030		xf_emit(ctx, 7, 0);	/* RO */
2031	/* SEEK */
2032	xf_emit(ctx, 0xa, 0);		/* RO */
2033	if (dev_priv->chipset == 0xa0)
2034		rep = 0xc;
2035	else
2036		rep = 4;
2037	for (i = 0; i < rep; i++) {
2038		/* SEEK */
2039		if (IS_NVA3F(dev_priv->chipset))
2040			xf_emit(ctx, 0x20, 0);	/* ffffffff */
2041		xf_emit(ctx, 0x200, 0);	/* ffffffff */
2042		xf_emit(ctx, 4, 0);	/* 7f/ff, 0, 0, 0 */
2043		xf_emit(ctx, 4, 0);	/* ffffffff */
2044	}
2045	/* SEEK */
2046	xf_emit(ctx, 1, 0);		/* 113/111 */
2047	xf_emit(ctx, 1, 0xf);		/* ffffffff VP_ATTR_EN */
2048	xf_emit(ctx, (acnt/8)-1, 0);	/* ffffffff VP_ATTR_EN */
2049	xf_emit(ctx, acnt/8, 0);	/* ffffffff VTX_ATTR_MASK_UNK0DD0 */
2050	xf_emit(ctx, 1, 0);		/* 0000000f VP_GP_BUILTIN_ATTR_EN */
2051	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2052	/* SEEK */
2053	if (IS_NVA3F(dev_priv->chipset))
2054		xf_emit(ctx, 7, 0);	/* weird... */
2055	else
2056		xf_emit(ctx, 5, 0);	/* weird... */
2057}
2058
2059static void
2060nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx)
2061{
2062	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2063	/* middle of strand 1 on pre-NVA0 [after vfetch], middle of strand 6 on NVAx */
2064	/* SEEK */
2065	xf_emit(ctx, 2, 0);		/* 0001ffff CLIP_X, CLIP_Y */
2066	xf_emit(ctx, 2, 0);		/* 0000ffff CLIP_W, CLIP_H */
2067	xf_emit(ctx, 1, 0);		/* 00000001 CLIP_ENABLE */
2068	if (dev_priv->chipset < 0xa0) {
2069		/* this is useless on everything but the original NV50,
2070		 * guess they forgot to nuke it. Or just didn't bother. */
2071		xf_emit(ctx, 2, 0);	/* 0000ffff IFC_CLIP_X, Y */
2072		xf_emit(ctx, 2, 1);	/* 0000ffff IFC_CLIP_W, H */
2073		xf_emit(ctx, 1, 0);	/* 00000001 IFC_CLIP_ENABLE */
2074	}
2075	xf_emit(ctx, 1, 1);		/* 00000001 DST_LINEAR */
2076	xf_emit(ctx, 1, 0x100);		/* 0001ffff DST_WIDTH */
2077	xf_emit(ctx, 1, 0x100);		/* 0001ffff DST_HEIGHT */
2078	xf_emit(ctx, 1, 0x11);		/* 3f[NV50]/7f[NV84+] DST_FORMAT */
2079	xf_emit(ctx, 1, 0);		/* 0001ffff DRAW_POINT_X */
2080	xf_emit(ctx, 1, 8);		/* 0000000f DRAW_UNK58C */
2081	xf_emit(ctx, 1, 0);		/* 000fffff SIFC_DST_X_FRACT */
2082	xf_emit(ctx, 1, 0);		/* 0001ffff SIFC_DST_X_INT */
2083	xf_emit(ctx, 1, 0);		/* 000fffff SIFC_DST_Y_FRACT */
2084	xf_emit(ctx, 1, 0);		/* 0001ffff SIFC_DST_Y_INT */
2085	xf_emit(ctx, 1, 0);		/* 000fffff SIFC_DX_DU_FRACT */
2086	xf_emit(ctx, 1, 1);		/* 0001ffff SIFC_DX_DU_INT */
2087	xf_emit(ctx, 1, 0);		/* 000fffff SIFC_DY_DV_FRACT */
2088	xf_emit(ctx, 1, 1);		/* 0001ffff SIFC_DY_DV_INT */
2089	xf_emit(ctx, 1, 1);		/* 0000ffff SIFC_WIDTH */
2090	xf_emit(ctx, 1, 1);		/* 0000ffff SIFC_HEIGHT */
2091	xf_emit(ctx, 1, 0xcf);		/* 000000ff SIFC_FORMAT */
2092	xf_emit(ctx, 1, 2);		/* 00000003 SIFC_BITMAP_UNK808 */
2093	xf_emit(ctx, 1, 0);		/* 00000003 SIFC_BITMAP_LINE_PACK_MODE */
2094	xf_emit(ctx, 1, 0);		/* 00000001 SIFC_BITMAP_LSB_FIRST */
2095	xf_emit(ctx, 1, 0);		/* 00000001 SIFC_BITMAP_ENABLE */
2096	xf_emit(ctx, 1, 0);		/* 0000ffff BLIT_DST_X */
2097	xf_emit(ctx, 1, 0);		/* 0000ffff BLIT_DST_Y */
2098	xf_emit(ctx, 1, 0);		/* 000fffff BLIT_DU_DX_FRACT */
2099	xf_emit(ctx, 1, 1);		/* 0001ffff BLIT_DU_DX_INT */
2100	xf_emit(ctx, 1, 0);		/* 000fffff BLIT_DV_DY_FRACT */
2101	xf_emit(ctx, 1, 1);		/* 0001ffff BLIT_DV_DY_INT */
2102	xf_emit(ctx, 1, 1);		/* 0000ffff BLIT_DST_W */
2103	xf_emit(ctx, 1, 1);		/* 0000ffff BLIT_DST_H */
2104	xf_emit(ctx, 1, 0);		/* 000fffff BLIT_SRC_X_FRACT */
2105	xf_emit(ctx, 1, 0);		/* 0001ffff BLIT_SRC_X_INT */
2106	xf_emit(ctx, 1, 0);		/* 000fffff BLIT_SRC_Y_FRACT */
2107	xf_emit(ctx, 1, 0);		/* 00000001 UNK888 */
2108	xf_emit(ctx, 1, 4);		/* 0000003f UNK884 */
2109	xf_emit(ctx, 1, 0);		/* 00000007 UNK880 */
2110	xf_emit(ctx, 1, 1);		/* 0000001f tesla UNK0FB8 */
2111	xf_emit(ctx, 1, 0x15);		/* 000000ff tesla UNK128C */
2112	xf_emit(ctx, 2, 0);		/* 00000007, ffff0ff3 */
2113	xf_emit(ctx, 1, 0);		/* 00000001 UNK260 */
2114	xf_emit(ctx, 1, 0x4444480);	/* 1fffffff UNK870 */
2115	/* SEEK */
2116	xf_emit(ctx, 0x10, 0);
2117	/* SEEK */
2118	xf_emit(ctx, 0x27, 0);
2119}
2120
2121static void
2122nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx)
2123{
2124	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2125	/* middle of strand 1 on pre-NVA0 [after eng2d], middle of strand 0 on NVAx */
2126	/* SEEK */
2127	xf_emit(ctx, 2, 0);		/* 00007fff WINDOW_OFFSET_XY... what is it doing here??? */
2128	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1924 */
2129	xf_emit(ctx, 1, 0);		/* 00000003 WINDOW_ORIGIN */
2130	xf_emit(ctx, 1, 0x8100c12);	/* 1fffffff FP_INTERPOLANT_CTRL */
2131	xf_emit(ctx, 1, 0);		/* 000003ff */
2132	/* SEEK */
2133	xf_emit(ctx, 1, 0);		/* ffffffff turing UNK364 */
2134	xf_emit(ctx, 1, 0);		/* 0000000f turing UNK36C */
2135	xf_emit(ctx, 1, 0);		/* 0000ffff USER_PARAM_COUNT */
2136	xf_emit(ctx, 1, 0x100);		/* 00ffffff turing UNK384 */
2137	xf_emit(ctx, 1, 0);		/* 0000000f turing UNK2A0 */
2138	xf_emit(ctx, 1, 0);		/* 0000ffff GRIDID */
2139	xf_emit(ctx, 1, 0x10001);	/* ffffffff GRIDDIM_XY */
2140	xf_emit(ctx, 1, 0);		/* ffffffff */
2141	xf_emit(ctx, 1, 0x10001);	/* ffffffff BLOCKDIM_XY */
2142	xf_emit(ctx, 1, 1);		/* 0000ffff BLOCKDIM_Z */
2143	xf_emit(ctx, 1, 0x10001);	/* 00ffffff BLOCK_ALLOC */
2144	xf_emit(ctx, 1, 1);		/* 00000001 LANES32 */
2145	xf_emit(ctx, 1, 4);		/* 000000ff FP_REG_ALLOC_TEMP */
2146	xf_emit(ctx, 1, 2);		/* 00000003 REG_MODE */
2147	/* SEEK */
2148	xf_emit(ctx, 0x40, 0);		/* ffffffff USER_PARAM */
2149	switch (dev_priv->chipset) {
2150	case 0x50:
2151	case 0x92:
2152		xf_emit(ctx, 8, 0);	/* 7, 0, 0, 0, ... */
2153		xf_emit(ctx, 0x80, 0);	/* fff */
2154		xf_emit(ctx, 2, 0);	/* ff, fff */
2155		xf_emit(ctx, 0x10*2, 0);	/* ffffffff, 1f */
2156		break;
2157	case 0x84:
2158		xf_emit(ctx, 8, 0);	/* 7, 0, 0, 0, ... */
2159		xf_emit(ctx, 0x60, 0);	/* fff */
2160		xf_emit(ctx, 2, 0);	/* ff, fff */
2161		xf_emit(ctx, 0xc*2, 0);	/* ffffffff, 1f */
2162		break;
2163	case 0x94:
2164	case 0x96:
2165		xf_emit(ctx, 8, 0);	/* 7, 0, 0, 0, ... */
2166		xf_emit(ctx, 0x40, 0);	/* fff */
2167		xf_emit(ctx, 2, 0);	/* ff, fff */
2168		xf_emit(ctx, 8*2, 0);	/* ffffffff, 1f */
2169		break;
2170	case 0x86:
2171	case 0x98:
2172		xf_emit(ctx, 4, 0);	/* f, 0, 0, 0 */
2173		xf_emit(ctx, 0x10, 0);	/* fff */
2174		xf_emit(ctx, 2, 0);	/* ff, fff */
2175		xf_emit(ctx, 2*2, 0);	/* ffffffff, 1f */
2176		break;
2177	case 0xa0:
2178		xf_emit(ctx, 8, 0);	/* 7, 0, 0, 0, ... */
2179		xf_emit(ctx, 0xf0, 0);	/* fff */
2180		xf_emit(ctx, 2, 0);	/* ff, fff */
2181		xf_emit(ctx, 0x1e*2, 0);	/* ffffffff, 1f */
2182		break;
2183	case 0xa3:
2184		xf_emit(ctx, 8, 0);	/* 7, 0, 0, 0, ... */
2185		xf_emit(ctx, 0x60, 0);	/* fff */
2186		xf_emit(ctx, 2, 0);	/* ff, fff */
2187		xf_emit(ctx, 0xc*2, 0);	/* ffffffff, 1f */
2188		break;
2189	case 0xa5:
2190	case 0xaf:
2191		xf_emit(ctx, 8, 0);	/* 7, 0, 0, 0, ... */
2192		xf_emit(ctx, 0x30, 0);	/* fff */
2193		xf_emit(ctx, 2, 0);	/* ff, fff */
2194		xf_emit(ctx, 6*2, 0);	/* ffffffff, 1f */
2195		break;
2196	case 0xaa:
2197		xf_emit(ctx, 0x12, 0);
2198		break;
2199	case 0xa8:
2200	case 0xac:
2201		xf_emit(ctx, 4, 0);	/* f, 0, 0, 0 */
2202		xf_emit(ctx, 0x10, 0);	/* fff */
2203		xf_emit(ctx, 2, 0);	/* ff, fff */
2204		xf_emit(ctx, 2*2, 0);	/* ffffffff, 1f */
2205		break;
2206	}
2207	xf_emit(ctx, 1, 0);		/* 0000000f */
2208	xf_emit(ctx, 1, 0);		/* 00000000 */
2209	xf_emit(ctx, 1, 0);		/* ffffffff */
2210	xf_emit(ctx, 1, 0);		/* 0000001f */
2211	xf_emit(ctx, 4, 0);		/* ffffffff */
2212	xf_emit(ctx, 1, 0);		/* 00000003 turing UNK35C */
2213	xf_emit(ctx, 1, 0);		/* ffffffff */
2214	xf_emit(ctx, 4, 0);		/* ffffffff */
2215	xf_emit(ctx, 1, 0);		/* 00000003 turing UNK35C */
2216	xf_emit(ctx, 1, 0);		/* ffffffff */
2217	xf_emit(ctx, 1, 0);		/* 000000ff */
2218}
2219
2220static void
2221nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx)
2222{
2223	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2224	xf_emit(ctx, 2, 0);		/* 00007fff WINDOW_OFFSET_XY */
2225	xf_emit(ctx, 1, 0x3f800000);	/* ffffffff LINE_WIDTH */
2226	xf_emit(ctx, 1, 0);		/* 00000001 LINE_SMOOTH_ENABLE */
2227	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1658 */
2228	xf_emit(ctx, 1, 0);		/* 00000001 POLYGON_SMOOTH_ENABLE */
2229	xf_emit(ctx, 3, 0);		/* 00000001 POLYGON_OFFSET_*_ENABLE */
2230	xf_emit(ctx, 1, 4);		/* 0000000f CULL_MODE */
2231	xf_emit(ctx, 1, 0x1a);		/* 0000001f POLYGON_MODE */
2232	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2233	xf_emit(ctx, 1, 0);		/* 00000001 POINT_SPRITE_ENABLE */
2234	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK165C */
2235	xf_emit(ctx, 0x10, 0);		/* 00000001 SCISSOR_ENABLE */
2236	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2237	xf_emit(ctx, 1, 0);		/* 00000001 LINE_STIPPLE_ENABLE */
2238	xf_emit(ctx, 1, 0x00ffff00);	/* 00ffffff LINE_STIPPLE_PATTERN */
2239	xf_emit(ctx, 1, 0);		/* ffffffff POLYGON_OFFSET_UNITS */
2240	xf_emit(ctx, 1, 0);		/* ffffffff POLYGON_OFFSET_FACTOR */
2241	xf_emit(ctx, 1, 0);		/* 00000003 tesla UNK1668 */
2242	xf_emit(ctx, 2, 0);		/* 07ffffff SCREEN_SCISSOR */
2243	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1900 */
2244	xf_emit(ctx, 1, 0xf);		/* 0000000f COLOR_MASK */
2245	xf_emit(ctx, 7, 0);		/* 0000000f COLOR_MASK */
2246	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2247	xf_emit(ctx, 1, 0x11);		/* 0000007f RT_FORMAT */
2248	xf_emit(ctx, 7, 0);		/* 0000007f RT_FORMAT */
2249	xf_emit(ctx, 8, 0);		/* 00000001 RT_HORIZ_LINEAR */
2250	xf_emit(ctx, 1, 4);		/* 00000007 FP_CONTROL */
2251	xf_emit(ctx, 1, 0);		/* 00000001 ALPHA_TEST_ENABLE */
2252	xf_emit(ctx, 1, 0);		/* 00000007 ALPHA_TEST_FUNC */
2253	if (IS_NVA3F(dev_priv->chipset))
2254		xf_emit(ctx, 1, 3);	/* 00000003 UNK16B4 */
2255	else if (dev_priv->chipset >= 0xa0)
2256		xf_emit(ctx, 1, 1);	/* 00000001 UNK16B4 */
2257	xf_emit(ctx, 1, 0);		/* 00000003 MULTISAMPLE_CTRL */
2258	xf_emit(ctx, 1, 0);		/* 00000003 tesla UNK0F90 */
2259	xf_emit(ctx, 1, 2);		/* 00000003 tesla UNK143C */
2260	xf_emit(ctx, 2, 0x04000000);	/* 07ffffff tesla UNK0D6C */
2261	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_MASK */
2262	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2263	xf_emit(ctx, 1, 0);		/* 00000001 SAMPLECNT_ENABLE */
2264	xf_emit(ctx, 1, 5);		/* 0000000f UNK1408 */
2265	xf_emit(ctx, 1, 0x52);		/* 000001ff SEMANTIC_PTSZ */
2266	xf_emit(ctx, 1, 0);		/* ffffffff POINT_SIZE */
2267	xf_emit(ctx, 1, 0);		/* 00000001 */
2268	xf_emit(ctx, 1, 0);		/* 00000007 tesla UNK0FB4 */
2269	if (dev_priv->chipset != 0x50) {
2270		xf_emit(ctx, 1, 0);	/* 3ff */
2271		xf_emit(ctx, 1, 1);	/* 00000001 tesla UNK1110 */
2272	}
2273	if (IS_NVA3F(dev_priv->chipset))
2274		xf_emit(ctx, 1, 0);	/* 00000003 tesla UNK1928 */
2275	xf_emit(ctx, 0x10, 0);		/* ffffffff DEPTH_RANGE_NEAR */
2276	xf_emit(ctx, 0x10, 0x3f800000);	/* ffffffff DEPTH_RANGE_FAR */
2277	xf_emit(ctx, 1, 0x10);		/* 000000ff VIEW_VOLUME_CLIP_CTRL */
2278	xf_emit(ctx, 0x20, 0);		/* 07ffffff VIEWPORT_HORIZ, then VIEWPORT_VERT. (W&0x3fff)<<13 | (X&0x1fff). */
2279	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK187C */
2280	xf_emit(ctx, 1, 0);		/* 00000003 WINDOW_ORIGIN */
2281	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2282	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2283	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_BACK_ENABLE */
2284	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_MASK */
2285	xf_emit(ctx, 1, 0x8100c12);	/* 1fffffff FP_INTERPOLANT_CTRL */
2286	xf_emit(ctx, 1, 5);		/* 0000000f tesla UNK1220 */
2287	xf_emit(ctx, 1, 0);		/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
2288	xf_emit(ctx, 1, 0);		/* 000000ff tesla UNK1A20 */
2289	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2290	xf_emit(ctx, 1, 0);		/* 00000001 VERTEX_TWO_SIDE_ENABLE */
2291	xf_emit(ctx, 4, 0xffff);	/* 0000ffff MSAA_MASK */
2292	if (dev_priv->chipset != 0x50)
2293		xf_emit(ctx, 1, 3);	/* 00000003 tesla UNK1100 */
2294	if (dev_priv->chipset < 0xa0)
2295		xf_emit(ctx, 0x1c, 0);	/* RO */
2296	else if (IS_NVA3F(dev_priv->chipset))
2297		xf_emit(ctx, 0x9, 0);
2298	xf_emit(ctx, 1, 0);		/* 00000001 UNK1534 */
2299	xf_emit(ctx, 1, 0);		/* 00000001 LINE_SMOOTH_ENABLE */
2300	xf_emit(ctx, 1, 0);		/* 00000001 LINE_STIPPLE_ENABLE */
2301	xf_emit(ctx, 1, 0x00ffff00);	/* 00ffffff LINE_STIPPLE_PATTERN */
2302	xf_emit(ctx, 1, 0x1a);		/* 0000001f POLYGON_MODE */
2303	xf_emit(ctx, 1, 0);		/* 00000003 WINDOW_ORIGIN */
2304	if (dev_priv->chipset != 0x50) {
2305		xf_emit(ctx, 1, 3);	/* 00000003 tesla UNK1100 */
2306		xf_emit(ctx, 1, 0);	/* 3ff */
2307	}
2308	/* XXX: the following block could belong either to unk1cxx, or
2309	 * to STRMOUT. Rather hard to tell. */
2310	if (dev_priv->chipset < 0xa0)
2311		xf_emit(ctx, 0x25, 0);
2312	else
2313		xf_emit(ctx, 0x3b, 0);
2314}
2315
2316static void
2317nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx)
2318{
2319	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2320	xf_emit(ctx, 1, 0x102);		/* 0000ffff STRMOUT_BUFFER_CTRL */
2321	xf_emit(ctx, 1, 0);		/* ffffffff STRMOUT_PRIMITIVE_COUNT */
2322	xf_emit(ctx, 4, 4);		/* 000000ff STRMOUT_NUM_ATTRIBS */
2323	if (dev_priv->chipset >= 0xa0) {
2324		xf_emit(ctx, 4, 0);	/* ffffffff UNK1A8C */
2325		xf_emit(ctx, 4, 0);	/* ffffffff UNK1780 */
2326	}
2327	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
2328	xf_emit(ctx, 1, 4);		/* 0000007f VP_RESULT_MAP_SIZE */
2329	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2330	if (dev_priv->chipset == 0x50)
2331		xf_emit(ctx, 1, 0x3ff);	/* 000003ff tesla UNK0D68 */
2332	else
2333		xf_emit(ctx, 1, 0x7ff);	/* 000007ff tesla UNK0D68 */
2334	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2335	/* SEEK */
2336	xf_emit(ctx, 1, 0x102);		/* 0000ffff STRMOUT_BUFFER_CTRL */
2337	xf_emit(ctx, 1, 0);		/* ffffffff STRMOUT_PRIMITIVE_COUNT */
2338	xf_emit(ctx, 4, 0);		/* 000000ff STRMOUT_ADDRESS_HIGH */
2339	xf_emit(ctx, 4, 0);		/* ffffffff STRMOUT_ADDRESS_LOW */
2340	xf_emit(ctx, 4, 4);		/* 000000ff STRMOUT_NUM_ATTRIBS */
2341	if (dev_priv->chipset >= 0xa0) {
2342		xf_emit(ctx, 4, 0);	/* ffffffff UNK1A8C */
2343		xf_emit(ctx, 4, 0);	/* ffffffff UNK1780 */
2344	}
2345	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_STRMOUT */
2346	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_QUERY */
2347	xf_emit(ctx, 1, 0);		/* 000000ff QUERY_ADDRESS_HIGH */
2348	xf_emit(ctx, 2, 0);		/* ffffffff QUERY_ADDRESS_LOW QUERY_COUNTER */
2349	xf_emit(ctx, 2, 0);		/* ffffffff */
2350	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2351	/* SEEK */
2352	xf_emit(ctx, 0x20, 0);		/* ffffffff STRMOUT_MAP */
2353	xf_emit(ctx, 1, 0);		/* 0000000f */
2354	xf_emit(ctx, 1, 0);		/* 00000000? */
2355	xf_emit(ctx, 2, 0);		/* ffffffff */
2356}
2357
2358static void
2359nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx)
2360{
2361	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2362	xf_emit(ctx, 1, 0x4e3bfdf);	/* ffffffff UNK0D64 */
2363	xf_emit(ctx, 1, 0x4e3bfdf);	/* ffffffff UNK0DF4 */
2364	xf_emit(ctx, 1, 0);		/* 00000007 */
2365	xf_emit(ctx, 1, 0);		/* 000003ff */
2366	if (IS_NVA3F(dev_priv->chipset))
2367		xf_emit(ctx, 1, 0x11);	/* 000000ff tesla UNK1968 */
2368	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2369}
2370
2371static void
2372nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx)
2373{
2374	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2375	/* SEEK */
2376	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_QUERY */
2377	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2378	xf_emit(ctx, 2, 0);		/* ffffffff */
2379	xf_emit(ctx, 1, 0);		/* 000000ff QUERY_ADDRESS_HIGH */
2380	xf_emit(ctx, 2, 0);		/* ffffffff QUERY_ADDRESS_LOW, COUNTER */
2381	xf_emit(ctx, 1, 0);		/* 00000001 SAMPLECNT_ENABLE */
2382	xf_emit(ctx, 1, 0);		/* 7 */
2383	/* SEEK */
2384	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_QUERY */
2385	xf_emit(ctx, 1, 0);		/* 000000ff QUERY_ADDRESS_HIGH */
2386	xf_emit(ctx, 2, 0);		/* ffffffff QUERY_ADDRESS_LOW, COUNTER */
2387	xf_emit(ctx, 1, 0x4e3bfdf);	/* ffffffff UNK0D64 */
2388	xf_emit(ctx, 1, 0x4e3bfdf);	/* ffffffff UNK0DF4 */
2389	xf_emit(ctx, 1, 0);		/* 00000001 eng2d UNK260 */
2390	xf_emit(ctx, 1, 0);		/* ff/3ff */
2391	xf_emit(ctx, 1, 0);		/* 00000007 */
2392	if (IS_NVA3F(dev_priv->chipset))
2393		xf_emit(ctx, 1, 0x11);	/* 000000ff tesla UNK1968 */
2394	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2395}
2396
2397static void
2398nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx)
2399{
2400	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2401	int magic2;
2402	if (dev_priv->chipset == 0x50) {
2403		magic2 = 0x00003e60;
2404	} else if (!IS_NVA3F(dev_priv->chipset)) {
2405		magic2 = 0x001ffe67;
2406	} else {
2407		magic2 = 0x00087e67;
2408	}
2409	xf_emit(ctx, 1, 0);		/* f/7 MUTISAMPLE_SAMPLES_LOG2 */
2410	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2411	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_BACK_FUNC_FUNC */
2412	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_MASK */
2413	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_MASK */
2414	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */
2415	xf_emit(ctx, 1, 2);		/* 00000003 tesla UNK143C */
2416	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2417	xf_emit(ctx, 1, magic2);	/* 001fffff tesla UNK0F78 */
2418	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2419	xf_emit(ctx, 1, 0);		/* 00000007 DEPTH_TEST_FUNC */
2420	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2421	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2422	if (IS_NVA3F(dev_priv->chipset))
2423		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2424	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_FRONT_FUNC_FUNC */
2425	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_MASK */
2426	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_MASK */
2427	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */
2428	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2429	if (dev_priv->chipset >= 0xa0 && !IS_NVAAF(dev_priv->chipset))
2430		xf_emit(ctx, 1, 0x15);	/* 000000ff */
2431	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_BACK_ENABLE */
2432	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK15B4 */
2433	xf_emit(ctx, 1, 0x10);		/* 3ff/ff VIEW_VOLUME_CLIP_CTRL */
2434	xf_emit(ctx, 1, 0);		/* ffffffff CLEAR_DEPTH */
2435	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2436	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2437	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2438	if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x92 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa0) {
2439		xf_emit(ctx, 3, 0);	/* ff, ffffffff, ffffffff */
2440		xf_emit(ctx, 1, 4);	/* 7 */
2441		xf_emit(ctx, 1, 0x400);	/* fffffff */
2442		xf_emit(ctx, 1, 0x300);	/* ffff */
2443		xf_emit(ctx, 1, 0x1001);	/* 1fff */
2444		if (dev_priv->chipset != 0xa0) {
2445			if (IS_NVA3F(dev_priv->chipset))
2446				xf_emit(ctx, 1, 0);	/* 0000000f UNK15C8 */
2447			else
2448				xf_emit(ctx, 1, 0x15);	/* ff */
2449		}
2450	}
2451	xf_emit(ctx, 1, 0);		/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
2452	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2453	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_BACK_FUNC_FUNC */
2454	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_MASK */
2455	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2456	xf_emit(ctx, 1, 2);		/* 00000003 tesla UNK143C */
2457	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2458	xf_emit(ctx, 1, 0);		/* 00000007 DEPTH_TEST_FUNC */
2459	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2460	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2461	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_FRONT_FUNC_FUNC */
2462	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_MASK */
2463	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2464	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_BACK_ENABLE */
2465	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK15B4 */
2466	xf_emit(ctx, 1, 0x10);		/* 7f/ff VIEW_VOLUME_CLIP_CTRL */
2467	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2468	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2469	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2470	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2471	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1900 */
2472	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_BACK_FUNC_FUNC */
2473	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_MASK */
2474	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_REF */
2475	xf_emit(ctx, 2, 0);		/* ffffffff DEPTH_BOUNDS */
2476	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2477	xf_emit(ctx, 1, 0);		/* 00000007 DEPTH_TEST_FUNC */
2478	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2479	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2480	xf_emit(ctx, 1, 0);		/* 0000000f */
2481	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK0FB0 */
2482	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_FRONT_FUNC_FUNC */
2483	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_MASK */
2484	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_REF */
2485	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2486	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_BACK_ENABLE */
2487	xf_emit(ctx, 1, 0x10);		/* 7f/ff VIEW_VOLUME_CLIP_CTRL */
2488	xf_emit(ctx, 0x10, 0);		/* ffffffff DEPTH_RANGE_NEAR */
2489	xf_emit(ctx, 0x10, 0x3f800000);	/* ffffffff DEPTH_RANGE_FAR */
2490	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2491	xf_emit(ctx, 1, 0);		/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
2492	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_BACK_FUNC_FUNC */
2493	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_MASK */
2494	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_FUNC_REF */
2495	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_MASK */
2496	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */
2497	xf_emit(ctx, 2, 0);		/* ffffffff DEPTH_BOUNDS */
2498	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2499	xf_emit(ctx, 1, 0);		/* 00000007 DEPTH_TEST_FUNC */
2500	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2501	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2502	xf_emit(ctx, 1, 0);		/* 000000ff CLEAR_STENCIL */
2503	xf_emit(ctx, 1, 0);		/* 00000007 STENCIL_FRONT_FUNC_FUNC */
2504	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_MASK */
2505	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_FUNC_REF */
2506	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_MASK */
2507	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */
2508	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2509	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_BACK_ENABLE */
2510	xf_emit(ctx, 1, 0x10);		/* 7f/ff VIEW_VOLUME_CLIP_CTRL */
2511	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2512	xf_emit(ctx, 1, 0x3f);		/* 0000003f UNK1590 */
2513	xf_emit(ctx, 1, 0);		/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
2514	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2515	xf_emit(ctx, 2, 0);		/* ffff0ff3, ffff */
2516	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK0FB0 */
2517	xf_emit(ctx, 1, 0);		/* 0001ffff GP_BUILTIN_RESULT_EN */
2518	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK15B4 */
2519	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2520	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2521	xf_emit(ctx, 1, 0);		/* ffffffff CLEAR_DEPTH */
2522	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK19CC */
2523	if (dev_priv->chipset >= 0xa0) {
2524		xf_emit(ctx, 2, 0);
2525		xf_emit(ctx, 1, 0x1001);
2526		xf_emit(ctx, 0xb, 0);
2527	} else {
2528		xf_emit(ctx, 1, 0);	/* 00000007 */
2529		xf_emit(ctx, 1, 0);	/* 00000001 tesla UNK1534 */
2530		xf_emit(ctx, 1, 0);	/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
2531		xf_emit(ctx, 8, 0);	/* 00000001 BLEND_ENABLE */
2532		xf_emit(ctx, 1, 0);	/* ffff0ff3 */
2533	}
2534	xf_emit(ctx, 1, 0x11);		/* 3f/7f RT_FORMAT */
2535	xf_emit(ctx, 7, 0);		/* 3f/7f RT_FORMAT */
2536	xf_emit(ctx, 1, 0xf);		/* 0000000f COLOR_MASK */
2537	xf_emit(ctx, 7, 0);		/* 0000000f COLOR_MASK */
2538	xf_emit(ctx, 1, 0x11);		/* 3f/7f */
2539	xf_emit(ctx, 1, 0);		/* 00000001 LOGIC_OP_ENABLE */
2540	if (dev_priv->chipset != 0x50) {
2541		xf_emit(ctx, 1, 0);	/* 0000000f LOGIC_OP */
2542		xf_emit(ctx, 1, 0);	/* 000000ff */
2543	}
2544	xf_emit(ctx, 1, 0);		/* 00000007 OPERATION */
2545	xf_emit(ctx, 1, 0);		/* ff/3ff */
2546	xf_emit(ctx, 1, 0);		/* 00000003 UNK0F90 */
2547	xf_emit(ctx, 2, 1);		/* 00000007 BLEND_EQUATION_RGB, ALPHA */
2548	xf_emit(ctx, 1, 1);		/* 00000001 UNK133C */
2549	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_RGB */
2550	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_RGB */
2551	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_ALPHA */
2552	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_ALPHA */
2553	xf_emit(ctx, 1, 0);		/* 00000001 */
2554	xf_emit(ctx, 1, magic2);	/* 001fffff tesla UNK0F78 */
2555	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2556	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2557	if (IS_NVA3F(dev_priv->chipset)) {
2558		xf_emit(ctx, 1, 0);	/* 00000001 tesla UNK12E4 */
2559		xf_emit(ctx, 8, 1);	/* 00000007 IBLEND_EQUATION_RGB */
2560		xf_emit(ctx, 8, 1);	/* 00000007 IBLEND_EQUATION_ALPHA */
2561		xf_emit(ctx, 8, 1);	/* 00000001 IBLEND_UNK00 */
2562		xf_emit(ctx, 8, 2);	/* 0000001f IBLEND_FUNC_SRC_RGB */
2563		xf_emit(ctx, 8, 1);	/* 0000001f IBLEND_FUNC_DST_RGB */
2564		xf_emit(ctx, 8, 2);	/* 0000001f IBLEND_FUNC_SRC_ALPHA */
2565		xf_emit(ctx, 8, 1);	/* 0000001f IBLEND_FUNC_DST_ALPHA */
2566		xf_emit(ctx, 1, 0);	/* 00000001 tesla UNK1140 */
2567		xf_emit(ctx, 2, 0);	/* 00000001 */
2568		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2569		xf_emit(ctx, 1, 0);	/* 0000000f */
2570		xf_emit(ctx, 1, 0);	/* 00000003 */
2571		xf_emit(ctx, 1, 0);	/* ffffffff */
2572		xf_emit(ctx, 2, 0);	/* 00000001 */
2573		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2574		xf_emit(ctx, 1, 0);	/* 00000001 */
2575		xf_emit(ctx, 1, 0);	/* 000003ff */
2576	} else if (dev_priv->chipset >= 0xa0) {
2577		xf_emit(ctx, 2, 0);	/* 00000001 */
2578		xf_emit(ctx, 1, 0);	/* 00000007 */
2579		xf_emit(ctx, 1, 0);	/* 00000003 */
2580		xf_emit(ctx, 1, 0);	/* ffffffff */
2581		xf_emit(ctx, 2, 0);	/* 00000001 */
2582	} else {
2583		xf_emit(ctx, 1, 0);	/* 00000007 MULTISAMPLE_SAMPLES_LOG2 */
2584		xf_emit(ctx, 1, 0);	/* 00000003 tesla UNK1430 */
2585		xf_emit(ctx, 1, 0);	/* ffffffff tesla UNK1A3C */
2586	}
2587	xf_emit(ctx, 4, 0);		/* ffffffff CLEAR_COLOR */
2588	xf_emit(ctx, 4, 0);		/* ffffffff BLEND_COLOR A R G B */
2589	xf_emit(ctx, 1, 0);		/* 00000fff eng2d UNK2B0 */
2590	if (dev_priv->chipset >= 0xa0)
2591		xf_emit(ctx, 2, 0);	/* 00000001 */
2592	xf_emit(ctx, 1, 0);		/* 000003ff */
2593	xf_emit(ctx, 8, 0);		/* 00000001 BLEND_ENABLE */
2594	xf_emit(ctx, 1, 1);		/* 00000001 UNK133C */
2595	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_RGB */
2596	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_RGB */
2597	xf_emit(ctx, 1, 1);		/* 00000007 BLEND_EQUATION_RGB */
2598	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_ALPHA */
2599	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_ALPHA */
2600	xf_emit(ctx, 1, 1);		/* 00000007 BLEND_EQUATION_ALPHA */
2601	xf_emit(ctx, 1, 0);		/* 00000001 UNK19C0 */
2602	xf_emit(ctx, 1, 0);		/* 00000001 LOGIC_OP_ENABLE */
2603	xf_emit(ctx, 1, 0);		/* 0000000f LOGIC_OP */
2604	if (dev_priv->chipset >= 0xa0)
2605		xf_emit(ctx, 1, 0);	/* 00000001 UNK12E4? NVA3+ only? */
2606	if (IS_NVA3F(dev_priv->chipset)) {
2607		xf_emit(ctx, 8, 1);	/* 00000001 IBLEND_UNK00 */
2608		xf_emit(ctx, 8, 1);	/* 00000007 IBLEND_EQUATION_RGB */
2609		xf_emit(ctx, 8, 2);	/* 0000001f IBLEND_FUNC_SRC_RGB */
2610		xf_emit(ctx, 8, 1);	/* 0000001f IBLEND_FUNC_DST_RGB */
2611		xf_emit(ctx, 8, 1);	/* 00000007 IBLEND_EQUATION_ALPHA */
2612		xf_emit(ctx, 8, 2);	/* 0000001f IBLEND_FUNC_SRC_ALPHA */
2613		xf_emit(ctx, 8, 1);	/* 0000001f IBLEND_FUNC_DST_ALPHA */
2614		xf_emit(ctx, 1, 0);	/* 00000001 tesla UNK15C4 */
2615		xf_emit(ctx, 1, 0);	/* 00000001 */
2616		xf_emit(ctx, 1, 0);	/* 00000001 tesla UNK1140 */
2617	}
2618	xf_emit(ctx, 1, 0x11);		/* 3f/7f DST_FORMAT */
2619	xf_emit(ctx, 1, 1);		/* 00000001 DST_LINEAR */
2620	xf_emit(ctx, 1, 0);		/* 00000007 PATTERN_COLOR_FORMAT */
2621	xf_emit(ctx, 2, 0);		/* ffffffff PATTERN_MONO_COLOR */
2622	xf_emit(ctx, 1, 0);		/* 00000001 PATTERN_MONO_FORMAT */
2623	xf_emit(ctx, 2, 0);		/* ffffffff PATTERN_MONO_BITMAP */
2624	xf_emit(ctx, 1, 0);		/* 00000003 PATTERN_SELECT */
2625	xf_emit(ctx, 1, 0);		/* 000000ff ROP */
2626	xf_emit(ctx, 1, 0);		/* ffffffff BETA1 */
2627	xf_emit(ctx, 1, 0);		/* ffffffff BETA4 */
2628	xf_emit(ctx, 1, 0);		/* 00000007 OPERATION */
2629	xf_emit(ctx, 0x50, 0);		/* 10x ffffff, ffffff, ffffff, ffffff, 3 PATTERN */
2630}
2631
2632static void
2633nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx)
2634{
2635	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2636	int magic3;
2637	switch (dev_priv->chipset) {
2638	case 0x50:
2639		magic3 = 0x1000;
2640		break;
2641	case 0x86:
2642	case 0x98:
2643	case 0xa8:
2644	case 0xaa:
2645	case 0xac:
2646	case 0xaf:
2647		magic3 = 0x1e00;
2648		break;
2649	default:
2650		magic3 = 0;
2651	}
2652	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2653	xf_emit(ctx, 1, 4);		/* 7f/ff[NVA0+] VP_REG_ALLOC_RESULT */
2654	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2655	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2656	xf_emit(ctx, 1, 0);		/* 111/113[NVA0+] */
2657	if (IS_NVA3F(dev_priv->chipset))
2658		xf_emit(ctx, 0x1f, 0);	/* ffffffff */
2659	else if (dev_priv->chipset >= 0xa0)
2660		xf_emit(ctx, 0x0f, 0);	/* ffffffff */
2661	else
2662		xf_emit(ctx, 0x10, 0);	/* fffffff VP_RESULT_MAP_1 up */
2663	xf_emit(ctx, 2, 0);		/* f/1f[NVA3], fffffff/ffffffff[NVA0+] */
2664	xf_emit(ctx, 1, 4);		/* 7f/ff VP_REG_ALLOC_RESULT */
2665	xf_emit(ctx, 1, 4);		/* 7f/ff VP_RESULT_MAP_SIZE */
2666	if (dev_priv->chipset >= 0xa0)
2667		xf_emit(ctx, 1, 0x03020100);	/* ffffffff */
2668	else
2669		xf_emit(ctx, 1, 0x00608080);	/* fffffff VP_RESULT_MAP_0 */
2670	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2671	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2672	xf_emit(ctx, 2, 0);		/* 111/113, 7f/ff */
2673	xf_emit(ctx, 1, 4);		/* 7f/ff VP_RESULT_MAP_SIZE */
2674	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2675	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2676	xf_emit(ctx, 1, 4);		/* 000000ff GP_REG_ALLOC_RESULT */
2677	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
2678	xf_emit(ctx, 1, 0x80);		/* 0000ffff GP_VERTEX_OUTPUT_COUNT */
2679	if (magic3)
2680		xf_emit(ctx, 1, magic3);	/* 00007fff tesla UNK141C */
2681	xf_emit(ctx, 1, 4);		/* 7f/ff VP_RESULT_MAP_SIZE */
2682	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2683	xf_emit(ctx, 1, 0);		/* 111/113 */
2684	xf_emit(ctx, 0x1f, 0);		/* ffffffff GP_RESULT_MAP_1 up */
2685	xf_emit(ctx, 1, 0);		/* 0000001f */
2686	xf_emit(ctx, 1, 0);		/* ffffffff */
2687	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2688	xf_emit(ctx, 1, 4);		/* 000000ff GP_REG_ALLOC_RESULT */
2689	xf_emit(ctx, 1, 0x80);		/* 0000ffff GP_VERTEX_OUTPUT_COUNT */
2690	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
2691	xf_emit(ctx, 1, 0x03020100);	/* ffffffff GP_RESULT_MAP_0 */
2692	xf_emit(ctx, 1, 3);		/* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */
2693	if (magic3)
2694		xf_emit(ctx, 1, magic3);	/* 7fff tesla UNK141C */
2695	xf_emit(ctx, 1, 4);		/* 7f/ff VP_RESULT_MAP_SIZE */
2696	xf_emit(ctx, 1, 0);		/* 00000001 PROVOKING_VERTEX_LAST */
2697	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2698	xf_emit(ctx, 1, 0);		/* 111/113 */
2699	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2700	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
2701	xf_emit(ctx, 1, 3);		/* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */
2702	xf_emit(ctx, 1, 0);		/* 00000001 PROVOKING_VERTEX_LAST */
2703	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2704	xf_emit(ctx, 1, 0);		/* 00000003 tesla UNK13A0 */
2705	xf_emit(ctx, 1, 4);		/* 7f/ff VP_REG_ALLOC_RESULT */
2706	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2707	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2708	xf_emit(ctx, 1, 0);		/* 111/113 */
2709	if (dev_priv->chipset == 0x94 || dev_priv->chipset == 0x96)
2710		xf_emit(ctx, 0x1020, 0);	/* 4 x (0x400 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */
2711	else if (dev_priv->chipset < 0xa0)
2712		xf_emit(ctx, 0xa20, 0);	/* 4 x (0x280 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */
2713	else if (!IS_NVA3F(dev_priv->chipset))
2714		xf_emit(ctx, 0x210, 0);	/* ffffffff */
2715	else
2716		xf_emit(ctx, 0x410, 0);	/* ffffffff */
2717	xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
2718	xf_emit(ctx, 1, 4);		/* 000000ff GP_RESULT_MAP_SIZE */
2719	xf_emit(ctx, 1, 3);		/* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */
2720	xf_emit(ctx, 1, 0);		/* 00000001 PROVOKING_VERTEX_LAST */
2721	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
2722}
2723
2724static void
2725nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx)
2726{
2727	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
2728	int magic1, magic2;
2729	if (dev_priv->chipset == 0x50) {
2730		magic1 = 0x3ff;
2731		magic2 = 0x00003e60;
2732	} else if (!IS_NVA3F(dev_priv->chipset)) {
2733		magic1 = 0x7ff;
2734		magic2 = 0x001ffe67;
2735	} else {
2736		magic1 = 0x7ff;
2737		magic2 = 0x00087e67;
2738	}
2739	xf_emit(ctx, 1, 0);		/* 00000007 ALPHA_TEST_FUNC */
2740	xf_emit(ctx, 1, 0);		/* ffffffff ALPHA_TEST_REF */
2741	xf_emit(ctx, 1, 0);		/* 00000001 ALPHA_TEST_ENABLE */
2742	if (IS_NVA3F(dev_priv->chipset))
2743		xf_emit(ctx, 1, 1);	/* 0000000f UNK16A0 */
2744	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
2745	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2746	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_BACK_MASK */
2747	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */
2748	xf_emit(ctx, 4, 0);		/* ffffffff BLEND_COLOR */
2749	xf_emit(ctx, 1, 0);		/* 00000001 UNK19C0 */
2750	xf_emit(ctx, 1, 0);		/* 00000001 UNK0FDC */
2751	xf_emit(ctx, 1, 0xf);		/* 0000000f COLOR_MASK */
2752	xf_emit(ctx, 7, 0);		/* 0000000f COLOR_MASK */
2753	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2754	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2755	xf_emit(ctx, 1, 0);		/* 00000001 LOGIC_OP_ENABLE */
2756	xf_emit(ctx, 1, 0);		/* ff[NV50]/3ff[NV84+] */
2757	xf_emit(ctx, 1, 4);		/* 00000007 FP_CONTROL */
2758	xf_emit(ctx, 4, 0xffff);	/* 0000ffff MSAA_MASK */
2759	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_MASK */
2760	xf_emit(ctx, 3, 0);		/* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */
2761	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2762	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_BACK_ENABLE */
2763	xf_emit(ctx, 2, 0);		/* 00007fff WINDOW_OFFSET_XY */
2764	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK19CC */
2765	xf_emit(ctx, 1, 0);		/* 7 */
2766	xf_emit(ctx, 1, 0);		/* 00000001 SAMPLECNT_ENABLE */
2767	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2768	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2769	xf_emit(ctx, 1, 0);		/* ffffffff COLOR_KEY */
2770	xf_emit(ctx, 1, 0);		/* 00000001 COLOR_KEY_ENABLE */
2771	xf_emit(ctx, 1, 0);		/* 00000007 COLOR_KEY_FORMAT */
2772	xf_emit(ctx, 2, 0);		/* ffffffff SIFC_BITMAP_COLOR */
2773	xf_emit(ctx, 1, 1);		/* 00000001 SIFC_BITMAP_WRITE_BIT0_ENABLE */
2774	xf_emit(ctx, 1, 0);		/* 00000007 ALPHA_TEST_FUNC */
2775	xf_emit(ctx, 1, 0);		/* 00000001 ALPHA_TEST_ENABLE */
2776	if (IS_NVA3F(dev_priv->chipset)) {
2777		xf_emit(ctx, 1, 3);	/* 00000003 tesla UNK16B4 */
2778		xf_emit(ctx, 1, 0);	/* 00000003 */
2779		xf_emit(ctx, 1, 0);	/* 00000003 tesla UNK1298 */
2780	} else if (dev_priv->chipset >= 0xa0) {
2781		xf_emit(ctx, 1, 1);	/* 00000001 tesla UNK16B4 */
2782		xf_emit(ctx, 1, 0);	/* 00000003 */
2783	} else {
2784		xf_emit(ctx, 1, 0);	/* 00000003 MULTISAMPLE_CTRL */
2785	}
2786	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2787	xf_emit(ctx, 8, 0);		/* 00000001 BLEND_ENABLE */
2788	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_ALPHA */
2789	xf_emit(ctx, 1, 1);		/* 00000007 BLEND_EQUATION_ALPHA */
2790	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_ALPHA */
2791	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_RGB */
2792	xf_emit(ctx, 1, 1);		/* 00000007 BLEND_EQUATION_RGB */
2793	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_RGB */
2794	if (IS_NVA3F(dev_priv->chipset)) {
2795		xf_emit(ctx, 1, 0);	/* 00000001 UNK12E4 */
2796		xf_emit(ctx, 8, 1);	/* 00000007 IBLEND_EQUATION_RGB */
2797		xf_emit(ctx, 8, 1);	/* 00000007 IBLEND_EQUATION_ALPHA */
2798		xf_emit(ctx, 8, 1);	/* 00000001 IBLEND_UNK00 */
2799		xf_emit(ctx, 8, 2);	/* 0000001f IBLEND_SRC_RGB */
2800		xf_emit(ctx, 8, 1);	/* 0000001f IBLEND_DST_RGB */
2801		xf_emit(ctx, 8, 2);	/* 0000001f IBLEND_SRC_ALPHA */
2802		xf_emit(ctx, 8, 1);	/* 0000001f IBLEND_DST_ALPHA */
2803		xf_emit(ctx, 1, 0);	/* 00000001 UNK1140 */
2804	}
2805	xf_emit(ctx, 1, 1);		/* 00000001 UNK133C */
2806	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2807	xf_emit(ctx, 1, 0x11);		/* 3f/7f RT_FORMAT */
2808	xf_emit(ctx, 7, 0);		/* 3f/7f RT_FORMAT */
2809	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2810	xf_emit(ctx, 1, 0);		/* 00000001 LOGIC_OP_ENABLE */
2811	xf_emit(ctx, 1, 0);		/* ff/3ff */
2812	xf_emit(ctx, 1, 4);		/* 00000007 FP_CONTROL */
2813	xf_emit(ctx, 1, 0);		/* 00000003 UNK0F90 */
2814	xf_emit(ctx, 1, 0);		/* 00000001 FRAMEBUFFER_SRGB */
2815	xf_emit(ctx, 1, 0);		/* 7 */
2816	xf_emit(ctx, 1, 0x11);		/* 3f/7f DST_FORMAT */
2817	xf_emit(ctx, 1, 1);		/* 00000001 DST_LINEAR */
2818	xf_emit(ctx, 1, 0);		/* 00000007 OPERATION */
2819	xf_emit(ctx, 1, 0xcf);		/* 000000ff SIFC_FORMAT */
2820	xf_emit(ctx, 1, 0xcf);		/* 000000ff DRAW_COLOR_FORMAT */
2821	xf_emit(ctx, 1, 0xcf);		/* 000000ff SRC_FORMAT */
2822	if (IS_NVA3F(dev_priv->chipset))
2823		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2824	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2825	xf_emit(ctx, 1, 0);		/* 7/f[NVA3] MULTISAMPLE_SAMPLES_LOG2 */
2826	xf_emit(ctx, 8, 0);		/* 00000001 BLEND_ENABLE */
2827	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_ALPHA */
2828	xf_emit(ctx, 1, 1);		/* 00000007 BLEND_EQUATION_ALPHA */
2829	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_ALPHA */
2830	xf_emit(ctx, 1, 1);		/* 0000001f BLEND_FUNC_DST_RGB */
2831	xf_emit(ctx, 1, 1);		/* 00000007 BLEND_EQUATION_RGB */
2832	xf_emit(ctx, 1, 2);		/* 0000001f BLEND_FUNC_SRC_RGB */
2833	xf_emit(ctx, 1, 1);		/* 00000001 UNK133C */
2834	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2835	xf_emit(ctx, 8, 1);		/* 00000001 UNK19E0 */
2836	xf_emit(ctx, 1, 0x11);		/* 3f/7f RT_FORMAT */
2837	xf_emit(ctx, 7, 0);		/* 3f/7f RT_FORMAT */
2838	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2839	xf_emit(ctx, 1, 0xf);		/* 0000000f COLOR_MASK */
2840	xf_emit(ctx, 7, 0);		/* 0000000f COLOR_MASK */
2841	xf_emit(ctx, 1, magic2);	/* 001fffff tesla UNK0F78 */
2842	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2843	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2844	xf_emit(ctx, 1, 0x11);		/* 3f/7f DST_FORMAT */
2845	xf_emit(ctx, 1, 1);		/* 00000001 DST_LINEAR */
2846	if (IS_NVA3F(dev_priv->chipset))
2847		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2848	if (dev_priv->chipset == 0x50)
2849		xf_emit(ctx, 1, 0);	/* ff */
2850	else
2851		xf_emit(ctx, 3, 0);	/* 1, 7, 3ff */
2852	xf_emit(ctx, 1, 4);		/* 00000007 FP_CONTROL */
2853	xf_emit(ctx, 1, 0);		/* 00000003 UNK0F90 */
2854	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2855	xf_emit(ctx, 1, 0);		/* 00000007 */
2856	xf_emit(ctx, 1, 0);		/* 00000001 SAMPLECNT_ENABLE */
2857	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2858	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2859	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2860	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
2861	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2862	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2863	xf_emit(ctx, 1, 0x11);		/* 3f/7f RT_FORMAT */
2864	xf_emit(ctx, 7, 0);		/* 3f/7f RT_FORMAT */
2865	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2866	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2867	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2868	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2869	xf_emit(ctx, 1, 0x11);		/* 3f/7f DST_FORMAT */
2870	xf_emit(ctx, 1, 1);		/* 00000001 DST_LINEAR */
2871	xf_emit(ctx, 1, 0);		/* 000fffff BLIT_DU_DX_FRACT */
2872	xf_emit(ctx, 1, 1);		/* 0001ffff BLIT_DU_DX_INT */
2873	xf_emit(ctx, 1, 0);		/* 000fffff BLIT_DV_DY_FRACT */
2874	xf_emit(ctx, 1, 1);		/* 0001ffff BLIT_DV_DY_INT */
2875	xf_emit(ctx, 1, 0);		/* ff/3ff */
2876	xf_emit(ctx, 1, magic1);	/* 3ff/7ff tesla UNK0D68 */
2877	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2878	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK15B4 */
2879	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2880	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2881	xf_emit(ctx, 1, 0);		/* 00000007 */
2882	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2883	if (IS_NVA3F(dev_priv->chipset))
2884		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2885	xf_emit(ctx, 8, 0);		/* 0000ffff DMA_COLOR */
2886	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_GLOBAL */
2887	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_LOCAL */
2888	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_STACK */
2889	xf_emit(ctx, 1, 0);		/* ff/3ff */
2890	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_DST */
2891	xf_emit(ctx, 1, 0);		/* 7 */
2892	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
2893	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2894	xf_emit(ctx, 8, 0);		/* 000000ff RT_ADDRESS_HIGH */
2895	xf_emit(ctx, 8, 0);		/* ffffffff RT_LAYER_STRIDE */
2896	xf_emit(ctx, 8, 0);		/* ffffffff RT_ADDRESS_LOW */
2897	xf_emit(ctx, 8, 8);		/* 0000007f RT_TILE_MODE */
2898	xf_emit(ctx, 1, 0x11);		/* 3f/7f RT_FORMAT */
2899	xf_emit(ctx, 7, 0);		/* 3f/7f RT_FORMAT */
2900	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2901	xf_emit(ctx, 8, 0x400);		/* 0fffffff RT_HORIZ */
2902	xf_emit(ctx, 8, 0x300);		/* 0000ffff RT_VERT */
2903	xf_emit(ctx, 1, 1);		/* 00001fff RT_ARRAY_MODE */
2904	xf_emit(ctx, 1, 0xf);		/* 0000000f COLOR_MASK */
2905	xf_emit(ctx, 7, 0);		/* 0000000f COLOR_MASK */
2906	xf_emit(ctx, 1, 0x20);		/* 00000fff DST_TILE_MODE */
2907	xf_emit(ctx, 1, 0x11);		/* 3f/7f DST_FORMAT */
2908	xf_emit(ctx, 1, 0x100);		/* 0001ffff DST_HEIGHT */
2909	xf_emit(ctx, 1, 0);		/* 000007ff DST_LAYER */
2910	xf_emit(ctx, 1, 1);		/* 00000001 DST_LINEAR */
2911	xf_emit(ctx, 1, 0);		/* ffffffff DST_ADDRESS_LOW */
2912	xf_emit(ctx, 1, 0);		/* 000000ff DST_ADDRESS_HIGH */
2913	xf_emit(ctx, 1, 0x40);		/* 0007ffff DST_PITCH */
2914	xf_emit(ctx, 1, 0x100);		/* 0001ffff DST_WIDTH */
2915	xf_emit(ctx, 1, 0);		/* 0000ffff */
2916	xf_emit(ctx, 1, 3);		/* 00000003 tesla UNK15AC */
2917	xf_emit(ctx, 1, 0);		/* ff/3ff */
2918	xf_emit(ctx, 1, 0);		/* 0001ffff GP_BUILTIN_RESULT_EN */
2919	xf_emit(ctx, 1, 0);		/* 00000003 UNK0F90 */
2920	xf_emit(ctx, 1, 0);		/* 00000007 */
2921	if (IS_NVA3F(dev_priv->chipset))
2922		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2923	xf_emit(ctx, 1, magic2);	/* 001fffff tesla UNK0F78 */
2924	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
2925	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1534 */
2926	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2927	xf_emit(ctx, 1, 2);		/* 00000003 tesla UNK143C */
2928	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2929	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_ZETA */
2930	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2931	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2932	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2933	xf_emit(ctx, 2, 0);		/* ffff, ff/3ff */
2934	xf_emit(ctx, 1, 0);		/* 0001ffff GP_BUILTIN_RESULT_EN */
2935	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2936	xf_emit(ctx, 1, 0);		/* 000000ff STENCIL_FRONT_MASK */
2937	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK15B4 */
2938	xf_emit(ctx, 1, 0);		/* 00000007 */
2939	xf_emit(ctx, 1, 0);		/* ffffffff ZETA_LAYER_STRIDE */
2940	xf_emit(ctx, 1, 0);		/* 000000ff ZETA_ADDRESS_HIGH */
2941	xf_emit(ctx, 1, 0);		/* ffffffff ZETA_ADDRESS_LOW */
2942	xf_emit(ctx, 1, 4);		/* 00000007 ZETA_TILE_MODE */
2943	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2944	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2945	xf_emit(ctx, 1, 0x400);		/* 0fffffff ZETA_HORIZ */
2946	xf_emit(ctx, 1, 0x300);		/* 0000ffff ZETA_VERT */
2947	xf_emit(ctx, 1, 0x1001);	/* 00001fff ZETA_ARRAY_MODE */
2948	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2949	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
2950	if (IS_NVA3F(dev_priv->chipset))
2951		xf_emit(ctx, 1, 0);	/* 00000001 */
2952	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2953	xf_emit(ctx, 1, 0x11);		/* 3f/7f RT_FORMAT */
2954	xf_emit(ctx, 7, 0);		/* 3f/7f RT_FORMAT */
2955	xf_emit(ctx, 1, 0x0fac6881);	/* 0fffffff RT_CONTROL */
2956	xf_emit(ctx, 1, 0xf);		/* 0000000f COLOR_MASK */
2957	xf_emit(ctx, 7, 0);		/* 0000000f COLOR_MASK */
2958	xf_emit(ctx, 1, 0);		/* ff/3ff */
2959	xf_emit(ctx, 8, 0);		/* 00000001 BLEND_ENABLE */
2960	xf_emit(ctx, 1, 0);		/* 00000003 UNK0F90 */
2961	xf_emit(ctx, 1, 0);		/* 00000001 FRAMEBUFFER_SRGB */
2962	xf_emit(ctx, 1, 0);		/* 7 */
2963	xf_emit(ctx, 1, 0);		/* 00000001 LOGIC_OP_ENABLE */
2964	if (IS_NVA3F(dev_priv->chipset)) {
2965		xf_emit(ctx, 1, 0);	/* 00000001 UNK1140 */
2966		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2967	}
2968	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
2969	xf_emit(ctx, 1, 0);		/* 00000001 UNK1534 */
2970	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
2971	if (dev_priv->chipset >= 0xa0)
2972		xf_emit(ctx, 1, 0x0fac6881);	/* fffffff */
2973	xf_emit(ctx, 1, magic2);	/* 001fffff tesla UNK0F78 */
2974	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_BOUNDS_EN */
2975	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
2976	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE_ENABLE */
2977	xf_emit(ctx, 1, 0x11);		/* 3f/7f DST_FORMAT */
2978	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK0FB0 */
2979	xf_emit(ctx, 1, 0);		/* ff/3ff */
2980	xf_emit(ctx, 1, 4);		/* 00000007 FP_CONTROL */
2981	xf_emit(ctx, 1, 0);		/* 00000001 STENCIL_FRONT_ENABLE */
2982	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK15B4 */
2983	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK19CC */
2984	xf_emit(ctx, 1, 0);		/* 00000007 */
2985	xf_emit(ctx, 1, 0);		/* 00000001 SAMPLECNT_ENABLE */
2986	xf_emit(ctx, 1, 0);		/* 0000000f ZETA_FORMAT */
2987	xf_emit(ctx, 1, 1);		/* 00000001 ZETA_ENABLE */
2988	if (IS_NVA3F(dev_priv->chipset)) {
2989		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
2990		xf_emit(ctx, 1, 0);	/* 0000000f tesla UNK15C8 */
2991	}
2992	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A3C */
2993	if (dev_priv->chipset >= 0xa0) {
2994		xf_emit(ctx, 3, 0);		/* 7/f, 1, ffff0ff3 */
2995		xf_emit(ctx, 1, 0xfac6881);	/* fffffff */
2996		xf_emit(ctx, 4, 0);		/* 1, 1, 1, 3ff */
2997		xf_emit(ctx, 1, 4);		/* 7 */
2998		xf_emit(ctx, 1, 0);		/* 1 */
2999		xf_emit(ctx, 2, 1);		/* 1 */
3000		xf_emit(ctx, 2, 0);		/* 7, f */
3001		xf_emit(ctx, 1, 1);		/* 1 */
3002		xf_emit(ctx, 1, 0);		/* 7/f */
3003		if (IS_NVA3F(dev_priv->chipset))
3004			xf_emit(ctx, 0x9, 0);	/* 1 */
3005		else
3006			xf_emit(ctx, 0x8, 0);	/* 1 */
3007		xf_emit(ctx, 1, 0);		/* ffff0ff3 */
3008		xf_emit(ctx, 8, 1);		/* 1 */
3009		xf_emit(ctx, 1, 0x11);		/* 7f */
3010		xf_emit(ctx, 7, 0);		/* 7f */
3011		xf_emit(ctx, 1, 0xfac6881);	/* fffffff */
3012		xf_emit(ctx, 1, 0xf);		/* f */
3013		xf_emit(ctx, 7, 0);		/* f */
3014		xf_emit(ctx, 1, 0x11);		/* 7f */
3015		xf_emit(ctx, 1, 1);		/* 1 */
3016		xf_emit(ctx, 5, 0);		/* 1, 7, 3ff, 3, 7 */
3017		if (IS_NVA3F(dev_priv->chipset)) {
3018			xf_emit(ctx, 1, 0);	/* 00000001 UNK1140 */
3019			xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
3020		}
3021	}
3022}
3023
3024static void
3025nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx)
3026{
3027	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
3028	xf_emit(ctx, 2, 0);		/* 1 LINKED_TSC. yes, 2. */
3029	if (dev_priv->chipset != 0x50)
3030		xf_emit(ctx, 1, 0);	/* 3 */
3031	xf_emit(ctx, 1, 1);		/* 1ffff BLIT_DU_DX_INT */
3032	xf_emit(ctx, 1, 0);		/* fffff BLIT_DU_DX_FRACT */
3033	xf_emit(ctx, 1, 1);		/* 1ffff BLIT_DV_DY_INT */
3034	xf_emit(ctx, 1, 0);		/* fffff BLIT_DV_DY_FRACT */
3035	if (dev_priv->chipset == 0x50)
3036		xf_emit(ctx, 1, 0);	/* 3 BLIT_CONTROL */
3037	else
3038		xf_emit(ctx, 2, 0);	/* 3ff, 1 */
3039	xf_emit(ctx, 1, 0x2a712488);	/* ffffffff SRC_TIC_0 */
3040	xf_emit(ctx, 1, 0);		/* ffffffff SRC_TIC_1 */
3041	xf_emit(ctx, 1, 0x4085c000);	/* ffffffff SRC_TIC_2 */
3042	xf_emit(ctx, 1, 0x40);		/* ffffffff SRC_TIC_3 */
3043	xf_emit(ctx, 1, 0x100);		/* ffffffff SRC_TIC_4 */
3044	xf_emit(ctx, 1, 0x10100);	/* ffffffff SRC_TIC_5 */
3045	xf_emit(ctx, 1, 0x02800000);	/* ffffffff SRC_TIC_6 */
3046	xf_emit(ctx, 1, 0);		/* ffffffff SRC_TIC_7 */
3047	if (dev_priv->chipset == 0x50) {
3048		xf_emit(ctx, 1, 0);	/* 00000001 turing UNK358 */
3049		xf_emit(ctx, 1, 0);	/* ffffffff tesla UNK1A34? */
3050		xf_emit(ctx, 1, 0);	/* 00000003 turing UNK37C tesla UNK1690 */
3051		xf_emit(ctx, 1, 0);	/* 00000003 BLIT_CONTROL */
3052		xf_emit(ctx, 1, 0);	/* 00000001 turing UNK32C tesla UNK0F94 */
3053	} else if (!IS_NVAAF(dev_priv->chipset)) {
3054		xf_emit(ctx, 1, 0);	/* ffffffff tesla UNK1A34? */
3055		xf_emit(ctx, 1, 0);	/* 00000003 */
3056		xf_emit(ctx, 1, 0);	/* 000003ff */
3057		xf_emit(ctx, 1, 0);	/* 00000003 */
3058		xf_emit(ctx, 1, 0);	/* 000003ff */
3059		xf_emit(ctx, 1, 0);	/* 00000003 tesla UNK1664 / turing UNK03E8 */
3060		xf_emit(ctx, 1, 0);	/* 00000003 */
3061		xf_emit(ctx, 1, 0);	/* 000003ff */
3062	} else {
3063		xf_emit(ctx, 0x6, 0);
3064	}
3065	xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A34 */
3066	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_TEXTURE */
3067	xf_emit(ctx, 1, 0);		/* 0000ffff DMA_SRC */
3068}
3069
3070static void
3071nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx)
3072{
3073	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
3074	xf_emit(ctx, 1, 0);		/* 00000001 UNK1534 */
3075	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
3076	xf_emit(ctx, 2, 0);		/* 7, ffff0ff3 */
3077	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
3078	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE */
3079	xf_emit(ctx, 1, 0x04e3bfdf);	/* ffffffff UNK0D64 */
3080	xf_emit(ctx, 1, 0x04e3bfdf);	/* ffffffff UNK0DF4 */
3081	xf_emit(ctx, 1, 1);		/* 00000001 UNK15B4 */
3082	xf_emit(ctx, 1, 0);		/* 00000001 LINE_STIPPLE_ENABLE */
3083	xf_emit(ctx, 1, 0x00ffff00);	/* 00ffffff LINE_STIPPLE_PATTERN */
3084	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK0F98 */
3085	if (IS_NVA3F(dev_priv->chipset))
3086		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
3087	xf_emit(ctx, 1, 0);		/* 00000003 tesla UNK1668 */
3088	xf_emit(ctx, 1, 0);		/* 00000001 LINE_STIPPLE_ENABLE */
3089	xf_emit(ctx, 1, 0x00ffff00);	/* 00ffffff LINE_STIPPLE_PATTERN */
3090	xf_emit(ctx, 1, 0);		/* 00000001 POLYGON_SMOOTH_ENABLE */
3091	xf_emit(ctx, 1, 0);		/* 00000001 UNK1534 */
3092	xf_emit(ctx, 1, 0);		/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
3093	xf_emit(ctx, 1, 0);		/* 00000001 tesla UNK1658 */
3094	xf_emit(ctx, 1, 0);		/* 00000001 LINE_SMOOTH_ENABLE */
3095	xf_emit(ctx, 1, 0);		/* ffff0ff3 */
3096	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_TEST_ENABLE */
3097	xf_emit(ctx, 1, 0);		/* 00000001 DEPTH_WRITE */
3098	xf_emit(ctx, 1, 1);		/* 00000001 UNK15B4 */
3099	xf_emit(ctx, 1, 0);		/* 00000001 POINT_SPRITE_ENABLE */
3100	xf_emit(ctx, 1, 1);		/* 00000001 tesla UNK165C */
3101	xf_emit(ctx, 1, 0x30201000);	/* ffffffff tesla UNK1670 */
3102	xf_emit(ctx, 1, 0x70605040);	/* ffffffff tesla UNK1670 */
3103	xf_emit(ctx, 1, 0xb8a89888);	/* ffffffff tesla UNK1670 */
3104	xf_emit(ctx, 1, 0xf8e8d8c8);	/* ffffffff tesla UNK1670 */
3105	xf_emit(ctx, 1, 0);		/* 00000001 VERTEX_TWO_SIDE_ENABLE */
3106	xf_emit(ctx, 1, 0x1a);		/* 0000001f POLYGON_MODE */
3107}
3108
3109static void
3110nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx)
3111{
3112	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
3113	if (dev_priv->chipset < 0xa0) {
3114		nv50_graph_construct_xfer_unk84xx(ctx);
3115		nv50_graph_construct_xfer_tprop(ctx);
3116		nv50_graph_construct_xfer_tex(ctx);
3117		nv50_graph_construct_xfer_unk8cxx(ctx);
3118	} else {
3119		nv50_graph_construct_xfer_tex(ctx);
3120		nv50_graph_construct_xfer_tprop(ctx);
3121		nv50_graph_construct_xfer_unk8cxx(ctx);
3122		nv50_graph_construct_xfer_unk84xx(ctx);
3123	}
3124}
3125
3126static void
3127nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx)
3128{
3129	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
3130	int i, mpcnt = 2;
3131	switch (dev_priv->chipset) {
3132		case 0x98:
3133		case 0xaa:
3134			mpcnt = 1;
3135			break;
3136		case 0x50:
3137		case 0x84:
3138		case 0x86:
3139		case 0x92:
3140		case 0x94:
3141		case 0x96:
3142		case 0xa8:
3143		case 0xac:
3144			mpcnt = 2;
3145			break;
3146		case 0xa0:
3147		case 0xa3:
3148		case 0xa5:
3149		case 0xaf:
3150			mpcnt = 3;
3151			break;
3152	}
3153	for (i = 0; i < mpcnt; i++) {
3154		xf_emit(ctx, 1, 0);		/* ff */
3155		xf_emit(ctx, 1, 0x80);		/* ffffffff tesla UNK1404 */
3156		xf_emit(ctx, 1, 0x80007004);	/* ffffffff tesla UNK12B0 */
3157		xf_emit(ctx, 1, 0x04000400);	/* ffffffff */
3158		if (dev_priv->chipset >= 0xa0)
3159			xf_emit(ctx, 1, 0xc0);	/* 00007fff tesla UNK152C */
3160		xf_emit(ctx, 1, 0x1000);	/* 0000ffff tesla UNK0D60 */
3161		xf_emit(ctx, 1, 0);		/* ff/3ff */
3162		xf_emit(ctx, 1, 0);		/* ffffffff tesla UNK1A30 */
3163		if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset == 0xa8 || IS_NVAAF(dev_priv->chipset)) {
3164			xf_emit(ctx, 1, 0xe00);		/* 7fff */
3165			xf_emit(ctx, 1, 0x1e00);	/* 7fff */
3166		}
3167		xf_emit(ctx, 1, 1);		/* 000000ff VP_REG_ALLOC_TEMP */
3168		xf_emit(ctx, 1, 0);		/* 00000001 LINKED_TSC */
3169		xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
3170		if (dev_priv->chipset == 0x50)
3171			xf_emit(ctx, 2, 0x1000);	/* 7fff tesla UNK141C */
3172		xf_emit(ctx, 1, 1);		/* 000000ff GP_REG_ALLOC_TEMP */
3173		xf_emit(ctx, 1, 0);		/* 00000001 GP_ENABLE */
3174		xf_emit(ctx, 1, 4);		/* 000000ff FP_REG_ALLOC_TEMP */
3175		xf_emit(ctx, 1, 2);		/* 00000003 REG_MODE */
3176		if (IS_NVAAF(dev_priv->chipset))
3177			xf_emit(ctx, 0xb, 0);	/* RO */
3178		else if (dev_priv->chipset >= 0xa0)
3179			xf_emit(ctx, 0xc, 0);	/* RO */
3180		else
3181			xf_emit(ctx, 0xa, 0);	/* RO */
3182	}
3183	xf_emit(ctx, 1, 0x08100c12);		/* 1fffffff FP_INTERPOLANT_CTRL */
3184	xf_emit(ctx, 1, 0);			/* ff/3ff */
3185	if (dev_priv->chipset >= 0xa0) {
3186		xf_emit(ctx, 1, 0x1fe21);	/* 0003ffff tesla UNK0FAC */
3187	}
3188	xf_emit(ctx, 3, 0);			/* 7fff, 0, 0 */
3189	xf_emit(ctx, 1, 0);			/* 00000001 tesla UNK1534 */
3190	xf_emit(ctx, 1, 0);			/* 7/f MULTISAMPLE_SAMPLES_LOG2 */
3191	xf_emit(ctx, 4, 0xffff);		/* 0000ffff MSAA_MASK */
3192	xf_emit(ctx, 1, 1);			/* 00000001 LANES32 */
3193	xf_emit(ctx, 1, 0x10001);		/* 00ffffff BLOCK_ALLOC */
3194	xf_emit(ctx, 1, 0x10001);		/* ffffffff BLOCKDIM_XY */
3195	xf_emit(ctx, 1, 1);			/* 0000ffff BLOCKDIM_Z */
3196	xf_emit(ctx, 1, 0);			/* ffffffff SHARED_SIZE */
3197	xf_emit(ctx, 1, 0x1fe21);		/* 1ffff/3ffff[NVA0+] tesla UNk0FAC */
3198	xf_emit(ctx, 1, 0);			/* ffffffff tesla UNK1A34 */
3199	if (IS_NVA3F(dev_priv->chipset))
3200		xf_emit(ctx, 1, 1);		/* 0000001f tesla UNK169C */
3201	xf_emit(ctx, 1, 0);			/* ff/3ff */
3202	xf_emit(ctx, 1, 0);			/* 1 LINKED_TSC */
3203	xf_emit(ctx, 1, 0);			/* ff FP_ADDRESS_HIGH */
3204	xf_emit(ctx, 1, 0);			/* ffffffff FP_ADDRESS_LOW */
3205	xf_emit(ctx, 1, 0x08100c12);		/* 1fffffff FP_INTERPOLANT_CTRL */
3206	xf_emit(ctx, 1, 4);			/* 00000007 FP_CONTROL */
3207	xf_emit(ctx, 1, 0);			/* 000000ff FRAG_COLOR_CLAMP_EN */
3208	xf_emit(ctx, 1, 2);			/* 00000003 REG_MODE */
3209	xf_emit(ctx, 1, 0x11);			/* 0000007f RT_FORMAT */
3210	xf_emit(ctx, 7, 0);			/* 0000007f RT_FORMAT */
3211	xf_emit(ctx, 1, 0);			/* 00000007 */
3212	xf_emit(ctx, 1, 0xfac6881);		/* 0fffffff RT_CONTROL */
3213	xf_emit(ctx, 1, 0);			/* 00000003 MULTISAMPLE_CTRL */
3214	if (IS_NVA3F(dev_priv->chipset))
3215		xf_emit(ctx, 1, 3);		/* 00000003 tesla UNK16B4 */
3216	xf_emit(ctx, 1, 0);			/* 00000001 ALPHA_TEST_ENABLE */
3217	xf_emit(ctx, 1, 0);			/* 00000007 ALPHA_TEST_FUNC */
3218	xf_emit(ctx, 1, 0);			/* 00000001 FRAMEBUFFER_SRGB */
3219	xf_emit(ctx, 1, 4);			/* ffffffff tesla UNK1400 */
3220	xf_emit(ctx, 8, 0);			/* 00000001 BLEND_ENABLE */
3221	xf_emit(ctx, 1, 0);			/* 00000001 LOGIC_OP_ENABLE */
3222	xf_emit(ctx, 1, 2);			/* 0000001f BLEND_FUNC_SRC_RGB */
3223	xf_emit(ctx, 1, 1);			/* 0000001f BLEND_FUNC_DST_RGB */
3224	xf_emit(ctx, 1, 1);			/* 00000007 BLEND_EQUATION_RGB */
3225	xf_emit(ctx, 1, 2);			/* 0000001f BLEND_FUNC_SRC_ALPHA */
3226	xf_emit(ctx, 1, 1);			/* 0000001f BLEND_FUNC_DST_ALPHA */
3227	xf_emit(ctx, 1, 1);			/* 00000007 BLEND_EQUATION_ALPHA */
3228	xf_emit(ctx, 1, 1);			/* 00000001 UNK133C */
3229	if (IS_NVA3F(dev_priv->chipset)) {
3230		xf_emit(ctx, 1, 0);		/* 00000001 UNK12E4 */
3231		xf_emit(ctx, 8, 2);		/* 0000001f IBLEND_FUNC_SRC_RGB */
3232		xf_emit(ctx, 8, 1);		/* 0000001f IBLEND_FUNC_DST_RGB */
3233		xf_emit(ctx, 8, 1);		/* 00000007 IBLEND_EQUATION_RGB */
3234		xf_emit(ctx, 8, 2);		/* 0000001f IBLEND_FUNC_SRC_ALPHA */
3235		xf_emit(ctx, 8, 1);		/* 0000001f IBLEND_FUNC_DST_ALPHA */
3236		xf_emit(ctx, 8, 1);		/* 00000007 IBLEND_EQUATION_ALPHA */
3237		xf_emit(ctx, 8, 1);		/* 00000001 IBLEND_UNK00 */
3238		xf_emit(ctx, 1, 0);		/* 00000003 tesla UNK1928 */
3239		xf_emit(ctx, 1, 0);		/* 00000001 UNK1140 */
3240	}
3241	xf_emit(ctx, 1, 0);			/* 00000003 tesla UNK0F90 */
3242	xf_emit(ctx, 1, 4);			/* 000000ff FP_RESULT_COUNT */
3243	/* XXX: demagic this part some day */
3244	if (dev_priv->chipset == 0x50)
3245		xf_emit(ctx, 0x3a0, 0);
3246	else if (dev_priv->chipset < 0x94)
3247		xf_emit(ctx, 0x3a2, 0);
3248	else if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa)
3249		xf_emit(ctx, 0x39f, 0);
3250	else
3251		xf_emit(ctx, 0x3a3, 0);
3252	xf_emit(ctx, 1, 0x11);			/* 3f/7f DST_FORMAT */
3253	xf_emit(ctx, 1, 0);			/* 7 OPERATION */
3254	xf_emit(ctx, 1, 1);			/* 1 DST_LINEAR */
3255	xf_emit(ctx, 0x2d, 0);
3256}
3257
3258static void
3259nv50_graph_construct_xfer2(struct nouveau_grctx *ctx)
3260{
3261	struct drm_nouveau_private *dev_priv = ctx->dev->dev_private;
3262	int i;
3263	uint32_t offset;
3264	uint32_t units = nv_rd32 (ctx->dev, 0x1540);
3265	int size = 0;
3266
3267	offset = (ctx->ctxvals_pos+0x3f)&~0x3f;
3268
3269	if (dev_priv->chipset < 0xa0) {
3270		for (i = 0; i < 8; i++) {
3271			ctx->ctxvals_pos = offset + i;
3272			/* that little bugger belongs to csched. No idea
3273			 * what it's doing here. */
3274			if (i == 0)
3275				xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */
3276			if (units & (1 << i))
3277				nv50_graph_construct_xfer_mpc(ctx);
3278			if ((ctx->ctxvals_pos-offset)/8 > size)
3279				size = (ctx->ctxvals_pos-offset)/8;
3280		}
3281	} else {
3282		/* Strand 0: TPs 0, 1 */
3283		ctx->ctxvals_pos = offset;
3284		/* that little bugger belongs to csched. No idea
3285		 * what it's doing here. */
3286		xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */
3287		if (units & (1 << 0))
3288			nv50_graph_construct_xfer_mpc(ctx);
3289		if (units & (1 << 1))
3290			nv50_graph_construct_xfer_mpc(ctx);
3291		if ((ctx->ctxvals_pos-offset)/8 > size)
3292			size = (ctx->ctxvals_pos-offset)/8;
3293
3294		/* Strand 1: TPs 2, 3 */
3295		ctx->ctxvals_pos = offset + 1;
3296		if (units & (1 << 2))
3297			nv50_graph_construct_xfer_mpc(ctx);
3298		if (units & (1 << 3))
3299			nv50_graph_construct_xfer_mpc(ctx);
3300		if ((ctx->ctxvals_pos-offset)/8 > size)
3301			size = (ctx->ctxvals_pos-offset)/8;
3302
3303		/* Strand 2: TPs 4, 5, 6 */
3304		ctx->ctxvals_pos = offset + 2;
3305		if (units & (1 << 4))
3306			nv50_graph_construct_xfer_mpc(ctx);
3307		if (units & (1 << 5))
3308			nv50_graph_construct_xfer_mpc(ctx);
3309		if (units & (1 << 6))
3310			nv50_graph_construct_xfer_mpc(ctx);
3311		if ((ctx->ctxvals_pos-offset)/8 > size)
3312			size = (ctx->ctxvals_pos-offset)/8;
3313
3314		/* Strand 3: TPs 7, 8, 9 */
3315		ctx->ctxvals_pos = offset + 3;
3316		if (units & (1 << 7))
3317			nv50_graph_construct_xfer_mpc(ctx);
3318		if (units & (1 << 8))
3319			nv50_graph_construct_xfer_mpc(ctx);
3320		if (units & (1 << 9))
3321			nv50_graph_construct_xfer_mpc(ctx);
3322		if ((ctx->ctxvals_pos-offset)/8 > size)
3323			size = (ctx->ctxvals_pos-offset)/8;
3324	}
3325	ctx->ctxvals_pos = offset + size * 8;
3326	ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f;
3327	cp_lsr (ctx, offset);
3328	cp_out (ctx, CP_SET_XFER_POINTER);
3329	cp_lsr (ctx, size);
3330	cp_out (ctx, CP_SEEK_2);
3331	cp_out (ctx, CP_XFER_2);
3332	cp_wait(ctx, XFER, BUSY);
3333}
3334