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