cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ctxnv50.c (126394B)


      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}