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