Linux Audio

Check our new training course

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