Linux Audio

Check our new training course

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