diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/graph')
32 files changed, 23698 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctx.h b/drivers/gpu/drm/nouveau/core/engine/graph/ctx.h new file mode 100644 index 00000000000..e1947013d3b --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctx.h @@ -0,0 +1,129 @@ +#ifndef __NOUVEAU_GRCTX_H__ +#define __NOUVEAU_GRCTX_H__ + +struct nouveau_grctx { + struct nouveau_device *device; + + enum { + NOUVEAU_GRCTX_PROG, + NOUVEAU_GRCTX_VALS + } mode; + void *data; + + u32 ctxprog_max; + u32 ctxprog_len; + u32 ctxprog_reg; + int ctxprog_label[32]; + u32 ctxvals_pos; + u32 ctxvals_base; +}; + +static inline void +cp_out(struct nouveau_grctx *ctx, u32 inst) +{ + u32 *ctxprog = ctx->data; + + if (ctx->mode != NOUVEAU_GRCTX_PROG) + return; + + BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max); + ctxprog[ctx->ctxprog_len++] = inst; +} + +static inline void +cp_lsr(struct nouveau_grctx *ctx, u32 val) +{ + cp_out(ctx, CP_LOAD_SR | val); +} + +static inline void +cp_ctx(struct nouveau_grctx *ctx, u32 reg, u32 length) +{ + ctx->ctxprog_reg = (reg - 0x00400000) >> 2; + + ctx->ctxvals_base = ctx->ctxvals_pos; + ctx->ctxvals_pos = ctx->ctxvals_base + length; + + if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) { + cp_lsr(ctx, length); + length = 0; + } + + cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg); +} + +static inline void +cp_name(struct nouveau_grctx *ctx, int name) +{ + u32 *ctxprog = ctx->data; + int i; + + if (ctx->mode != NOUVEAU_GRCTX_PROG) + return; + + ctx->ctxprog_label[name] = ctx->ctxprog_len; + for (i = 0; i < ctx->ctxprog_len; i++) { + if ((ctxprog[i] & 0xfff00000) != 0xff400000) + continue; + if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT)) + continue; + ctxprog[i] = (ctxprog[i] & 0x00ff00ff) | + (ctx->ctxprog_len << CP_BRA_IP_SHIFT); + } +} + +static inline void +_cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name) +{ + int ip = 0; + + if (mod != 2) { + ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT; + if (ip == 0) + ip = 0xff000000 | (name << CP_BRA_IP_SHIFT); + } + + cp_out(ctx, CP_BRA | (mod << 18) | ip | flag | + (state ? 0 : CP_BRA_IF_CLEAR)); +} +#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) +#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) +#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) + +static inline void +_cp_wait(struct nouveau_grctx *ctx, int flag, int state) +{ + cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0)); +} +#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) + +static inline void +_cp_set(struct nouveau_grctx *ctx, int flag, int state) +{ + cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0)); +} +#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) + +static inline void +cp_pos(struct nouveau_grctx *ctx, int offset) +{ + ctx->ctxvals_pos = offset; + ctx->ctxvals_base = ctx->ctxvals_pos; + + cp_lsr(ctx, ctx->ctxvals_pos); + cp_out(ctx, CP_SET_CONTEXT_POINTER); +} + +static inline void +gr_def(struct nouveau_grctx *ctx, u32 reg, u32 val) +{ + if (ctx->mode != NOUVEAU_GRCTX_VALS) + return; + + reg = (reg - 0x00400000) / 4; + reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base; + + nv_wo32(ctx->data, reg * 4, val); +} + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c new file mode 100644 index 00000000000..e45035efb8c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c @@ -0,0 +1,689 @@ +/* + * Copyright 2009 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include <core/gpuobj.h> + +/* NVIDIA context programs handle a number of other conditions which are + * not implemented in our versions. It's not clear why NVIDIA context + * programs have this code, nor whether it's strictly necessary for + * correct operation. We'll implement additional handling if/when we + * discover it's necessary. + * + * - On context save, NVIDIA set 0x400314 bit 0 to 1 if the "3D state" + * flag is set, this gets saved into the context. + * - On context save, the context program for all cards load nsource + * into a flag register and check for ILLEGAL_MTHD. If it's set, + * opcode 0x60000d is called before resuming normal operation. + * - Some context programs check more conditions than the above. NV44 + * checks: ((nsource & 0x0857) || (0x400718 & 0x0100) || (intr & 0x0001)) + * and calls 0x60000d before resuming normal operation. + * - At the very beginning of NVIDIA's context programs, flag 9 is checked + * and if true 0x800001 is called with count=0, pos=0, the flag is cleared + * and then the ctxprog is aborted. It looks like a complicated NOP, + * its purpose is unknown. + * - In the section of code that loads the per-vs state, NVIDIA check + * flag 10. If it's set, they only transfer the small 0x300 byte block + * of state + the state for a single vs as opposed to the state for + * all vs units. It doesn't seem likely that it'll occur in normal + * operation, especially seeing as it appears NVIDIA may have screwed + * up the ctxprogs for some cards and have an invalid instruction + * rather than a cp_lsr(ctx, dwords_for_1_vs_unit) instruction. + * - There's a number of places where context offset 0 (where we place + * the PRAMIN offset of the context) is loaded into either 0x408000, + * 0x408004 or 0x408008. Not sure what's up there either. + * - The ctxprogs for some cards save 0x400a00 again during the cleanup + * path for auto-loadctx. + */ + +#define CP_FLAG_CLEAR 0 +#define CP_FLAG_SET 1 +#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0) +#define CP_FLAG_SWAP_DIRECTION_LOAD 0 +#define CP_FLAG_SWAP_DIRECTION_SAVE 1 +#define CP_FLAG_USER_SAVE ((0 * 32) + 5) +#define CP_FLAG_USER_SAVE_NOT_PENDING 0 +#define CP_FLAG_USER_SAVE_PENDING 1 +#define CP_FLAG_USER_LOAD ((0 * 32) + 6) +#define CP_FLAG_USER_LOAD_NOT_PENDING 0 +#define CP_FLAG_USER_LOAD_PENDING 1 +#define CP_FLAG_STATUS ((3 * 32) + 0) +#define CP_FLAG_STATUS_IDLE 0 +#define CP_FLAG_STATUS_BUSY 1 +#define CP_FLAG_AUTO_SAVE ((3 * 32) + 4) +#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0 +#define CP_FLAG_AUTO_SAVE_PENDING 1 +#define CP_FLAG_AUTO_LOAD ((3 * 32) + 5) +#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 +#define CP_FLAG_AUTO_LOAD_PENDING 1 +#define CP_FLAG_UNK54 ((3 * 32) + 6) +#define CP_FLAG_UNK54_CLEAR 0 +#define CP_FLAG_UNK54_SET 1 +#define CP_FLAG_ALWAYS ((3 * 32) + 8) +#define CP_FLAG_ALWAYS_FALSE 0 +#define CP_FLAG_ALWAYS_TRUE 1 +#define CP_FLAG_UNK57 ((3 * 32) + 9) +#define CP_FLAG_UNK57_CLEAR 0 +#define CP_FLAG_UNK57_SET 1 + +#define CP_CTX 0x00100000 +#define CP_CTX_COUNT 0x000fc000 +#define CP_CTX_COUNT_SHIFT 14 +#define CP_CTX_REG 0x00003fff +#define CP_LOAD_SR 0x00200000 +#define CP_LOAD_SR_VALUE 0x000fffff +#define CP_BRA 0x00400000 +#define CP_BRA_IP 0x0000ff00 +#define CP_BRA_IP_SHIFT 8 +#define CP_BRA_IF_CLEAR 0x00000080 +#define CP_BRA_FLAG 0x0000007f +#define CP_WAIT 0x00500000 +#define CP_WAIT_SET 0x00000080 +#define CP_WAIT_FLAG 0x0000007f +#define CP_SET 0x00700000 +#define CP_SET_1 0x00000080 +#define CP_SET_FLAG 0x0000007f +#define CP_NEXT_TO_SWAP 0x00600007 +#define CP_NEXT_TO_CURRENT 0x00600009 +#define CP_SET_CONTEXT_POINTER 0x0060000a +#define CP_END 0x0060000e +#define CP_LOAD_MAGIC_UNK01 0x00800001 /* unknown */ +#define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */ +#define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */ + +#include "nv40.h" +#include "ctx.h" + +/* TODO: + * - get vs count from 0x1540 + */ + +static int +nv40_graph_vs_count(struct nouveau_device *device) +{ + + switch (device->chipset) { + case 0x47: + case 0x49: + case 0x4b: + return 8; + case 0x40: + return 6; + case 0x41: + case 0x42: + return 5; + case 0x43: + case 0x44: + case 0x46: + case 0x4a: + return 3; + case 0x4c: + case 0x4e: + case 0x67: + default: + return 1; + } +} + + +enum cp_label { + cp_check_load = 1, + cp_setup_auto_load, + cp_setup_load, + cp_setup_save, + cp_swap_state, + cp_swap_state3d_3_is_save, + cp_prepare_exit, + cp_exit, +}; + +static void +nv40_graph_construct_general(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i; + + cp_ctx(ctx, 0x4000a4, 1); + gr_def(ctx, 0x4000a4, 0x00000008); + cp_ctx(ctx, 0x400144, 58); + gr_def(ctx, 0x400144, 0x00000001); + cp_ctx(ctx, 0x400314, 1); + gr_def(ctx, 0x400314, 0x00000000); + cp_ctx(ctx, 0x400400, 10); + cp_ctx(ctx, 0x400480, 10); + cp_ctx(ctx, 0x400500, 19); + gr_def(ctx, 0x400514, 0x00040000); + gr_def(ctx, 0x400524, 0x55555555); + gr_def(ctx, 0x400528, 0x55555555); + gr_def(ctx, 0x40052c, 0x55555555); + gr_def(ctx, 0x400530, 0x55555555); + cp_ctx(ctx, 0x400560, 6); + gr_def(ctx, 0x400568, 0x0000ffff); + gr_def(ctx, 0x40056c, 0x0000ffff); + cp_ctx(ctx, 0x40057c, 5); + cp_ctx(ctx, 0x400710, 3); + gr_def(ctx, 0x400710, 0x20010001); + gr_def(ctx, 0x400714, 0x0f73ef00); + cp_ctx(ctx, 0x400724, 1); + gr_def(ctx, 0x400724, 0x02008821); + cp_ctx(ctx, 0x400770, 3); + if (device->chipset == 0x40) { + cp_ctx(ctx, 0x400814, 4); + cp_ctx(ctx, 0x400828, 5); + cp_ctx(ctx, 0x400840, 5); + gr_def(ctx, 0x400850, 0x00000040); + cp_ctx(ctx, 0x400858, 4); + gr_def(ctx, 0x400858, 0x00000040); + gr_def(ctx, 0x40085c, 0x00000040); + gr_def(ctx, 0x400864, 0x80000000); + cp_ctx(ctx, 0x40086c, 9); + gr_def(ctx, 0x40086c, 0x80000000); + gr_def(ctx, 0x400870, 0x80000000); + gr_def(ctx, 0x400874, 0x80000000); + gr_def(ctx, 0x400878, 0x80000000); + gr_def(ctx, 0x400888, 0x00000040); + gr_def(ctx, 0x40088c, 0x80000000); + cp_ctx(ctx, 0x4009c0, 8); + gr_def(ctx, 0x4009cc, 0x80000000); + gr_def(ctx, 0x4009dc, 0x80000000); + } else { + cp_ctx(ctx, 0x400840, 20); + if (nv44_graph_class(ctx->device)) { + for (i = 0; i < 8; i++) + gr_def(ctx, 0x400860 + (i * 4), 0x00000001); + } + gr_def(ctx, 0x400880, 0x00000040); + gr_def(ctx, 0x400884, 0x00000040); + gr_def(ctx, 0x400888, 0x00000040); + cp_ctx(ctx, 0x400894, 11); + gr_def(ctx, 0x400894, 0x00000040); + if (!nv44_graph_class(ctx->device)) { + for (i = 0; i < 8; i++) + gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000); + } + cp_ctx(ctx, 0x4008e0, 2); + cp_ctx(ctx, 0x4008f8, 2); + if (device->chipset == 0x4c || + (device->chipset & 0xf0) == 0x60) + cp_ctx(ctx, 0x4009f8, 1); + } + cp_ctx(ctx, 0x400a00, 73); + gr_def(ctx, 0x400b0c, 0x0b0b0b0c); + cp_ctx(ctx, 0x401000, 4); + cp_ctx(ctx, 0x405004, 1); + switch (device->chipset) { + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x403448, 1); + gr_def(ctx, 0x403448, 0x00001010); + break; + default: + cp_ctx(ctx, 0x403440, 1); + switch (device->chipset) { + case 0x40: + gr_def(ctx, 0x403440, 0x00000010); + break; + case 0x44: + case 0x46: + case 0x4a: + gr_def(ctx, 0x403440, 0x00003010); + break; + case 0x41: + case 0x42: + case 0x43: + case 0x4c: + case 0x4e: + case 0x67: + default: + gr_def(ctx, 0x403440, 0x00001010); + break; + } + break; + } +} + +static void +nv40_graph_construct_state3d(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i; + + if (device->chipset == 0x40) { + cp_ctx(ctx, 0x401880, 51); + gr_def(ctx, 0x401940, 0x00000100); + } else + if (device->chipset == 0x46 || device->chipset == 0x47 || + device->chipset == 0x49 || device->chipset == 0x4b) { + cp_ctx(ctx, 0x401880, 32); + for (i = 0; i < 16; i++) + gr_def(ctx, 0x401880 + (i * 4), 0x00000111); + if (device->chipset == 0x46) + cp_ctx(ctx, 0x401900, 16); + cp_ctx(ctx, 0x401940, 3); + } + cp_ctx(ctx, 0x40194c, 18); + gr_def(ctx, 0x401954, 0x00000111); + gr_def(ctx, 0x401958, 0x00080060); + gr_def(ctx, 0x401974, 0x00000080); + gr_def(ctx, 0x401978, 0xffff0000); + gr_def(ctx, 0x40197c, 0x00000001); + gr_def(ctx, 0x401990, 0x46400000); + if (device->chipset == 0x40) { + cp_ctx(ctx, 0x4019a0, 2); + cp_ctx(ctx, 0x4019ac, 5); + } else { + cp_ctx(ctx, 0x4019a0, 1); + cp_ctx(ctx, 0x4019b4, 3); + } + gr_def(ctx, 0x4019bc, 0xffff0000); + switch (device->chipset) { + case 0x46: + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x4019c0, 18); + for (i = 0; i < 16; i++) + gr_def(ctx, 0x4019c0 + (i * 4), 0x88888888); + break; + } + cp_ctx(ctx, 0x401a08, 8); + gr_def(ctx, 0x401a10, 0x0fff0000); + gr_def(ctx, 0x401a14, 0x0fff0000); + gr_def(ctx, 0x401a1c, 0x00011100); + cp_ctx(ctx, 0x401a2c, 4); + cp_ctx(ctx, 0x401a44, 26); + for (i = 0; i < 16; i++) + gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000); + gr_def(ctx, 0x401a8c, 0x4b7fffff); + if (device->chipset == 0x40) { + cp_ctx(ctx, 0x401ab8, 3); + } else { + cp_ctx(ctx, 0x401ab8, 1); + cp_ctx(ctx, 0x401ac0, 1); + } + cp_ctx(ctx, 0x401ad0, 8); + gr_def(ctx, 0x401ad0, 0x30201000); + gr_def(ctx, 0x401ad4, 0x70605040); + gr_def(ctx, 0x401ad8, 0xb8a89888); + gr_def(ctx, 0x401adc, 0xf8e8d8c8); + cp_ctx(ctx, 0x401b10, device->chipset == 0x40 ? 2 : 1); + gr_def(ctx, 0x401b10, 0x40100000); + cp_ctx(ctx, 0x401b18, device->chipset == 0x40 ? 6 : 5); + gr_def(ctx, 0x401b28, device->chipset == 0x40 ? + 0x00000004 : 0x00000000); + cp_ctx(ctx, 0x401b30, 25); + gr_def(ctx, 0x401b34, 0x0000ffff); + gr_def(ctx, 0x401b68, 0x435185d6); + gr_def(ctx, 0x401b6c, 0x2155b699); + gr_def(ctx, 0x401b70, 0xfedcba98); + gr_def(ctx, 0x401b74, 0x00000098); + gr_def(ctx, 0x401b84, 0xffffffff); + gr_def(ctx, 0x401b88, 0x00ff7000); + gr_def(ctx, 0x401b8c, 0x0000ffff); + if (device->chipset != 0x44 && device->chipset != 0x4a && + device->chipset != 0x4e) + cp_ctx(ctx, 0x401b94, 1); + cp_ctx(ctx, 0x401b98, 8); + gr_def(ctx, 0x401b9c, 0x00ff0000); + cp_ctx(ctx, 0x401bc0, 9); + gr_def(ctx, 0x401be0, 0x00ffff00); + cp_ctx(ctx, 0x401c00, 192); + for (i = 0; i < 16; i++) { /* fragment texture units */ + gr_def(ctx, 0x401c40 + (i * 4), 0x00018488); + gr_def(ctx, 0x401c80 + (i * 4), 0x00028202); + gr_def(ctx, 0x401d00 + (i * 4), 0x0000aae4); + gr_def(ctx, 0x401d40 + (i * 4), 0x01012000); + gr_def(ctx, 0x401d80 + (i * 4), 0x00080008); + gr_def(ctx, 0x401e00 + (i * 4), 0x00100008); + } + for (i = 0; i < 4; i++) { /* vertex texture units */ + gr_def(ctx, 0x401e90 + (i * 4), 0x0001bc80); + gr_def(ctx, 0x401ea0 + (i * 4), 0x00000202); + gr_def(ctx, 0x401ec0 + (i * 4), 0x00000008); + gr_def(ctx, 0x401ee0 + (i * 4), 0x00080008); + } + cp_ctx(ctx, 0x400f5c, 3); + gr_def(ctx, 0x400f5c, 0x00000002); + cp_ctx(ctx, 0x400f84, 1); +} + +static void +nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i; + + cp_ctx(ctx, 0x402000, 1); + cp_ctx(ctx, 0x402404, device->chipset == 0x40 ? 1 : 2); + switch (device->chipset) { + case 0x40: + gr_def(ctx, 0x402404, 0x00000001); + break; + case 0x4c: + case 0x4e: + case 0x67: + gr_def(ctx, 0x402404, 0x00000020); + break; + case 0x46: + case 0x49: + case 0x4b: + gr_def(ctx, 0x402404, 0x00000421); + break; + default: + gr_def(ctx, 0x402404, 0x00000021); + } + if (device->chipset != 0x40) + gr_def(ctx, 0x402408, 0x030c30c3); + switch (device->chipset) { + case 0x44: + case 0x46: + case 0x4a: + case 0x4c: + case 0x4e: + case 0x67: + cp_ctx(ctx, 0x402440, 1); + gr_def(ctx, 0x402440, 0x00011001); + break; + default: + break; + } + cp_ctx(ctx, 0x402480, device->chipset == 0x40 ? 8 : 9); + gr_def(ctx, 0x402488, 0x3e020200); + gr_def(ctx, 0x40248c, 0x00ffffff); + switch (device->chipset) { + case 0x40: + gr_def(ctx, 0x402490, 0x60103f00); + break; + case 0x47: + gr_def(ctx, 0x402490, 0x40103f00); + break; + case 0x41: + case 0x42: + case 0x49: + case 0x4b: + gr_def(ctx, 0x402490, 0x20103f00); + break; + default: + gr_def(ctx, 0x402490, 0x0c103f00); + break; + } + gr_def(ctx, 0x40249c, device->chipset <= 0x43 ? + 0x00020000 : 0x00040000); + cp_ctx(ctx, 0x402500, 31); + gr_def(ctx, 0x402530, 0x00008100); + if (device->chipset == 0x40) + cp_ctx(ctx, 0x40257c, 6); + cp_ctx(ctx, 0x402594, 16); + cp_ctx(ctx, 0x402800, 17); + gr_def(ctx, 0x402800, 0x00000001); + switch (device->chipset) { + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x402864, 1); + gr_def(ctx, 0x402864, 0x00001001); + cp_ctx(ctx, 0x402870, 3); + gr_def(ctx, 0x402878, 0x00000003); + if (device->chipset != 0x47) { /* belong at end!! */ + cp_ctx(ctx, 0x402900, 1); + cp_ctx(ctx, 0x402940, 1); + cp_ctx(ctx, 0x402980, 1); + cp_ctx(ctx, 0x4029c0, 1); + cp_ctx(ctx, 0x402a00, 1); + cp_ctx(ctx, 0x402a40, 1); + cp_ctx(ctx, 0x402a80, 1); + cp_ctx(ctx, 0x402ac0, 1); + } + break; + case 0x40: + cp_ctx(ctx, 0x402844, 1); + gr_def(ctx, 0x402844, 0x00000001); + cp_ctx(ctx, 0x402850, 1); + break; + default: + cp_ctx(ctx, 0x402844, 1); + gr_def(ctx, 0x402844, 0x00001001); + cp_ctx(ctx, 0x402850, 2); + gr_def(ctx, 0x402854, 0x00000003); + break; + } + + cp_ctx(ctx, 0x402c00, 4); + gr_def(ctx, 0x402c00, device->chipset == 0x40 ? + 0x80800001 : 0x00888001); + switch (device->chipset) { + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x402c20, 40); + for (i = 0; i < 32; i++) + gr_def(ctx, 0x402c40 + (i * 4), 0xffffffff); + cp_ctx(ctx, 0x4030b8, 13); + gr_def(ctx, 0x4030dc, 0x00000005); + gr_def(ctx, 0x4030e8, 0x0000ffff); + break; + default: + cp_ctx(ctx, 0x402c10, 4); + if (device->chipset == 0x40) + cp_ctx(ctx, 0x402c20, 36); + else + if (device->chipset <= 0x42) + cp_ctx(ctx, 0x402c20, 24); + else + if (device->chipset <= 0x4a) + cp_ctx(ctx, 0x402c20, 16); + else + cp_ctx(ctx, 0x402c20, 8); + cp_ctx(ctx, 0x402cb0, device->chipset == 0x40 ? 12 : 13); + gr_def(ctx, 0x402cd4, 0x00000005); + if (device->chipset != 0x40) + gr_def(ctx, 0x402ce0, 0x0000ffff); + break; + } + + cp_ctx(ctx, 0x403400, device->chipset == 0x40 ? 4 : 3); + cp_ctx(ctx, 0x403410, device->chipset == 0x40 ? 4 : 3); + cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->device)); + for (i = 0; i < nv40_graph_vs_count(ctx->device); i++) + gr_def(ctx, 0x403420 + (i * 4), 0x00005555); + + if (device->chipset != 0x40) { + cp_ctx(ctx, 0x403600, 1); + gr_def(ctx, 0x403600, 0x00000001); + } + cp_ctx(ctx, 0x403800, 1); + + cp_ctx(ctx, 0x403c18, 1); + gr_def(ctx, 0x403c18, 0x00000001); + switch (device->chipset) { + case 0x46: + case 0x47: + case 0x49: + case 0x4b: + cp_ctx(ctx, 0x405018, 1); + gr_def(ctx, 0x405018, 0x08e00001); + cp_ctx(ctx, 0x405c24, 1); + gr_def(ctx, 0x405c24, 0x000e3000); + break; + } + if (device->chipset != 0x4e) + cp_ctx(ctx, 0x405800, 11); + cp_ctx(ctx, 0x407000, 1); +} + +static void +nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx) +{ + int len = nv44_graph_class(ctx->device) ? 0x0084 : 0x0684; + + cp_out (ctx, 0x300000); + cp_lsr (ctx, len - 4); + cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save); + cp_lsr (ctx, len); + cp_name(ctx, cp_swap_state3d_3_is_save); + cp_out (ctx, 0x800001); + + ctx->ctxvals_pos += len; +} + +static void +nv40_graph_construct_shader(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + struct nouveau_gpuobj *obj = ctx->data; + int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset; + int offset, i; + + vs_nr = nv40_graph_vs_count(ctx->device); + vs_nr_b0 = 363; + vs_nr_b1 = device->chipset == 0x40 ? 128 : 64; + if (device->chipset == 0x40) { + b0_offset = 0x2200/4; /* 33a0 */ + b1_offset = 0x55a0/4; /* 1500 */ + vs_len = 0x6aa0/4; + } else + if (device->chipset == 0x41 || device->chipset == 0x42) { + b0_offset = 0x2200/4; /* 2200 */ + b1_offset = 0x4400/4; /* 0b00 */ + vs_len = 0x4f00/4; + } else { + b0_offset = 0x1d40/4; /* 2200 */ + b1_offset = 0x3f40/4; /* 0b00 : 0a40 */ + vs_len = nv44_graph_class(device) ? 0x4980/4 : 0x4a40/4; + } + + cp_lsr(ctx, vs_len * vs_nr + 0x300/4); + cp_out(ctx, nv44_graph_class(device) ? 0x800029 : 0x800041); + + offset = ctx->ctxvals_pos; + ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len)); + + if (ctx->mode != NOUVEAU_GRCTX_VALS) + return; + + offset += 0x0280/4; + for (i = 0; i < 16; i++, offset += 2) + nv_wo32(obj, offset * 4, 0x3f800000); + + for (vs = 0; vs < vs_nr; vs++, offset += vs_len) { + for (i = 0; i < vs_nr_b0 * 6; i += 6) + nv_wo32(obj, (offset + b0_offset + i) * 4, 0x00000001); + for (i = 0; i < vs_nr_b1 * 4; i += 4) + nv_wo32(obj, (offset + b1_offset + i) * 4, 0x3f800000); + } +} + +static void +nv40_grctx_generate(struct nouveau_grctx *ctx) +{ + /* decide whether we're loading/unloading the context */ + cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save); + cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save); + + cp_name(ctx, cp_check_load); + cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load); + cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load); + cp_bra (ctx, ALWAYS, TRUE, cp_exit); + + /* setup for context load */ + cp_name(ctx, cp_setup_auto_load); + cp_wait(ctx, STATUS, IDLE); + cp_out (ctx, CP_NEXT_TO_SWAP); + cp_name(ctx, cp_setup_load); + cp_wait(ctx, STATUS, IDLE); + cp_set (ctx, SWAP_DIRECTION, LOAD); + cp_out (ctx, 0x00910880); /* ?? */ + cp_out (ctx, 0x00901ffe); /* ?? */ + cp_out (ctx, 0x01940000); /* ?? */ + cp_lsr (ctx, 0x20); + cp_out (ctx, 0x0060000b); /* ?? */ + cp_wait(ctx, UNK57, CLEAR); + cp_out (ctx, 0x0060000c); /* ?? */ + cp_bra (ctx, ALWAYS, TRUE, cp_swap_state); + + /* setup for context save */ + cp_name(ctx, cp_setup_save); + cp_set (ctx, SWAP_DIRECTION, SAVE); + + /* general PGRAPH state */ + cp_name(ctx, cp_swap_state); + cp_pos (ctx, 0x00020/4); + nv40_graph_construct_general(ctx); + cp_wait(ctx, STATUS, IDLE); + + /* 3D state, block 1 */ + cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit); + nv40_graph_construct_state3d(ctx); + cp_wait(ctx, STATUS, IDLE); + + /* 3D state, block 2 */ + nv40_graph_construct_state3d_2(ctx); + + /* Some other block of "random" state */ + nv40_graph_construct_state3d_3(ctx); + + /* Per-vertex shader state */ + cp_pos (ctx, ctx->ctxvals_pos); + nv40_graph_construct_shader(ctx); + + /* pre-exit state updates */ + cp_name(ctx, cp_prepare_exit); + cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load); + cp_bra (ctx, USER_SAVE, PENDING, cp_exit); + cp_out (ctx, CP_NEXT_TO_CURRENT); + + cp_name(ctx, cp_exit); + cp_set (ctx, USER_SAVE, NOT_PENDING); + cp_set (ctx, USER_LOAD, NOT_PENDING); + cp_out (ctx, CP_END); +} + +void +nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) +{ + nv40_grctx_generate(&(struct nouveau_grctx) { + .device = device, + .mode = NOUVEAU_GRCTX_VALS, + .data = mem, + }); +} + +void +nv40_grctx_init(struct nouveau_device *device, u32 *size) +{ + u32 ctxprog[256], i; + struct nouveau_grctx ctx = { + .device = device, + .mode = NOUVEAU_GRCTX_PROG, + .data = ctxprog, + .ctxprog_max = ARRAY_SIZE(ctxprog) + }; + + nv40_grctx_generate(&ctx); + + nv_wr32(device, 0x400324, 0); + for (i = 0; i < ctx.ctxprog_len; i++) + nv_wr32(device, 0x400328, ctxprog[i]); + *size = ctx.ctxvals_pos * 4; +} diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c new file mode 100644 index 00000000000..552fdbd45eb --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv50.c @@ -0,0 +1,3341 @@ +/* + * Copyright 2009 Marcin KoĆcielnicki + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <core/gpuobj.h> + +#define CP_FLAG_CLEAR 0 +#define CP_FLAG_SET 1 +#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0) +#define CP_FLAG_SWAP_DIRECTION_LOAD 0 +#define CP_FLAG_SWAP_DIRECTION_SAVE 1 +#define CP_FLAG_UNK01 ((0 * 32) + 1) +#define CP_FLAG_UNK01_CLEAR 0 +#define CP_FLAG_UNK01_SET 1 +#define CP_FLAG_UNK03 ((0 * 32) + 3) +#define CP_FLAG_UNK03_CLEAR 0 +#define CP_FLAG_UNK03_SET 1 +#define CP_FLAG_USER_SAVE ((0 * 32) + 5) +#define CP_FLAG_USER_SAVE_NOT_PENDING 0 +#define CP_FLAG_USER_SAVE_PENDING 1 +#define CP_FLAG_USER_LOAD ((0 * 32) + 6) +#define CP_FLAG_USER_LOAD_NOT_PENDING 0 +#define CP_FLAG_USER_LOAD_PENDING 1 +#define CP_FLAG_UNK0B ((0 * 32) + 0xb) +#define CP_FLAG_UNK0B_CLEAR 0 +#define CP_FLAG_UNK0B_SET 1 +#define CP_FLAG_XFER_SWITCH ((0 * 32) + 0xe) +#define CP_FLAG_XFER_SWITCH_DISABLE 0 +#define CP_FLAG_XFER_SWITCH_ENABLE 1 +#define CP_FLAG_STATE ((0 * 32) + 0x1c) +#define CP_FLAG_STATE_STOPPED 0 +#define CP_FLAG_STATE_RUNNING 1 +#define CP_FLAG_UNK1D ((0 * 32) + 0x1d) +#define CP_FLAG_UNK1D_CLEAR 0 +#define CP_FLAG_UNK1D_SET 1 +#define CP_FLAG_UNK20 ((1 * 32) + 0) +#define CP_FLAG_UNK20_CLEAR 0 +#define CP_FLAG_UNK20_SET 1 +#define CP_FLAG_STATUS ((2 * 32) + 0) +#define CP_FLAG_STATUS_BUSY 0 +#define CP_FLAG_STATUS_IDLE 1 +#define CP_FLAG_AUTO_SAVE ((2 * 32) + 4) +#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0 +#define CP_FLAG_AUTO_SAVE_PENDING 1 +#define CP_FLAG_AUTO_LOAD ((2 * 32) + 5) +#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 +#define CP_FLAG_AUTO_LOAD_PENDING 1 +#define CP_FLAG_NEWCTX ((2 * 32) + 10) +#define CP_FLAG_NEWCTX_BUSY 0 +#define CP_FLAG_NEWCTX_DONE 1 +#define CP_FLAG_XFER ((2 * 32) + 11) +#define CP_FLAG_XFER_IDLE 0 +#define CP_FLAG_XFER_BUSY 1 +#define CP_FLAG_ALWAYS ((2 * 32) + 13) +#define CP_FLAG_ALWAYS_FALSE 0 +#define CP_FLAG_ALWAYS_TRUE 1 +#define CP_FLAG_INTR ((2 * 32) + 15) +#define CP_FLAG_INTR_NOT_PENDING 0 +#define CP_FLAG_INTR_PENDING 1 + +#define CP_CTX 0x00100000 +#define CP_CTX_COUNT 0x000f0000 +#define CP_CTX_COUNT_SHIFT 16 +#define CP_CTX_REG 0x00003fff +#define CP_LOAD_SR 0x00200000 +#define CP_LOAD_SR_VALUE 0x000fffff +#define CP_BRA 0x00400000 +#define CP_BRA_IP 0x0001ff00 +#define CP_BRA_IP_SHIFT 8 +#define CP_BRA_IF_CLEAR 0x00000080 +#define CP_BRA_FLAG 0x0000007f +#define CP_WAIT 0x00500000 +#define CP_WAIT_SET 0x00000080 +#define CP_WAIT_FLAG 0x0000007f +#define CP_SET 0x00700000 +#define CP_SET_1 0x00000080 +#define CP_SET_FLAG 0x0000007f +#define CP_NEWCTX 0x00600004 +#define CP_NEXT_TO_SWAP 0x00600005 +#define CP_SET_CONTEXT_POINTER 0x00600006 +#define CP_SET_XFER_POINTER 0x00600007 +#define CP_ENABLE 0x00600009 +#define CP_END 0x0060000c +#define CP_NEXT_TO_CURRENT 0x0060000d +#define CP_DISABLE1 0x0090ffff +#define CP_DISABLE2 0x0091ffff +#define CP_XFER_1 0x008000ff +#define CP_XFER_2 0x008800ff +#define CP_SEEK_1 0x00c000ff +#define CP_SEEK_2 0x00c800ff + +#include "nv50.h" +#include "ctx.h" + +#define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf) +#define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac) + +/* + * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's + * the GPU itself that does context-switching, but it needs a special + * microcode to do it. And it's the driver's task to supply this microcode, + * further known as ctxprog, as well as the initial context values, known + * as ctxvals. + * + * Without ctxprog, you cannot switch contexts. Not even in software, since + * the majority of context [xfer strands] isn't accessible directly. You're + * stuck with a single channel, and you also suffer all the problems resulting + * from missing ctxvals, since you cannot load them. + * + * Without ctxvals, you're stuck with PGRAPH's default context. It's enough to + * run 2d operations, but trying to utilise 3d or CUDA will just lock you up, + * since you don't have... some sort of needed setup. + * + * Nouveau will just disable acceleration if not given ctxprog + ctxvals, since + * it's too much hassle to handle no-ctxprog as a special case. + */ + +/* + * How ctxprogs work. + * + * The ctxprog is written in its own kind of microcode, with very small and + * crappy set of available commands. You upload it to a small [512 insns] + * area of memory on PGRAPH, and it'll be run when PFIFO wants PGRAPH to + * switch channel. or when the driver explicitely requests it. Stuff visible + * to ctxprog consists of: PGRAPH MMIO registers, PGRAPH context strands, + * the per-channel context save area in VRAM [known as ctxvals or grctx], + * 4 flags registers, a scratch register, two grctx pointers, plus many + * random poorly-understood details. + * + * When ctxprog runs, it's supposed to check what operations are asked of it, + * save old context if requested, optionally reset PGRAPH and switch to the + * new channel, and load the new context. Context consists of three major + * parts: subset of MMIO registers and two "xfer areas". + */ + +/* TODO: + * - document unimplemented bits compared to nvidia + * - NVAx: make a TP subroutine, use it. + * - use 0x4008fc instead of 0x1540? + */ + +enum cp_label { + cp_check_load = 1, + cp_setup_auto_load, + cp_setup_load, + cp_setup_save, + cp_swap_state, + cp_prepare_exit, + cp_exit, +}; + +static void nv50_graph_construct_mmio(struct nouveau_grctx *ctx); +static void nv50_graph_construct_xfer1(struct nouveau_grctx *ctx); +static void nv50_graph_construct_xfer2(struct nouveau_grctx *ctx); + +/* Main function: construct the ctxprog skeleton, call the other functions. */ + +static int +nv50_grctx_generate(struct nouveau_grctx *ctx) +{ + cp_set (ctx, STATE, RUNNING); + cp_set (ctx, XFER_SWITCH, ENABLE); + /* decide whether we're loading/unloading the context */ + cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save); + cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save); + + cp_name(ctx, cp_check_load); + cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load); + cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load); + cp_bra (ctx, ALWAYS, TRUE, cp_prepare_exit); + + /* setup for context load */ + cp_name(ctx, cp_setup_auto_load); + cp_out (ctx, CP_DISABLE1); + cp_out (ctx, CP_DISABLE2); + cp_out (ctx, CP_ENABLE); + cp_out (ctx, CP_NEXT_TO_SWAP); + cp_set (ctx, UNK01, SET); + cp_name(ctx, cp_setup_load); + cp_out (ctx, CP_NEWCTX); + cp_wait(ctx, NEWCTX, BUSY); + cp_set (ctx, UNK1D, CLEAR); + cp_set (ctx, SWAP_DIRECTION, LOAD); + cp_bra (ctx, UNK0B, SET, cp_prepare_exit); + cp_bra (ctx, ALWAYS, TRUE, cp_swap_state); + + /* setup for context save */ + cp_name(ctx, cp_setup_save); + cp_set (ctx, UNK1D, SET); + cp_wait(ctx, STATUS, BUSY); + cp_wait(ctx, INTR, PENDING); + cp_bra (ctx, STATUS, BUSY, cp_setup_save); + cp_set (ctx, UNK01, SET); + cp_set (ctx, SWAP_DIRECTION, SAVE); + + /* general PGRAPH state */ + cp_name(ctx, cp_swap_state); + cp_set (ctx, UNK03, SET); + cp_pos (ctx, 0x00004/4); + cp_ctx (ctx, 0x400828, 1); /* needed. otherwise, flickering happens. */ + cp_pos (ctx, 0x00100/4); + nv50_graph_construct_mmio(ctx); + nv50_graph_construct_xfer1(ctx); + nv50_graph_construct_xfer2(ctx); + + cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load); + + cp_set (ctx, UNK20, SET); + cp_set (ctx, SWAP_DIRECTION, SAVE); /* no idea why this is needed, but fixes at least one lockup. */ + cp_lsr (ctx, ctx->ctxvals_base); + cp_out (ctx, CP_SET_XFER_POINTER); + cp_lsr (ctx, 4); + cp_out (ctx, CP_SEEK_1); + cp_out (ctx, CP_XFER_1); + cp_wait(ctx, XFER, BUSY); + + /* pre-exit state updates */ + cp_name(ctx, cp_prepare_exit); + cp_set (ctx, UNK01, CLEAR); + cp_set (ctx, UNK03, CLEAR); + cp_set (ctx, UNK1D, CLEAR); + + cp_bra (ctx, USER_SAVE, PENDING, cp_exit); + cp_out (ctx, CP_NEXT_TO_CURRENT); + + cp_name(ctx, cp_exit); + cp_set (ctx, USER_SAVE, NOT_PENDING); + cp_set (ctx, USER_LOAD, NOT_PENDING); + cp_set (ctx, XFER_SWITCH, DISABLE); + cp_set (ctx, STATE, STOPPED); + cp_out (ctx, CP_END); + ctx->ctxvals_pos += 0x400; /* padding... no idea why you need it */ + + return 0; +} + +void +nv50_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) +{ + nv50_grctx_generate(&(struct nouveau_grctx) { + .device = device, + .mode = NOUVEAU_GRCTX_VALS, + .data = mem, + }); +} + +int +nv50_grctx_init(struct nouveau_device *device, u32 *size) +{ + u32 *ctxprog = kmalloc(512 * 4, GFP_KERNEL), i; + struct nouveau_grctx ctx = { + .device = device, + .mode = NOUVEAU_GRCTX_PROG, + .data = ctxprog, + .ctxprog_max = 512, + }; + + if (!ctxprog) + return -ENOMEM; + nv50_grctx_generate(&ctx); + + nv_wr32(device, 0x400324, 0); + for (i = 0; i < ctx.ctxprog_len; i++) + nv_wr32(device, 0x400328, ctxprog[i]); + *size = ctx.ctxvals_pos * 4; + kfree(ctxprog); + return 0; +} + +/* + * Constructs MMIO part of ctxprog and ctxvals. Just a matter of knowing which + * registers to save/restore and the default values for them. + */ + +static void +nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx); + +static void +nv50_graph_construct_mmio(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i, j; + int offset, base; + u32 units = nv_rd32 (ctx->device, 0x1540); + + /* 0800: DISPATCH */ + cp_ctx(ctx, 0x400808, 7); + gr_def(ctx, 0x400814, 0x00000030); + cp_ctx(ctx, 0x400834, 0x32); + if (device->chipset == 0x50) { + gr_def(ctx, 0x400834, 0xff400040); + gr_def(ctx, 0x400838, 0xfff00080); + gr_def(ctx, 0x40083c, 0xfff70090); + gr_def(ctx, 0x400840, 0xffe806a8); + } + gr_def(ctx, 0x400844, 0x00000002); + if (IS_NVA3F(device->chipset)) + gr_def(ctx, 0x400894, 0x00001000); + gr_def(ctx, 0x4008e8, 0x00000003); + gr_def(ctx, 0x4008ec, 0x00001000); + if (device->chipset == 0x50) + cp_ctx(ctx, 0x400908, 0xb); + else if (device->chipset < 0xa0) + cp_ctx(ctx, 0x400908, 0xc); + else + cp_ctx(ctx, 0x400908, 0xe); + + if (device->chipset >= 0xa0) + cp_ctx(ctx, 0x400b00, 0x1); + if (IS_NVA3F(device->chipset)) { + cp_ctx(ctx, 0x400b10, 0x1); + gr_def(ctx, 0x400b10, 0x0001629d); + cp_ctx(ctx, 0x400b20, 0x1); + gr_def(ctx, 0x400b20, 0x0001629d); + } + + nv50_graph_construct_mmio_ddata(ctx); + + /* 0C00: VFETCH */ + cp_ctx(ctx, 0x400c08, 0x2); + gr_def(ctx, 0x400c08, 0x0000fe0c); + + /* 1000 */ + if (device->chipset < 0xa0) { + cp_ctx(ctx, 0x401008, 0x4); + gr_def(ctx, 0x401014, 0x00001000); + } else if (!IS_NVA3F(device->chipset)) { + cp_ctx(ctx, 0x401008, 0x5); + gr_def(ctx, 0x401018, 0x00001000); + } else { + cp_ctx(ctx, 0x401008, 0x5); + gr_def(ctx, 0x401018, 0x00004000); + } + + /* 1400 */ + cp_ctx(ctx, 0x401400, 0x8); + cp_ctx(ctx, 0x401424, 0x3); + if (device->chipset == 0x50) + gr_def(ctx, 0x40142c, 0x0001fd87); + else + gr_def(ctx, 0x40142c, 0x00000187); + cp_ctx(ctx, 0x401540, 0x5); + gr_def(ctx, 0x401550, 0x00001018); + + /* 1800: STREAMOUT */ + cp_ctx(ctx, 0x401814, 0x1); + gr_def(ctx, 0x401814, 0x000000ff); + if (device->chipset == 0x50) { + cp_ctx(ctx, 0x40181c, 0xe); + gr_def(ctx, 0x401850, 0x00000004); + } else if (device->chipset < 0xa0) { + cp_ctx(ctx, 0x40181c, 0xf); + gr_def(ctx, 0x401854, 0x00000004); + } else { + cp_ctx(ctx, 0x40181c, 0x13); + gr_def(ctx, 0x401864, 0x00000004); + } + + /* 1C00 */ + cp_ctx(ctx, 0x401c00, 0x1); + switch (device->chipset) { + case 0x50: + gr_def(ctx, 0x401c00, 0x0001005f); + break; + case 0x84: + case 0x86: + case 0x94: + gr_def(ctx, 0x401c00, 0x044d00df); + break; + case 0x92: + case 0x96: + case 0x98: + case 0xa0: + case 0xaa: + case 0xac: + gr_def(ctx, 0x401c00, 0x042500df); + break; + case 0xa3: + case 0xa5: + case 0xa8: + case 0xaf: + gr_def(ctx, 0x401c00, 0x142500df); + break; + } + + /* 2000 */ + + /* 2400 */ + cp_ctx(ctx, 0x402400, 0x1); + if (device->chipset == 0x50) + cp_ctx(ctx, 0x402408, 0x1); + else + cp_ctx(ctx, 0x402408, 0x2); + gr_def(ctx, 0x402408, 0x00000600); + + /* 2800: CSCHED */ + cp_ctx(ctx, 0x402800, 0x1); + if (device->chipset == 0x50) + gr_def(ctx, 0x402800, 0x00000006); + + /* 2C00: ZCULL */ + cp_ctx(ctx, 0x402c08, 0x6); + if (device->chipset != 0x50) + gr_def(ctx, 0x402c14, 0x01000000); + gr_def(ctx, 0x402c18, 0x000000ff); + if (device->chipset == 0x50) + cp_ctx(ctx, 0x402ca0, 0x1); + else + cp_ctx(ctx, 0x402ca0, 0x2); + if (device->chipset < 0xa0) + gr_def(ctx, 0x402ca0, 0x00000400); + else if (!IS_NVA3F(device->chipset)) + gr_def(ctx, 0x402ca0, 0x00000800); + else + gr_def(ctx, 0x402ca0, 0x00000400); + cp_ctx(ctx, 0x402cac, 0x4); + + /* 3000: ENG2D */ + cp_ctx(ctx, 0x403004, 0x1); + gr_def(ctx, 0x403004, 0x00000001); + + /* 3400 */ + if (device->chipset >= 0xa0) { + cp_ctx(ctx, 0x403404, 0x1); + gr_def(ctx, 0x403404, 0x00000001); + } + + /* 5000: CCACHE */ + cp_ctx(ctx, 0x405000, 0x1); + switch (device->chipset) { + case 0x50: + gr_def(ctx, 0x405000, 0x00300080); + break; + case 0x84: + case 0xa0: + case 0xa3: + case 0xa5: + case 0xa8: + case 0xaa: + case 0xac: + case 0xaf: + gr_def(ctx, 0x405000, 0x000e0080); + break; + case 0x86: + case 0x92: + case 0x94: + case 0x96: + case 0x98: + gr_def(ctx, 0x405000, 0x00000080); + break; + } + cp_ctx(ctx, 0x405014, 0x1); + gr_def(ctx, 0x405014, 0x00000004); + cp_ctx(ctx, 0x40501c, 0x1); + cp_ctx(ctx, 0x405024, 0x1); + cp_ctx(ctx, 0x40502c, 0x1); + + /* 6000? */ + if (device->chipset == 0x50) + cp_ctx(ctx, 0x4063e0, 0x1); + + /* 6800: M2MF */ + if (device->chipset < 0x90) { + cp_ctx(ctx, 0x406814, 0x2b); + gr_def(ctx, 0x406818, 0x00000f80); + gr_def(ctx, 0x406860, 0x007f0080); + gr_def(ctx, 0x40689c, 0x007f0080); + } else { + cp_ctx(ctx, 0x406814, 0x4); + if (device->chipset == 0x98) + gr_def(ctx, 0x406818, 0x00000f80); + else + gr_def(ctx, 0x406818, 0x00001f80); + if (IS_NVA3F(device->chipset)) + gr_def(ctx, 0x40681c, 0x00000030); + cp_ctx(ctx, 0x406830, 0x3); + } + + /* 7000: per-ROP group state */ + for (i = 0; i < 8; i++) { + if (units & (1<<(i+16))) { + cp_ctx(ctx, 0x407000 + (i<<8), 3); + if (device->chipset == 0x50) + gr_def(ctx, 0x407000 + (i<<8), 0x1b74f820); + else if (device->chipset != 0xa5) + gr_def(ctx, 0x407000 + (i<<8), 0x3b74f821); + else + gr_def(ctx, 0x407000 + (i<<8), 0x7b74f821); + gr_def(ctx, 0x407004 + (i<<8), 0x89058001); + + if (device->chipset == 0x50) { + cp_ctx(ctx, 0x407010 + (i<<8), 1); + } else if (device->chipset < 0xa0) { + cp_ctx(ctx, 0x407010 + (i<<8), 2); + gr_def(ctx, 0x407010 + (i<<8), 0x00001000); + gr_def(ctx, 0x407014 + (i<<8), 0x0000001f); + } else { + cp_ctx(ctx, 0x407010 + (i<<8), 3); + gr_def(ctx, 0x407010 + (i<<8), 0x00001000); + if (device->chipset != 0xa5) + gr_def(ctx, 0x407014 + (i<<8), 0x000000ff); + else + gr_def(ctx, 0x407014 + (i<<8), 0x000001ff); + } + + cp_ctx(ctx, 0x407080 + (i<<8), 4); + if (device->chipset != 0xa5) + gr_def(ctx, 0x407080 + (i<<8), 0x027c10fa); + else + gr_def(ctx, 0x407080 + (i<<8), 0x827c10fa); + if (device->chipset == 0x50) + gr_def(ctx, 0x407084 + (i<<8), 0x000000c0); + else + gr_def(ctx, 0x407084 + (i<<8), 0x400000c0); + gr_def(ctx, 0x407088 + (i<<8), 0xb7892080); + + if (device->chipset < 0xa0) + cp_ctx(ctx, 0x407094 + (i<<8), 1); + else if (!IS_NVA3F(device->chipset)) + cp_ctx(ctx, 0x407094 + (i<<8), 3); + else { + cp_ctx(ctx, 0x407094 + (i<<8), 4); + gr_def(ctx, 0x4070a0 + (i<<8), 1); + } + } + } + + cp_ctx(ctx, 0x407c00, 0x3); + if (device->chipset < 0x90) + gr_def(ctx, 0x407c00, 0x00010040); + else if (device->chipset < 0xa0) + gr_def(ctx, 0x407c00, 0x00390040); + else + gr_def(ctx, 0x407c00, 0x003d0040); + gr_def(ctx, 0x407c08, 0x00000022); + if (device->chipset >= 0xa0) { + cp_ctx(ctx, 0x407c10, 0x3); + cp_ctx(ctx, 0x407c20, 0x1); + cp_ctx(ctx, 0x407c2c, 0x1); + } + + if (device->chipset < 0xa0) { + cp_ctx(ctx, 0x407d00, 0x9); + } else { + cp_ctx(ctx, 0x407d00, 0x15); + } + if (device->chipset == 0x98) + gr_def(ctx, 0x407d08, 0x00380040); + else { + if (device->chipset < 0x90) + gr_def(ctx, 0x407d08, 0x00010040); + else if (device->chipset < 0xa0) + gr_def(ctx, 0x407d08, 0x00390040); + else + gr_def(ctx, 0x407d08, 0x003d0040); + gr_def(ctx, 0x407d0c, 0x00000022); + } + + /* 8000+: per-TP state */ + for (i = 0; i < 10; i++) { + if (units & (1<<i)) { + if (device->chipset < 0xa0) + base = 0x408000 + (i<<12); + else + base = 0x408000 + (i<<11); + if (device->chipset < 0xa0) + offset = base + 0xc00; + else + offset = base + 0x80; + cp_ctx(ctx, offset + 0x00, 1); + gr_def(ctx, offset + 0x00, 0x0000ff0a); + cp_ctx(ctx, offset + 0x08, 1); + + /* per-MP state */ + for (j = 0; j < (device->chipset < 0xa0 ? 2 : 4); j++) { + if (!(units & (1 << (j+24)))) continue; + if (device->chipset < 0xa0) + offset = base + 0x200 + (j<<7); + else + offset = base + 0x100 + (j<<7); + cp_ctx(ctx, offset, 0x20); + gr_def(ctx, offset + 0x00, 0x01800000); + gr_def(ctx, offset + 0x04, 0x00160000); + gr_def(ctx, offset + 0x08, 0x01800000); + gr_def(ctx, offset + 0x18, 0x0003ffff); + switch (device->chipset) { + case 0x50: + gr_def(ctx, offset + 0x1c, 0x00080000); + break; + case 0x84: + gr_def(ctx, offset + 0x1c, 0x00880000); + break; + case 0x86: + gr_def(ctx, offset + 0x1c, 0x018c0000); + break; + case 0x92: + case 0x96: + case 0x98: + gr_def(ctx, offset + 0x1c, 0x118c0000); + break; + case 0x94: + gr_def(ctx, offset + 0x1c, 0x10880000); + break; + case 0xa0: + case 0xa5: + gr_def(ctx, offset + 0x1c, 0x310c0000); + break; + case 0xa3: + case 0xa8: + case 0xaa: + case 0xac: + case 0xaf: + gr_def(ctx, offset + 0x1c, 0x300c0000); + break; + } + gr_def(ctx, offset + 0x40, 0x00010401); + if (device->chipset == 0x50) + gr_def(ctx, offset + 0x48, 0x00000040); + else + gr_def(ctx, offset + 0x48, 0x00000078); + gr_def(ctx, offset + 0x50, 0x000000bf); + gr_def(ctx, offset + 0x58, 0x00001210); + if (device->chipset == 0x50) + gr_def(ctx, offset + 0x5c, 0x00000080); + else + gr_def(ctx, offset + 0x5c, 0x08000080); + if (device->chipset >= 0xa0) + gr_def(ctx, offset + 0x68, 0x0000003e); + } + + if (device->chipset < 0xa0) + cp_ctx(ctx, base + 0x300, 0x4); + else + cp_ctx(ctx, base + 0x300, 0x5); + if (device->chipset == 0x50) + gr_def(ctx, base + 0x304, 0x00007070); + else if (device->chipset < 0xa0) + gr_def(ctx, base + 0x304, 0x00027070); + else if (!IS_NVA3F(device->chipset)) + gr_def(ctx, base + 0x304, 0x01127070); + else + gr_def(ctx, base + 0x304, 0x05127070); + + if (device->chipset < 0xa0) + cp_ctx(ctx, base + 0x318, 1); + else + cp_ctx(ctx, base + 0x320, 1); + if (device->chipset == 0x50) + gr_def(ctx, base + 0x318, 0x0003ffff); + else if (device->chipset < 0xa0) + gr_def(ctx, base + 0x318, 0x03ffffff); + else + gr_def(ctx, base + 0x320, 0x07ffffff); + + if (device->chipset < 0xa0) + cp_ctx(ctx, base + 0x324, 5); + else + cp_ctx(ctx, base + 0x328, 4); + + if (device->chipset < 0xa0) { + cp_ctx(ctx, base + 0x340, 9); + offset = base + 0x340; + } else if (!IS_NVA3F(device->chipset)) { + cp_ctx(ctx, base + 0x33c, 0xb); + offset = base + 0x344; + } else { + cp_ctx(ctx, base + 0x33c, 0xd); + offset = base + 0x344; + } + gr_def(ctx, offset + 0x0, 0x00120407); + gr_def(ctx, offset + 0x4, 0x05091507); + if (device->chipset == 0x84) + gr_def(ctx, offset + 0x8, 0x05100202); + else + gr_def(ctx, offset + 0x8, 0x05010202); + gr_def(ctx, offset + 0xc, 0x00030201); + if (device->chipset == 0xa3) + cp_ctx(ctx, base + 0x36c, 1); + + cp_ctx(ctx, base + 0x400, 2); + gr_def(ctx, base + 0x404, 0x00000040); + cp_ctx(ctx, base + 0x40c, 2); + gr_def(ctx, base + 0x40c, 0x0d0c0b0a); + gr_def(ctx, base + 0x410, 0x00141210); + + if (device->chipset < 0xa0) + offset = base + 0x800; + else + offset = base + 0x500; + cp_ctx(ctx, offset, 6); + gr_def(ctx, offset + 0x0, 0x000001f0); + gr_def(ctx, offset + 0x4, 0x00000001); + gr_def(ctx, offset + 0x8, 0x00000003); + if (device->chipset == 0x50 || IS_NVAAF(device->chipset)) + gr_def(ctx, offset + 0xc, 0x00008000); + gr_def(ctx, offset + 0x14, 0x00039e00); + cp_ctx(ctx, offset + 0x1c, 2); + if (device->chipset == 0x50) + gr_def(ctx, offset + 0x1c, 0x00000040); + else + gr_def(ctx, offset + 0x1c, 0x00000100); + gr_def(ctx, offset + 0x20, 0x00003800); + + if (device->chipset >= 0xa0) { + cp_ctx(ctx, base + 0x54c, 2); + if (!IS_NVA3F(device->chipset)) + gr_def(ctx, base + 0x54c, 0x003fe006); + else + gr_def(ctx, base + 0x54c, 0x003fe007); + gr_def(ctx, base + 0x550, 0x003fe000); + } + + if (device->chipset < 0xa0) + offset = base + 0xa00; + else + offset = base + 0x680; + cp_ctx(ctx, offset, 1); + gr_def(ctx, offset, 0x00404040); + + if (device->chipset < 0xa0) + offset = base + 0xe00; + else + offset = base + 0x700; + cp_ctx(ctx, offset, 2); + if (device->chipset < 0xa0) + gr_def(ctx, offset, 0x0077f005); + else if (device->chipset == 0xa5) + gr_def(ctx, offset, 0x6cf7f007); + else if (device->chipset == 0xa8) + gr_def(ctx, offset, 0x6cfff007); + else if (device->chipset == 0xac) + gr_def(ctx, offset, 0x0cfff007); + else + gr_def(ctx, offset, 0x0cf7f007); + if (device->chipset == 0x50) + gr_def(ctx, offset + 0x4, 0x00007fff); + else if (device->chipset < 0xa0) + gr_def(ctx, offset + 0x4, 0x003f7fff); + else + gr_def(ctx, offset + 0x4, 0x02bf7fff); + cp_ctx(ctx, offset + 0x2c, 1); + if (device->chipset == 0x50) { + cp_ctx(ctx, offset + 0x50, 9); + gr_def(ctx, offset + 0x54, 0x000003ff); + gr_def(ctx, offset + 0x58, 0x00000003); + gr_def(ctx, offset + 0x5c, 0x00000003); + gr_def(ctx, offset + 0x60, 0x000001ff); + gr_def(ctx, offset + 0x64, 0x0000001f); + gr_def(ctx, offset + 0x68, 0x0000000f); + gr_def(ctx, offset + 0x6c, 0x0000000f); + } else if (device->chipset < 0xa0) { + cp_ctx(ctx, offset + 0x50, 1); + cp_ctx(ctx, offset + 0x70, 1); + } else { + cp_ctx(ctx, offset + 0x50, 1); + cp_ctx(ctx, offset + 0x60, 5); + } + } + } +} + +static void +dd_emit(struct nouveau_grctx *ctx, int num, u32 val) { + int i; + if (val && ctx->mode == NOUVEAU_GRCTX_VALS) + for (i = 0; i < num; i++) + nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + i), val); + ctx->ctxvals_pos += num; +} + +static void +nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int base, num; + base = ctx->ctxvals_pos; + + /* tesla state */ + dd_emit(ctx, 1, 0); /* 00000001 UNK0F90 */ + dd_emit(ctx, 1, 0); /* 00000001 UNK135C */ + + /* SRC_TIC state */ + dd_emit(ctx, 1, 0); /* 00000007 SRC_TILE_MODE_Z */ + dd_emit(ctx, 1, 2); /* 00000007 SRC_TILE_MODE_Y */ + dd_emit(ctx, 1, 1); /* 00000001 SRC_LINEAR #1 */ + dd_emit(ctx, 1, 0); /* 000000ff SRC_ADDRESS_HIGH */ + dd_emit(ctx, 1, 0); /* 00000001 SRC_SRGB */ + if (device->chipset >= 0x94) + dd_emit(ctx, 1, 0); /* 00000003 eng2d UNK0258 */ + dd_emit(ctx, 1, 1); /* 00000fff SRC_DEPTH */ + dd_emit(ctx, 1, 0x100); /* 0000ffff SRC_HEIGHT */ + + /* turing state */ + dd_emit(ctx, 1, 0); /* 0000000f TEXTURES_LOG2 */ + dd_emit(ctx, 1, 0); /* 0000000f SAMPLERS_LOG2 */ + dd_emit(ctx, 1, 0); /* 000000ff CB_DEF_ADDRESS_HIGH */ + dd_emit(ctx, 1, 0); /* ffffffff CB_DEF_ADDRESS_LOW */ + dd_emit(ctx, 1, 0); /* ffffffff SHARED_SIZE */ + dd_emit(ctx, 1, 2); /* ffffffff REG_MODE */ + dd_emit(ctx, 1, 1); /* 0000ffff BLOCK_ALLOC_THREADS */ + dd_emit(ctx, 1, 1); /* 00000001 LANES32 */ + dd_emit(ctx, 1, 0); /* 000000ff UNK370 */ + dd_emit(ctx, 1, 0); /* 000000ff USER_PARAM_UNK */ + dd_emit(ctx, 1, 0); /* 000000ff USER_PARAM_COUNT */ + dd_emit(ctx, 1, 1); /* 000000ff UNK384 bits 8-15 */ + dd_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ + dd_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ + dd_emit(ctx, 1, 0); /* 0000ffff CB_ADDR_INDEX */ + dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_X */ + dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_XMY */ + dd_emit(ctx, 1, 0); /* 00000001 BLOCKDIM_XMY_OVERFLOW */ + dd_emit(ctx, 1, 1); /* 0003ffff BLOCKDIM_XMYMZ */ + dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_Y */ + dd_emit(ctx, 1, 1); /* 0000007f BLOCKDIM_Z */ + dd_emit(ctx, 1, 4); /* 000000ff CP_REG_ALLOC_TEMP */ + dd_emit(ctx, 1, 1); /* 00000001 BLOCKDIM_DIRTY */ + if (IS_NVA3F(device->chipset)) + dd_emit(ctx, 1, 0); /* 00000003 UNK03E8 */ + dd_emit(ctx, 1, 1); /* 0000007f BLOCK_ALLOC_HALFWARPS */ + dd_emit(ctx, 1, 1); /* 00000007 LOCAL_WARPS_NO_CLAMP */ + dd_emit(ctx, 1, 7); /* 00000007 LOCAL_WARPS_LOG_ALLOC */ + dd_emit(ctx, 1, 1); /* 00000007 STACK_WARPS_NO_CLAMP */ + dd_emit(ctx, 1, 7); /* 00000007 STACK_WARPS_LOG_ALLOC */ + dd_emit(ctx, 1, 1); /* 00001fff BLOCK_ALLOC_REGSLOTS_PACKED */ + dd_emit(ctx, 1, 1); /* 00001fff BLOCK_ALLOC_REGSLOTS_STRIDED */ + dd_emit(ctx, 1, 1); /* 000007ff BLOCK_ALLOC_THREADS */ + + /* compat 2d state */ + if (device->chipset == 0x50) { + dd_emit(ctx, 4, 0); /* 0000ffff clip X, Y, W, H */ + + dd_emit(ctx, 1, 1); /* ffffffff chroma COLOR_FORMAT */ + + dd_emit(ctx, 1, 1); /* ffffffff pattern COLOR_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff pattern SHAPE */ + dd_emit(ctx, 1, 1); /* ffffffff pattern PATTERN_SELECT */ + + dd_emit(ctx, 1, 0xa); /* ffffffff surf2d SRC_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff surf2d DMA_SRC */ + dd_emit(ctx, 1, 0); /* 000000ff surf2d SRC_ADDRESS_HIGH */ + dd_emit(ctx, 1, 0); /* ffffffff surf2d SRC_ADDRESS_LOW */ + dd_emit(ctx, 1, 0x40); /* 0000ffff surf2d SRC_PITCH */ + dd_emit(ctx, 1, 0); /* 0000000f surf2d SRC_TILE_MODE_Z */ + dd_emit(ctx, 1, 2); /* 0000000f surf2d SRC_TILE_MODE_Y */ + dd_emit(ctx, 1, 0x100); /* ffffffff surf2d SRC_HEIGHT */ + dd_emit(ctx, 1, 1); /* 00000001 surf2d SRC_LINEAR */ + dd_emit(ctx, 1, 0x100); /* ffffffff surf2d SRC_WIDTH */ + + dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_B_X */ + dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_B_Y */ + dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_C_X */ + dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_C_Y */ + dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_D_X */ + dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_D_Y */ + dd_emit(ctx, 1, 1); /* ffffffff gdirect COLOR_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff gdirect OPERATION */ + dd_emit(ctx, 1, 0); /* 0000ffff gdirect POINT_X */ + dd_emit(ctx, 1, 0); /* 0000ffff gdirect POINT_Y */ + + dd_emit(ctx, 1, 0); /* 0000ffff blit SRC_Y */ + dd_emit(ctx, 1, 0); /* ffffffff blit OPERATION */ + + dd_emit(ctx, 1, 0); /* ffffffff ifc OPERATION */ + + dd_emit(ctx, 1, 0); /* ffffffff iifc INDEX_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff iifc LUT_OFFSET */ + dd_emit(ctx, 1, 4); /* ffffffff iifc COLOR_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff iifc OPERATION */ + } + + /* m2mf state */ + dd_emit(ctx, 1, 0); /* ffffffff m2mf LINE_COUNT */ + dd_emit(ctx, 1, 0); /* ffffffff m2mf LINE_LENGTH_IN */ + dd_emit(ctx, 2, 0); /* ffffffff m2mf OFFSET_IN, OFFSET_OUT */ + dd_emit(ctx, 1, 1); /* ffffffff m2mf TILING_DEPTH_OUT */ + dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_HEIGHT_OUT */ + dd_emit(ctx, 1, 0); /* ffffffff m2mf TILING_POSITION_OUT_Z */ + dd_emit(ctx, 1, 1); /* 00000001 m2mf LINEAR_OUT */ + dd_emit(ctx, 2, 0); /* 0000ffff m2mf TILING_POSITION_OUT_X, Y */ + dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_PITCH_OUT */ + dd_emit(ctx, 1, 1); /* ffffffff m2mf TILING_DEPTH_IN */ + dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_HEIGHT_IN */ + dd_emit(ctx, 1, 0); /* ffffffff m2mf TILING_POSITION_IN_Z */ + dd_emit(ctx, 1, 1); /* 00000001 m2mf LINEAR_IN */ + dd_emit(ctx, 2, 0); /* 0000ffff m2mf TILING_POSITION_IN_X, Y */ + dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_PITCH_IN */ + + /* more compat 2d state */ + if (device->chipset == 0x50) { + dd_emit(ctx, 1, 1); /* ffffffff line COLOR_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff line OPERATION */ + + dd_emit(ctx, 1, 1); /* ffffffff triangle COLOR_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff triangle OPERATION */ + + dd_emit(ctx, 1, 0); /* 0000000f sifm TILE_MODE_Z */ + dd_emit(ctx, 1, 2); /* 0000000f sifm TILE_MODE_Y */ + dd_emit(ctx, 1, 0); /* 000000ff sifm FORMAT_FILTER */ + dd_emit(ctx, 1, 1); /* 000000ff sifm FORMAT_ORIGIN */ + dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_PITCH */ + dd_emit(ctx, 1, 1); /* 00000001 sifm SRC_LINEAR */ + dd_emit(ctx, 1, 0); /* 000000ff sifm SRC_OFFSET_HIGH */ + dd_emit(ctx, 1, 0); /* ffffffff sifm SRC_OFFSET */ + dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_HEIGHT */ + dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_WIDTH */ + dd_emit(ctx, 1, 3); /* ffffffff sifm COLOR_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff sifm OPERATION */ + + dd_emit(ctx, 1, 0); /* ffffffff sifc OPERATION */ + } + + /* tesla state */ + dd_emit(ctx, 1, 0); /* 0000000f GP_TEXTURES_LOG2 */ + dd_emit(ctx, 1, 0); /* 0000000f GP_SAMPLERS_LOG2 */ + dd_emit(ctx, 1, 0); /* 000000ff */ + dd_emit(ctx, 1, 0); /* ffffffff */ + dd_emit(ctx, 1, 4); /* 000000ff UNK12B0_0 */ + dd_emit(ctx, 1, 0x70); /* 000000ff UNK12B0_1 */ + dd_emit(ctx, 1, 0x80); /* 000000ff UNK12B0_3 */ + dd_emit(ctx, 1, 0); /* 000000ff UNK12B0_2 */ + dd_emit(ctx, 1, 0); /* 0000000f FP_TEXTURES_LOG2 */ + dd_emit(ctx, 1, 0); /* 0000000f FP_SAMPLERS_LOG2 */ + if (IS_NVA3F(device->chipset)) { + dd_emit(ctx, 1, 0); /* ffffffff */ + dd_emit(ctx, 1, 0); /* 0000007f MULTISAMPLE_SAMPLES_LOG2 */ + } else { + dd_emit(ctx, 1, 0); /* 0000000f MULTISAMPLE_SAMPLES_LOG2 */ + } + dd_emit(ctx, 1, 0xc); /* 000000ff SEMANTIC_COLOR.BFC0_ID */ + if (device->chipset != 0x50) + dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_COLOR.CLMP_EN */ + dd_emit(ctx, 1, 8); /* 000000ff SEMANTIC_COLOR.COLR_NR */ + dd_emit(ctx, 1, 0x14); /* 000000ff SEMANTIC_COLOR.FFC0_ID */ + if (device->chipset == 0x50) { + dd_emit(ctx, 1, 0); /* 000000ff SEMANTIC_LAYER */ + dd_emit(ctx, 1, 0); /* 00000001 */ + } else { + dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_PTSZ.ENABLE */ + dd_emit(ctx, 1, 0x29); /* 000000ff SEMANTIC_PTSZ.PTSZ_ID */ + dd_emit(ctx, 1, 0x27); /* 000000ff SEMANTIC_PRIM */ + dd_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ + dd_emit(ctx, 1, 8); /* 0000000f SMENATIC_CLIP.CLIP_HIGH */ + dd_emit(ctx, 1, 4); /* 000000ff SEMANTIC_CLIP.CLIP_LO */ + dd_emit(ctx, 1, 0x27); /* 000000ff UNK0FD4 */ + dd_emit(ctx, 1, 0); /* 00000001 UNK1900 */ + } + dd_emit(ctx, 1, 0); /* 00000007 RT_CONTROL_MAP0 */ + dd_emit(ctx, 1, 1); /* 00000007 RT_CONTROL_MAP1 */ + dd_emit(ctx, 1, 2); /* 00000007 RT_CONTROL_MAP2 */ + dd_emit(ctx, 1, 3); /* 00000007 RT_CONTROL_MAP3 */ + dd_emit(ctx, 1, 4); /* 00000007 RT_CONTROL_MAP4 */ + dd_emit(ctx, 1, 5); /* 00000007 RT_CONTROL_MAP5 */ + dd_emit(ctx, 1, 6); /* 00000007 RT_CONTROL_MAP6 */ + dd_emit(ctx, 1, 7); /* 00000007 RT_CONTROL_MAP7 */ + dd_emit(ctx, 1, 1); /* 0000000f RT_CONTROL_COUNT */ + dd_emit(ctx, 8, 0); /* 00000001 RT_HORIZ_UNK */ + dd_emit(ctx, 8, 0); /* ffffffff RT_ADDRESS_LOW */ + dd_emit(ctx, 1, 0xcf); /* 000000ff RT_FORMAT */ + dd_emit(ctx, 7, 0); /* 000000ff RT_FORMAT */ + if (device->chipset != 0x50) + dd_emit(ctx, 3, 0); /* 1, 1, 1 */ + else + dd_emit(ctx, 2, 0); /* 1, 1 */ + dd_emit(ctx, 1, 0); /* ffffffff GP_ENABLE */ + dd_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT*/ + dd_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ + dd_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + if (IS_NVA3F(device->chipset)) { + dd_emit(ctx, 1, 3); /* 00000003 */ + dd_emit(ctx, 1, 0); /* 00000001 UNK1418. Alone. */ + } + if (device->chipset != 0x50) + dd_emit(ctx, 1, 3); /* 00000003 UNK15AC */ + dd_emit(ctx, 1, 1); /* ffffffff RASTERIZE_ENABLE */ + dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.EXPORTS_Z */ + if (device->chipset != 0x50) + dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.MULTIPLE_RESULTS */ + dd_emit(ctx, 1, 0x12); /* 000000ff FP_INTERPOLANT_CTRL.COUNT */ + dd_emit(ctx, 1, 0x10); /* 000000ff FP_INTERPOLANT_CTRL.COUNT_NONFLAT */ + dd_emit(ctx, 1, 0xc); /* 000000ff FP_INTERPOLANT_CTRL.OFFSET */ + dd_emit(ctx, 1, 1); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.W */ + dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.X */ + dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.Y */ + dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.Z */ + dd_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */ + dd_emit(ctx, 1, 2); /* ffffffff REG_MODE */ + dd_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ + if (device->chipset >= 0xa0) + dd_emit(ctx, 1, 0); /* ffffffff */ + dd_emit(ctx, 1, 0); /* 00000001 GP_BUILTIN_RESULT_EN.LAYER_IDX */ + dd_emit(ctx, 1, 0); /* ffffffff STRMOUT_ENABLE */ + dd_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ + dd_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ + dd_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE*/ + if (device->chipset != 0x50) + dd_emit(ctx, 8, 0); /* 00000001 */ + if (device->chipset >= 0xa0) { + dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.COMP */ + dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.SIZE */ + dd_emit(ctx, 1, 2); /* 00000007 VTX_ATTR_DEFINE.TYPE */ + dd_emit(ctx, 1, 0); /* 000000ff VTX_ATTR_DEFINE.ATTR */ + } + dd_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + dd_emit(ctx, 1, 0x14); /* 0000001f ZETA_FORMAT */ + dd_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + dd_emit(ctx, 1, 0); /* 0000000f VP_TEXTURES_LOG2 */ + dd_emit(ctx, 1, 0); /* 0000000f VP_SAMPLERS_LOG2 */ + if (IS_NVA3F(device->chipset)) + dd_emit(ctx, 1, 0); /* 00000001 */ + dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_BACK */ + if (device->chipset >= 0xa0) + dd_emit(ctx, 1, 0); /* 00000003 VTX_ATTR_DEFINE.SIZE - 1 */ + dd_emit(ctx, 1, 0); /* 0000ffff CB_ADDR_INDEX */ + if (device->chipset >= 0xa0) + dd_emit(ctx, 1, 0); /* 00000003 */ + dd_emit(ctx, 1, 0); /* 00000001 CULL_FACE_ENABLE */ + dd_emit(ctx, 1, 1); /* 00000003 CULL_FACE */ + dd_emit(ctx, 1, 0); /* 00000001 FRONT_FACE */ + dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_FRONT */ + dd_emit(ctx, 1, 0x1000); /* 00007fff UNK141C */ + if (device->chipset != 0x50) { + dd_emit(ctx, 1, 0xe00); /* 7fff */ + dd_emit(ctx, 1, 0x1000); /* 7fff */ + dd_emit(ctx, 1, 0x1e00); /* 7fff */ + } + dd_emit(ctx, 1, 0); /* 00000001 BEGIN_END_ACTIVE */ + dd_emit(ctx, 1, 1); /* 00000001 POLYGON_MODE_??? */ + dd_emit(ctx, 1, 1); /* 000000ff GP_REG_ALLOC_TEMP / 4 rounded up */ + dd_emit(ctx, 1, 1); /* 000000ff FP_REG_ALLOC_TEMP... without /4? */ + dd_emit(ctx, 1, 1); /* 000000ff VP_REG_ALLOC_TEMP / 4 rounded up */ + dd_emit(ctx, 1, 1); /* 00000001 */ + dd_emit(ctx, 1, 0); /* 00000001 */ + dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK0 nonempty */ + dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK1 nonempty */ + dd_emit(ctx, 1, 0x200); /* 0003ffff GP_VERTEX_OUTPUT_COUNT*GP_REG_ALLOC_RESULT */ + if (IS_NVA3F(device->chipset)) + dd_emit(ctx, 1, 0x200); + dd_emit(ctx, 1, 0); /* 00000001 */ + if (device->chipset < 0xa0) { + dd_emit(ctx, 1, 1); /* 00000001 */ + dd_emit(ctx, 1, 0x70); /* 000000ff */ + dd_emit(ctx, 1, 0x80); /* 000000ff */ + dd_emit(ctx, 1, 0); /* 000000ff */ + dd_emit(ctx, 1, 0); /* 00000001 */ + dd_emit(ctx, 1, 1); /* 00000001 */ + dd_emit(ctx, 1, 0x70); /* 000000ff */ + dd_emit(ctx, 1, 0x80); /* 000000ff */ + dd_emit(ctx, 1, 0); /* 000000ff */ + } else { + dd_emit(ctx, 1, 1); /* 00000001 */ + dd_emit(ctx, 1, 0xf0); /* 000000ff */ + dd_emit(ctx, 1, 0xff); /* 000000ff */ + dd_emit(ctx, 1, 0); /* 000000ff */ + dd_emit(ctx, 1, 0); /* 00000001 */ + dd_emit(ctx, 1, 1); /* 00000001 */ + dd_emit(ctx, 1, 0xf0); /* 000000ff */ + dd_emit(ctx, 1, 0xff); /* 000000ff */ + dd_emit(ctx, 1, 0); /* 000000ff */ + dd_emit(ctx, 1, 9); /* 0000003f UNK114C.COMP,SIZE */ + } + + /* eng2d state */ + dd_emit(ctx, 1, 0); /* 00000001 eng2d COLOR_KEY_ENABLE */ + dd_emit(ctx, 1, 0); /* 00000007 eng2d COLOR_KEY_FORMAT */ + dd_emit(ctx, 1, 1); /* ffffffff eng2d DST_DEPTH */ + dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d DST_FORMAT */ + dd_emit(ctx, 1, 0); /* ffffffff eng2d DST_LAYER */ + dd_emit(ctx, 1, 1); /* 00000001 eng2d DST_LINEAR */ + dd_emit(ctx, 1, 0); /* 00000007 eng2d PATTERN_COLOR_FORMAT */ + dd_emit(ctx, 1, 0); /* 00000007 eng2d OPERATION */ + dd_emit(ctx, 1, 0); /* 00000003 eng2d PATTERN_SELECT */ + dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d SIFC_FORMAT */ + dd_emit(ctx, 1, 0); /* 00000001 eng2d SIFC_BITMAP_ENABLE */ + dd_emit(ctx, 1, 2); /* 00000003 eng2d SIFC_BITMAP_UNK808 */ + dd_emit(ctx, 1, 0); /* ffffffff eng2d BLIT_DU_DX_FRACT */ + dd_emit(ctx, 1, 1); /* ffffffff eng2d BLIT_DU_DX_INT */ + dd_emit(ctx, 1, 0); /* ffffffff eng2d BLIT_DV_DY_FRACT */ + dd_emit(ctx, 1, 1); /* ffffffff eng2d BLIT_DV_DY_INT */ + dd_emit(ctx, 1, 0); /* 00000001 eng2d BLIT_CONTROL_FILTER */ + dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d DRAW_COLOR_FORMAT */ + dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d SRC_FORMAT */ + dd_emit(ctx, 1, 1); /* 00000001 eng2d SRC_LINEAR #2 */ + + num = ctx->ctxvals_pos - base; + ctx->ctxvals_pos = base; + if (IS_NVA3F(device->chipset)) + cp_ctx(ctx, 0x404800, num); + else + cp_ctx(ctx, 0x405400, num); +} + +/* + * xfer areas. These are a pain. + * + * There are 2 xfer areas: the first one is big and contains all sorts of + * stuff, the second is small and contains some per-TP context. + * + * Each area is split into 8 "strands". The areas, when saved to grctx, + * are made of 8-word blocks. Each block contains a single word from + * each strand. The strands are independent of each other, their + * addresses are unrelated to each other, and data in them is closely + * packed together. The strand layout varies a bit between cards: here + * and there, a single word is thrown out in the middle and the whole + * strand is offset by a bit from corresponding one on another chipset. + * For this reason, addresses of stuff in strands are almost useless. + * Knowing sequence of stuff and size of gaps between them is much more + * useful, and that's how we build the strands in our generator. + * + * NVA0 takes this mess to a whole new level by cutting the old strands + * into a few dozen pieces [known as genes], rearranging them randomly, + * and putting them back together to make new strands. Hopefully these + * genes correspond more or less directly to the same PGRAPH subunits + * as in 400040 register. + * + * The most common value in default context is 0, and when the genes + * are separated by 0's, gene bounduaries are quite speculative... + * some of them can be clearly deduced, others can be guessed, and yet + * others won't be resolved without figuring out the real meaning of + * given ctxval. For the same reason, ending point of each strand + * is unknown. Except for strand 0, which is the longest strand and + * its end corresponds to end of the whole xfer. + * + * An unsolved mystery is the seek instruction: it takes an argument + * in bits 8-18, and that argument is clearly the place in strands to + * seek to... but the offsets don't seem to correspond to offsets as + * seen in grctx. Perhaps there's another, real, not randomly-changing + * addressing in strands, and the xfer insn just happens to skip over + * the unused bits? NV10-NV30 PIPE comes to mind... + * + * As far as I know, there's no way to access the xfer areas directly + * without the help of ctxprog. + */ + +static void +xf_emit(struct nouveau_grctx *ctx, int num, u32 val) { + int i; + if (val && ctx->mode == NOUVEAU_GRCTX_VALS) + for (i = 0; i < num; i++) + nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + (i << 3)), val); + ctx->ctxvals_pos += num << 3; +} + +/* Gene declarations... */ + +static void nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx); +static void nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx); +static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx); + +static void +nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i; + int offset; + int size = 0; + u32 units = nv_rd32 (ctx->device, 0x1540); + + offset = (ctx->ctxvals_pos+0x3f)&~0x3f; + ctx->ctxvals_base = offset; + + if (device->chipset < 0xa0) { + /* Strand 0 */ + ctx->ctxvals_pos = offset; + nv50_graph_construct_gene_dispatch(ctx); + nv50_graph_construct_gene_m2mf(ctx); + nv50_graph_construct_gene_unk24xx(ctx); + nv50_graph_construct_gene_clipid(ctx); + nv50_graph_construct_gene_zcull(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 1 */ + ctx->ctxvals_pos = offset + 0x1; + nv50_graph_construct_gene_vfetch(ctx); + nv50_graph_construct_gene_eng2d(ctx); + nv50_graph_construct_gene_csched(ctx); + nv50_graph_construct_gene_ropm1(ctx); + nv50_graph_construct_gene_ropm2(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 2 */ + ctx->ctxvals_pos = offset + 0x2; + nv50_graph_construct_gene_ccache(ctx); + nv50_graph_construct_gene_unk1cxx(ctx); + nv50_graph_construct_gene_strmout(ctx); + nv50_graph_construct_gene_unk14xx(ctx); + nv50_graph_construct_gene_unk10xx(ctx); + nv50_graph_construct_gene_unk34xx(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 3: per-ROP group state */ + ctx->ctxvals_pos = offset + 3; + for (i = 0; i < 6; i++) + if (units & (1 << (i + 16))) + nv50_graph_construct_gene_ropc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strands 4-7: per-TP state */ + for (i = 0; i < 4; i++) { + ctx->ctxvals_pos = offset + 4 + i; + if (units & (1 << (2 * i))) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << (2 * i + 1))) + nv50_graph_construct_xfer_tp(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + } + } else { + /* Strand 0 */ + ctx->ctxvals_pos = offset; + nv50_graph_construct_gene_dispatch(ctx); + nv50_graph_construct_gene_m2mf(ctx); + nv50_graph_construct_gene_unk34xx(ctx); + nv50_graph_construct_gene_csched(ctx); + nv50_graph_construct_gene_unk1cxx(ctx); + nv50_graph_construct_gene_strmout(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 1 */ + ctx->ctxvals_pos = offset + 1; + nv50_graph_construct_gene_unk10xx(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 2 */ + ctx->ctxvals_pos = offset + 2; + if (device->chipset == 0xa0) + nv50_graph_construct_gene_unk14xx(ctx); + nv50_graph_construct_gene_unk24xx(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 3 */ + ctx->ctxvals_pos = offset + 3; + nv50_graph_construct_gene_vfetch(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 4 */ + ctx->ctxvals_pos = offset + 4; + nv50_graph_construct_gene_ccache(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 5 */ + ctx->ctxvals_pos = offset + 5; + nv50_graph_construct_gene_ropm2(ctx); + nv50_graph_construct_gene_ropm1(ctx); + /* per-ROP context */ + for (i = 0; i < 8; i++) + if (units & (1<<(i+16))) + nv50_graph_construct_gene_ropc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 6 */ + ctx->ctxvals_pos = offset + 6; + nv50_graph_construct_gene_zcull(ctx); + nv50_graph_construct_gene_clipid(ctx); + nv50_graph_construct_gene_eng2d(ctx); + if (units & (1 << 0)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 1)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 2)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 3)) + nv50_graph_construct_xfer_tp(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 7 */ + ctx->ctxvals_pos = offset + 7; + if (device->chipset == 0xa0) { + if (units & (1 << 4)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 5)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 6)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 7)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 8)) + nv50_graph_construct_xfer_tp(ctx); + if (units & (1 << 9)) + nv50_graph_construct_xfer_tp(ctx); + } else { + nv50_graph_construct_gene_unk14xx(ctx); + } + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + } + + ctx->ctxvals_pos = offset + size * 8; + ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f; + cp_lsr (ctx, offset); + cp_out (ctx, CP_SET_XFER_POINTER); + cp_lsr (ctx, size); + cp_out (ctx, CP_SEEK_1); + cp_out (ctx, CP_XFER_1); + cp_wait(ctx, XFER, BUSY); +} + +/* + * non-trivial demagiced parts of ctx init go here + */ + +static void +nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx) +{ + /* start of strand 0 */ + struct nouveau_device *device = ctx->device; + /* SEEK */ + if (device->chipset == 0x50) + xf_emit(ctx, 5, 0); + else if (!IS_NVA3F(device->chipset)) + xf_emit(ctx, 6, 0); + else + xf_emit(ctx, 4, 0); + /* SEEK */ + /* the PGRAPH's internal FIFO */ + if (device->chipset == 0x50) + xf_emit(ctx, 8*3, 0); + else + xf_emit(ctx, 0x100*3, 0); + /* and another bonus slot?!? */ + xf_emit(ctx, 3, 0); + /* and YET ANOTHER bonus slot? */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 3, 0); + /* SEEK */ + /* CTX_SWITCH: caches of gr objects bound to subchannels. 8 values, last used index */ + xf_emit(ctx, 9, 0); + /* SEEK */ + xf_emit(ctx, 9, 0); + /* SEEK */ + xf_emit(ctx, 9, 0); + /* SEEK */ + xf_emit(ctx, 9, 0); + /* SEEK */ + if (device->chipset < 0x90) + xf_emit(ctx, 4, 0); + /* SEEK */ + xf_emit(ctx, 2, 0); + /* SEEK */ + xf_emit(ctx, 6*2, 0); + xf_emit(ctx, 2, 0); + /* SEEK */ + xf_emit(ctx, 2, 0); + /* SEEK */ + xf_emit(ctx, 6*2, 0); + xf_emit(ctx, 2, 0); + /* SEEK */ + if (device->chipset == 0x50) + xf_emit(ctx, 0x1c, 0); + else if (device->chipset < 0xa0) + xf_emit(ctx, 0x1e, 0); + else + xf_emit(ctx, 0x22, 0); + /* SEEK */ + xf_emit(ctx, 0x15, 0); +} + +static void +nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx) +{ + /* Strand 0, right after dispatch */ + struct nouveau_device *device = ctx->device; + int smallm2mf = 0; + if (device->chipset < 0x92 || device->chipset == 0x98) + smallm2mf = 1; + /* SEEK */ + xf_emit (ctx, 1, 0); /* DMA_NOTIFY instance >> 4 */ + xf_emit (ctx, 1, 0); /* DMA_BUFFER_IN instance >> 4 */ + xf_emit (ctx, 1, 0); /* DMA_BUFFER_OUT instance >> 4 */ + xf_emit (ctx, 1, 0); /* OFFSET_IN */ + xf_emit (ctx, 1, 0); /* OFFSET_OUT */ + xf_emit (ctx, 1, 0); /* PITCH_IN */ + xf_emit (ctx, 1, 0); /* PITCH_OUT */ + xf_emit (ctx, 1, 0); /* LINE_LENGTH */ + xf_emit (ctx, 1, 0); /* LINE_COUNT */ + xf_emit (ctx, 1, 0x21); /* FORMAT: bits 0-4 INPUT_INC, bits 5-9 OUTPUT_INC */ + xf_emit (ctx, 1, 1); /* LINEAR_IN */ + xf_emit (ctx, 1, 0x2); /* TILING_MODE_IN: bits 0-2 y tiling, bits 3-5 z tiling */ + xf_emit (ctx, 1, 0x100); /* TILING_PITCH_IN */ + xf_emit (ctx, 1, 0x100); /* TILING_HEIGHT_IN */ + xf_emit (ctx, 1, 1); /* TILING_DEPTH_IN */ + xf_emit (ctx, 1, 0); /* TILING_POSITION_IN_Z */ + xf_emit (ctx, 1, 0); /* TILING_POSITION_IN */ + xf_emit (ctx, 1, 1); /* LINEAR_OUT */ + xf_emit (ctx, 1, 0x2); /* TILING_MODE_OUT: bits 0-2 y tiling, bits 3-5 z tiling */ + xf_emit (ctx, 1, 0x100); /* TILING_PITCH_OUT */ + xf_emit (ctx, 1, 0x100); /* TILING_HEIGHT_OUT */ + xf_emit (ctx, 1, 1); /* TILING_DEPTH_OUT */ + xf_emit (ctx, 1, 0); /* TILING_POSITION_OUT_Z */ + xf_emit (ctx, 1, 0); /* TILING_POSITION_OUT */ + xf_emit (ctx, 1, 0); /* OFFSET_IN_HIGH */ + xf_emit (ctx, 1, 0); /* OFFSET_OUT_HIGH */ + /* SEEK */ + if (smallm2mf) + xf_emit(ctx, 0x40, 0); /* 20 * ffffffff, 3ffff */ + else + xf_emit(ctx, 0x100, 0); /* 80 * ffffffff, 3ffff */ + xf_emit(ctx, 4, 0); /* 1f/7f, 0, 1f/7f, 0 [1f for smallm2mf, 7f otherwise] */ + /* SEEK */ + if (smallm2mf) + xf_emit(ctx, 0x400, 0); /* ffffffff */ + else + xf_emit(ctx, 0x800, 0); /* ffffffff */ + xf_emit(ctx, 4, 0); /* ff/1ff, 0, 0, 0 [ff for smallm2mf, 1ff otherwise] */ + /* SEEK */ + xf_emit(ctx, 0x40, 0); /* 20 * bits ffffffff, 3ffff */ + xf_emit(ctx, 0x6, 0); /* 1f, 0, 1f, 0, 1f, 0 */ +} + +static void +nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + xf_emit(ctx, 2, 0); /* RO */ + xf_emit(ctx, 0x800, 0); /* ffffffff */ + switch (device->chipset) { + case 0x50: + case 0x92: + case 0xa0: + xf_emit(ctx, 0x2b, 0); + break; + case 0x84: + xf_emit(ctx, 0x29, 0); + break; + case 0x94: + case 0x96: + case 0xa3: + xf_emit(ctx, 0x27, 0); + break; + case 0x86: + case 0x98: + case 0xa5: + case 0xa8: + case 0xaa: + case 0xac: + case 0xaf: + xf_emit(ctx, 0x25, 0); + break; + } + /* CB bindings, 0x80 of them. first word is address >> 8, second is + * size >> 4 | valid << 24 */ + xf_emit(ctx, 0x100, 0); /* ffffffff CB_DEF */ + xf_emit(ctx, 1, 0); /* 0000007f CB_ADDR_BUFFER */ + xf_emit(ctx, 1, 0); /* 0 */ + xf_emit(ctx, 0x30, 0); /* ff SET_PROGRAM_CB */ + xf_emit(ctx, 1, 0); /* 3f last SET_PROGRAM_CB */ + xf_emit(ctx, 4, 0); /* RO */ + xf_emit(ctx, 0x100, 0); /* ffffffff */ + xf_emit(ctx, 8, 0); /* 1f, 0, 0, ... */ + xf_emit(ctx, 8, 0); /* ffffffff */ + xf_emit(ctx, 4, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 3 */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_CODE_CB */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_TIC */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_TSC */ + xf_emit(ctx, 1, 0); /* 00000001 LINKED_TSC */ + xf_emit(ctx, 1, 0); /* 000000ff TIC_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff TIC_ADDRESS_LOW */ + xf_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ + xf_emit(ctx, 1, 0); /* 000000ff TSC_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff TSC_ADDRESS_LOW */ + xf_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ + xf_emit(ctx, 1, 0); /* 000000ff VP_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff VP_ADDRESS_LOW */ + xf_emit(ctx, 1, 0); /* 00ffffff VP_START_ID */ + xf_emit(ctx, 1, 0); /* 000000ff CB_DEF_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff CB_DEF_ADDRESS_LOW */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0); /* 000000ff GP_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff GP_ADDRESS_LOW */ + xf_emit(ctx, 1, 0); /* 00ffffff GP_START_ID */ + xf_emit(ctx, 1, 0); /* 000000ff FP_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff FP_ADDRESS_LOW */ + xf_emit(ctx, 1, 0); /* 00ffffff FP_START_ID */ +} + +static void +nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i; + /* end of area 2 on pre-NVA0, area 1 on NVAx */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ + xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ + xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ + xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ + if (device->chipset == 0x50) + xf_emit(ctx, 1, 0x3ff); + else + xf_emit(ctx, 1, 0x7ff); /* 000007ff */ + xf_emit(ctx, 1, 0); /* 111/113 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + for (i = 0; i < 8; i++) { + switch (device->chipset) { + case 0x50: + case 0x86: + case 0x98: + case 0xaa: + case 0xac: + xf_emit(ctx, 0xa0, 0); /* ffffffff */ + break; + case 0x84: + case 0x92: + case 0x94: + case 0x96: + xf_emit(ctx, 0x120, 0); + break; + case 0xa5: + case 0xa8: + xf_emit(ctx, 0x100, 0); /* ffffffff */ + break; + case 0xa0: + case 0xa3: + case 0xaf: + xf_emit(ctx, 0x400, 0); /* ffffffff */ + break; + } + xf_emit(ctx, 4, 0); /* 3f, 0, 0, 0 */ + xf_emit(ctx, 4, 0); /* ffffffff */ + } + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ + xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_TEMP */ + xf_emit(ctx, 1, 1); /* 00000001 RASTERIZE_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 0x27); /* 000000ff UNK0FD4 */ + xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ + xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ +} + +static void +nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + /* end of area 2 on pre-NVA0, area 1 on NVAx */ + xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */ + xf_emit(ctx, 1, 0); /* 00000003 VIEWPORT_CLIP_MODE */ + xf_emit(ctx, 0x10, 0x04000000); /* 07ffffff VIEWPORT_CLIP_HORIZ*8, VIEWPORT_CLIP_VERT*8 */ + xf_emit(ctx, 1, 0); /* 00000001 POLYGON_STIPPLE_ENABLE */ + xf_emit(ctx, 0x20, 0); /* ffffffff POLYGON_STIPPLE */ + xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0D64 */ + xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0DF4 */ + xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0x1fe21); /* 0001ffff tesla UNK0FAC */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 1, 0x0fac6881); + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 1); + xf_emit(ctx, 3, 0); + } +} + +static void +nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + /* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */ + if (device->chipset != 0x50) { + xf_emit(ctx, 5, 0); /* ffffffff */ + xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + xf_emit(ctx, 1, 0x804); /* 00000fff SEMANTIC_CLIP */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 2, 4); /* 7f, ff */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + } + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 1, 0); /* 000000ff VP_CLIP_DISTANCE_ENABLE */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 0); /* 3ff */ + xf_emit(ctx, 1, 0); /* 000000ff tesla UNK1940 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0D7C */ + xf_emit(ctx, 1, 0x804); /* 00000fff SEMANTIC_CLIP */ + xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ + xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 0x7f); /* 000000ff tesla UNK0FFC */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 1); /* 00000001 SHADE_MODEL */ + xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0D7C */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0F8C */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 4, 0); /* ffffffff NOPERSPECTIVE_BITMAP */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 0); /* 0000000f */ + if (device->chipset == 0x50) + xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */ + else + xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */ + xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ + xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ + xf_emit(ctx, 0x30, 0); /* ffffffff VIEWPORT_SCALE: X0, Y0, Z0, X1, Y1, ... */ + xf_emit(ctx, 3, 0); /* f, 0, 0 */ + xf_emit(ctx, 3, 0); /* ffffffff last VIEWPORT_SCALE? */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ + xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 0x30, 0); /* ffffffff VIEWPORT_TRANSLATE */ + xf_emit(ctx, 3, 0); /* f, 0, 0 */ + xf_emit(ctx, 3, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 2, 0x88); /* 000001ff tesla UNK19D8 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ + xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ + xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ + xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ + xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ + xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ + xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 0); /* 0000000f */ + xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ + if (device->chipset != 0x50) { + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + } + xf_emit(ctx, 0x20, 0); /* 10xbits ffffffff, 3fffff. SCISSOR_* */ + xf_emit(ctx, 1, 0); /* f */ + xf_emit(ctx, 1, 0); /* 0? */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 003fffff */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 0x52); /* 000001ff SEMANTIC_PTSZ */ + xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ + xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ + xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ + xf_emit(ctx, 1, 0); /* 0000000f */ +} + +static void +nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + /* end of strand 0 on pre-NVA0, beginning of strand 6 on NVAx */ + /* SEEK */ + xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */ + xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ + xf_emit(ctx, 2, 0x04000000); /* 07ffffff tesla UNK0D6C */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 0); /* 00000001 CLIPID_ENABLE */ + xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ + xf_emit(ctx, 1, 0); /* 0000ffff */ + xf_emit(ctx, 1, 0); /* 00000001 UNK0FB0 */ + xf_emit(ctx, 1, 0); /* 00000001 POLYGON_STIPPLE_ENABLE */ + xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ + xf_emit(ctx, 1, 0); /* 000000ff CLEAR_STENCIL */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ + xf_emit(ctx, 1, 0); /* 00000007 */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1108 */ + xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0x1001); /* 00001fff ZETA_ARRAY_MODE */ + /* SEEK */ + xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ + xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ + xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ + xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ + xf_emit(ctx, 1, 0x10); /* 7f/ff/3ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */ + xf_emit(ctx, 1, 3); /* 00000003 FP_CTRL_UNK196C */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1968 */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 0); /* 0fffffff tesla UNK1104 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK151C */ +} + +static void +nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx) +{ + /* middle of strand 0 on pre-NVA0 [after 24xx], middle of area 6 on NVAx */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* 00000007 UNK0FB4 */ + /* SEEK */ + xf_emit(ctx, 4, 0); /* 07ffffff CLIPID_REGION_HORIZ */ + xf_emit(ctx, 4, 0); /* 07ffffff CLIPID_REGION_VERT */ + xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ + xf_emit(ctx, 2, 0x04000000); /* 07ffffff UNK1508 */ + xf_emit(ctx, 1, 0); /* 00000001 CLIPID_ENABLE */ + xf_emit(ctx, 1, 0x80); /* 00003fff CLIPID_WIDTH */ + xf_emit(ctx, 1, 0); /* 000000ff CLIPID_ID */ + xf_emit(ctx, 1, 0); /* 000000ff CLIPID_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff CLIPID_ADDRESS_LOW */ + xf_emit(ctx, 1, 0x80); /* 00003fff CLIPID_HEIGHT */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_CLIPID */ +} + +static void +nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i; + /* middle of strand 0 on pre-NVA0 [after m2mf], end of strand 2 on NVAx */ + /* SEEK */ + xf_emit(ctx, 0x33, 0); + /* SEEK */ + xf_emit(ctx, 2, 0); + /* SEEK */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + /* SEEK */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 4, 0); /* RO */ + xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ + xf_emit(ctx, 1, 0); /* 1ff */ + xf_emit(ctx, 8, 0); /* 0? */ + xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ + + xf_emit(ctx, 4, 0); /* RO */ + xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ + xf_emit(ctx, 1, 0); /* 1ff */ + xf_emit(ctx, 8, 0); /* 0? */ + xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ + } else { + xf_emit(ctx, 0xc, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ + xf_emit(ctx, 1, 0); /* 1ff */ + xf_emit(ctx, 8, 0); /* 0? */ + + /* SEEK */ + xf_emit(ctx, 0xc, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ + xf_emit(ctx, 1, 0); /* 1ff */ + xf_emit(ctx, 8, 0); /* 0? */ + } + /* SEEK */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ + xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ + xf_emit(ctx, 1, 1); /* 00000001 */ + /* SEEK */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 2, 4); /* 000000ff */ + xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ + xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 1, 0x27); /* 000000ff SEMANTIC_PRIM_ID */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000000f */ + xf_emit(ctx, 1, 1); /* 00000001 */ + for (i = 0; i < 10; i++) { + /* SEEK */ + xf_emit(ctx, 0x40, 0); /* ffffffff */ + xf_emit(ctx, 0x10, 0); /* 3, 0, 0.... */ + xf_emit(ctx, 0x10, 0); /* ffffffff */ + } + /* SEEK */ + xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_CTRL */ + xf_emit(ctx, 1, 1); /* 00000001 */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 4, 0); /* ffffffff NOPERSPECTIVE_BITMAP */ + xf_emit(ctx, 0x10, 0); /* 00ffffff POINT_COORD_REPLACE_MAP */ + xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 0); /* 000003ff */ +} + +static void +nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int acnt = 0x10, rep, i; + /* beginning of strand 1 on pre-NVA0, strand 3 on NVAx */ + if (IS_NVA3F(device->chipset)) + acnt = 0x20; + /* SEEK */ + if (device->chipset >= 0xa0) { + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK13A4 */ + xf_emit(ctx, 1, 1); /* 00000fff tesla UNK1318 */ + } + xf_emit(ctx, 1, 0); /* ffffffff VERTEX_BUFFER_FIRST */ + xf_emit(ctx, 1, 0); /* 00000001 PRIMITIVE_RESTART_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 UNK0DE8 */ + xf_emit(ctx, 1, 0); /* ffffffff PRIMITIVE_RESTART_INDEX */ + xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, acnt/8, 0); /* ffffffff VTX_ATR_MASK_UNK0DD0 */ + xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ + xf_emit(ctx, 1, 0x20); /* 0000ffff tesla UNK129C */ + xf_emit(ctx, 1, 0); /* 000000ff turing UNK370??? */ + xf_emit(ctx, 1, 0); /* 0000ffff turing USER_PARAM_COUNT */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + /* SEEK */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 0xb, 0); /* RO */ + else if (device->chipset >= 0xa0) + xf_emit(ctx, 0x9, 0); /* RO */ + else + xf_emit(ctx, 0x8, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* 00000001 EDGE_FLAG */ + xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + /* SEEK */ + xf_emit(ctx, 0xc, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* 7f/ff */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ + xf_emit(ctx, 1, 4); /* 000001ff UNK1A28 */ + xf_emit(ctx, 1, 8); /* 000001ff UNK0DF0 */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + if (device->chipset == 0x50) + xf_emit(ctx, 1, 0x3ff); /* 3ff tesla UNK0D68 */ + else + xf_emit(ctx, 1, 0x7ff); /* 7ff tesla UNK0D68 */ + if (device->chipset == 0xa8) + xf_emit(ctx, 1, 0x1e00); /* 7fff */ + /* SEEK */ + xf_emit(ctx, 0xc, 0); /* RO or close */ + /* SEEK */ + xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ + if (device->chipset > 0x50 && device->chipset < 0xa0) + xf_emit(ctx, 2, 0); /* ffffffff */ + else + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0FD8 */ + /* SEEK */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 0x10, 0); /* 0? */ + xf_emit(ctx, 2, 0); /* weird... */ + xf_emit(ctx, 2, 0); /* RO */ + } else { + xf_emit(ctx, 8, 0); /* 0? */ + xf_emit(ctx, 1, 0); /* weird... */ + xf_emit(ctx, 2, 0); /* RO */ + } + /* SEEK */ + xf_emit(ctx, 1, 0); /* ffffffff VB_ELEMENT_BASE */ + xf_emit(ctx, 1, 0); /* ffffffff UNK1438 */ + xf_emit(ctx, acnt, 0); /* 1 tesla UNK1000 */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1118? */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_UNK90C */ + xf_emit(ctx, 1, 0); /* f/1f */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_UNK90C */ + xf_emit(ctx, 1, 0); /* f/1f */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* RO */ + xf_emit(ctx, 2, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK111C? */ + xf_emit(ctx, 1, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* 000000ff UNK15F4_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff UNK15F4_ADDRESS_LOW */ + xf_emit(ctx, 1, 0); /* 000000ff UNK0F84_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff UNK0F84_ADDRESS_LOW */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* 00003fff VERTEX_ARRAY_ATTRIB_OFFSET */ + xf_emit(ctx, 3, 0); /* f/1f */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* 00000fff VERTEX_ARRAY_STRIDE */ + xf_emit(ctx, 3, 0); /* f/1f */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_LOW */ + xf_emit(ctx, 3, 0); /* f/1f */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* 000000ff VERTEX_ARRAY_HIGH */ + xf_emit(ctx, 3, 0); /* f/1f */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_LIMIT_LOW */ + xf_emit(ctx, 3, 0); /* f/1f */ + /* SEEK */ + xf_emit(ctx, acnt, 0); /* 000000ff VERTEX_LIMIT_HIGH */ + xf_emit(ctx, 3, 0); /* f/1f */ + /* SEEK */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, acnt, 0); /* f */ + xf_emit(ctx, 3, 0); /* f/1f */ + } + /* SEEK */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 2, 0); /* RO */ + else + xf_emit(ctx, 5, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* ffff DMA_VTXBUF */ + /* SEEK */ + if (device->chipset < 0xa0) { + xf_emit(ctx, 0x41, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 0x11, 0); /* RO */ + } else if (!IS_NVA3F(device->chipset)) + xf_emit(ctx, 0x50, 0); /* RO */ + else + xf_emit(ctx, 0x58, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, 1, 1); /* 1 UNK0DEC */ + /* SEEK */ + xf_emit(ctx, acnt*4, 0); /* ffffffff VTX_ATTR */ + xf_emit(ctx, 4, 0); /* f/1f, 0, 0, 0 */ + /* SEEK */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 0x1d, 0); /* RO */ + else + xf_emit(ctx, 0x16, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ + /* SEEK */ + if (device->chipset < 0xa0) + xf_emit(ctx, 8, 0); /* RO */ + else if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 0xc, 0); /* RO */ + else + xf_emit(ctx, 7, 0); /* RO */ + /* SEEK */ + xf_emit(ctx, 0xa, 0); /* RO */ + if (device->chipset == 0xa0) + rep = 0xc; + else + rep = 4; + for (i = 0; i < rep; i++) { + /* SEEK */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 0x20, 0); /* ffffffff */ + xf_emit(ctx, 0x200, 0); /* ffffffff */ + xf_emit(ctx, 4, 0); /* 7f/ff, 0, 0, 0 */ + xf_emit(ctx, 4, 0); /* ffffffff */ + } + /* SEEK */ + xf_emit(ctx, 1, 0); /* 113/111 */ + xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ + xf_emit(ctx, acnt/8, 0); /* ffffffff VTX_ATTR_MASK_UNK0DD0 */ + xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + /* SEEK */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 7, 0); /* weird... */ + else + xf_emit(ctx, 5, 0); /* weird... */ +} + +static void +nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + /* middle of strand 1 on pre-NVA0 [after vfetch], middle of strand 6 on NVAx */ + /* SEEK */ + xf_emit(ctx, 2, 0); /* 0001ffff CLIP_X, CLIP_Y */ + xf_emit(ctx, 2, 0); /* 0000ffff CLIP_W, CLIP_H */ + xf_emit(ctx, 1, 0); /* 00000001 CLIP_ENABLE */ + if (device->chipset < 0xa0) { + /* this is useless on everything but the original NV50, + * guess they forgot to nuke it. Or just didn't bother. */ + xf_emit(ctx, 2, 0); /* 0000ffff IFC_CLIP_X, Y */ + xf_emit(ctx, 2, 1); /* 0000ffff IFC_CLIP_W, H */ + xf_emit(ctx, 1, 0); /* 00000001 IFC_CLIP_ENABLE */ + } + xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ + xf_emit(ctx, 1, 0x100); /* 0001ffff DST_WIDTH */ + xf_emit(ctx, 1, 0x100); /* 0001ffff DST_HEIGHT */ + xf_emit(ctx, 1, 0x11); /* 3f[NV50]/7f[NV84+] DST_FORMAT */ + xf_emit(ctx, 1, 0); /* 0001ffff DRAW_POINT_X */ + xf_emit(ctx, 1, 8); /* 0000000f DRAW_UNK58C */ + xf_emit(ctx, 1, 0); /* 000fffff SIFC_DST_X_FRACT */ + xf_emit(ctx, 1, 0); /* 0001ffff SIFC_DST_X_INT */ + xf_emit(ctx, 1, 0); /* 000fffff SIFC_DST_Y_FRACT */ + xf_emit(ctx, 1, 0); /* 0001ffff SIFC_DST_Y_INT */ + xf_emit(ctx, 1, 0); /* 000fffff SIFC_DX_DU_FRACT */ + xf_emit(ctx, 1, 1); /* 0001ffff SIFC_DX_DU_INT */ + xf_emit(ctx, 1, 0); /* 000fffff SIFC_DY_DV_FRACT */ + xf_emit(ctx, 1, 1); /* 0001ffff SIFC_DY_DV_INT */ + xf_emit(ctx, 1, 1); /* 0000ffff SIFC_WIDTH */ + xf_emit(ctx, 1, 1); /* 0000ffff SIFC_HEIGHT */ + xf_emit(ctx, 1, 0xcf); /* 000000ff SIFC_FORMAT */ + xf_emit(ctx, 1, 2); /* 00000003 SIFC_BITMAP_UNK808 */ + xf_emit(ctx, 1, 0); /* 00000003 SIFC_BITMAP_LINE_PACK_MODE */ + xf_emit(ctx, 1, 0); /* 00000001 SIFC_BITMAP_LSB_FIRST */ + xf_emit(ctx, 1, 0); /* 00000001 SIFC_BITMAP_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000ffff BLIT_DST_X */ + xf_emit(ctx, 1, 0); /* 0000ffff BLIT_DST_Y */ + xf_emit(ctx, 1, 0); /* 000fffff BLIT_DU_DX_FRACT */ + xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DU_DX_INT */ + xf_emit(ctx, 1, 0); /* 000fffff BLIT_DV_DY_FRACT */ + xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DV_DY_INT */ + xf_emit(ctx, 1, 1); /* 0000ffff BLIT_DST_W */ + xf_emit(ctx, 1, 1); /* 0000ffff BLIT_DST_H */ + xf_emit(ctx, 1, 0); /* 000fffff BLIT_SRC_X_FRACT */ + xf_emit(ctx, 1, 0); /* 0001ffff BLIT_SRC_X_INT */ + xf_emit(ctx, 1, 0); /* 000fffff BLIT_SRC_Y_FRACT */ + xf_emit(ctx, 1, 0); /* 00000001 UNK888 */ + xf_emit(ctx, 1, 4); /* 0000003f UNK884 */ + xf_emit(ctx, 1, 0); /* 00000007 UNK880 */ + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK0FB8 */ + xf_emit(ctx, 1, 0x15); /* 000000ff tesla UNK128C */ + xf_emit(ctx, 2, 0); /* 00000007, ffff0ff3 */ + xf_emit(ctx, 1, 0); /* 00000001 UNK260 */ + xf_emit(ctx, 1, 0x4444480); /* 1fffffff UNK870 */ + /* SEEK */ + xf_emit(ctx, 0x10, 0); + /* SEEK */ + xf_emit(ctx, 0x27, 0); +} + +static void +nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + /* middle of strand 1 on pre-NVA0 [after eng2d], middle of strand 0 on NVAx */ + /* SEEK */ + xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY... what is it doing here??? */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ + xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 1, 0); /* 000003ff */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* ffffffff turing UNK364 */ + xf_emit(ctx, 1, 0); /* 0000000f turing UNK36C */ + xf_emit(ctx, 1, 0); /* 0000ffff USER_PARAM_COUNT */ + xf_emit(ctx, 1, 0x100); /* 00ffffff turing UNK384 */ + xf_emit(ctx, 1, 0); /* 0000000f turing UNK2A0 */ + xf_emit(ctx, 1, 0); /* 0000ffff GRIDID */ + xf_emit(ctx, 1, 0x10001); /* ffffffff GRIDDIM_XY */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0x10001); /* ffffffff BLOCKDIM_XY */ + xf_emit(ctx, 1, 1); /* 0000ffff BLOCKDIM_Z */ + xf_emit(ctx, 1, 0x10001); /* 00ffffff BLOCK_ALLOC */ + xf_emit(ctx, 1, 1); /* 00000001 LANES32 */ + xf_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ + xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ + /* SEEK */ + xf_emit(ctx, 0x40, 0); /* ffffffff USER_PARAM */ + switch (device->chipset) { + case 0x50: + case 0x92: + xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ + xf_emit(ctx, 0x80, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 0x10*2, 0); /* ffffffff, 1f */ + break; + case 0x84: + xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ + xf_emit(ctx, 0x60, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 0xc*2, 0); /* ffffffff, 1f */ + break; + case 0x94: + case 0x96: + xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ + xf_emit(ctx, 0x40, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 8*2, 0); /* ffffffff, 1f */ + break; + case 0x86: + case 0x98: + xf_emit(ctx, 4, 0); /* f, 0, 0, 0 */ + xf_emit(ctx, 0x10, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 2*2, 0); /* ffffffff, 1f */ + break; + case 0xa0: + xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ + xf_emit(ctx, 0xf0, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 0x1e*2, 0); /* ffffffff, 1f */ + break; + case 0xa3: + xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ + xf_emit(ctx, 0x60, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 0xc*2, 0); /* ffffffff, 1f */ + break; + case 0xa5: + case 0xaf: + xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ + xf_emit(ctx, 0x30, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 6*2, 0); /* ffffffff, 1f */ + break; + case 0xaa: + xf_emit(ctx, 0x12, 0); + break; + case 0xa8: + case 0xac: + xf_emit(ctx, 4, 0); /* f, 0, 0, 0 */ + xf_emit(ctx, 0x10, 0); /* fff */ + xf_emit(ctx, 2, 0); /* ff, fff */ + xf_emit(ctx, 2*2, 0); /* ffffffff, 1f */ + break; + } + xf_emit(ctx, 1, 0); /* 0000000f */ + xf_emit(ctx, 1, 0); /* 00000000 */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 0000001f */ + xf_emit(ctx, 4, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 00000003 turing UNK35C */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 4, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 00000003 turing UNK35C */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 000000ff */ +} + +static void +nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ + xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1658 */ + xf_emit(ctx, 1, 0); /* 00000001 POLYGON_SMOOTH_ENABLE */ + xf_emit(ctx, 3, 0); /* 00000001 POLYGON_OFFSET_*_ENABLE */ + xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ + xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK165C */ + xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ + xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ + xf_emit(ctx, 1, 0); /* ffffffff POLYGON_OFFSET_UNITS */ + xf_emit(ctx, 1, 0); /* ffffffff POLYGON_OFFSET_FACTOR */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1668 */ + xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 1, 0x11); /* 0000007f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 0000007f RT_FORMAT */ + xf_emit(ctx, 8, 0); /* 00000001 RT_HORIZ_LINEAR */ + xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 3); /* 00000003 UNK16B4 */ + else if (device->chipset >= 0xa0) + xf_emit(ctx, 1, 1); /* 00000001 UNK16B4 */ + xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */ + xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ + xf_emit(ctx, 2, 0x04000000); /* 07ffffff tesla UNK0D6C */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ + xf_emit(ctx, 1, 5); /* 0000000f UNK1408 */ + xf_emit(ctx, 1, 0x52); /* 000001ff SEMANTIC_PTSZ */ + xf_emit(ctx, 1, 0); /* ffffffff POINT_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 00000007 tesla UNK0FB4 */ + if (device->chipset != 0x50) { + xf_emit(ctx, 1, 0); /* 3ff */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK1110 */ + } + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1928 */ + xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ + xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ + xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 0x20, 0); /* 07ffffff VIEWPORT_HORIZ, then VIEWPORT_VERT. (W&0x3fff)<<13 | (X&0x1fff). */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK187C */ + xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ + xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 1, 5); /* 0000000f tesla UNK1220 */ + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 000000ff tesla UNK1A20 */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ + xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ + if (device->chipset < 0xa0) + xf_emit(ctx, 0x1c, 0); /* RO */ + else if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 0x9, 0); + xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ + xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ + xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ + xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ + if (device->chipset != 0x50) { + xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ + xf_emit(ctx, 1, 0); /* 3ff */ + } + /* XXX: the following block could belong either to unk1cxx, or + * to STRMOUT. Rather hard to tell. */ + if (device->chipset < 0xa0) + xf_emit(ctx, 0x25, 0); + else + xf_emit(ctx, 0x3b, 0); +} + +static void +nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */ + xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */ + xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */ + if (device->chipset >= 0xa0) { + xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */ + xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */ + } + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + if (device->chipset == 0x50) + xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */ + else + xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + /* SEEK */ + xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */ + xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */ + xf_emit(ctx, 4, 0); /* 000000ff STRMOUT_ADDRESS_HIGH */ + xf_emit(ctx, 4, 0); /* ffffffff STRMOUT_ADDRESS_LOW */ + xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */ + if (device->chipset >= 0xa0) { + xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */ + xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */ + } + xf_emit(ctx, 1, 0); /* 0000ffff DMA_STRMOUT */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ + xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ + xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW QUERY_COUNTER */ + xf_emit(ctx, 2, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + /* SEEK */ + xf_emit(ctx, 0x20, 0); /* ffffffff STRMOUT_MAP */ + xf_emit(ctx, 1, 0); /* 0000000f */ + xf_emit(ctx, 1, 0); /* 00000000? */ + xf_emit(ctx, 2, 0); /* ffffffff */ +} + +static void +nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */ + xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ +} + +static void +nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + /* SEEK */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 2, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ + xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW, COUNTER */ + xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ + xf_emit(ctx, 1, 0); /* 7 */ + /* SEEK */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ + xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ + xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW, COUNTER */ + xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */ + xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */ + xf_emit(ctx, 1, 0); /* 00000001 eng2d UNK260 */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 0); /* 00000007 */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ +} + +static void +nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int magic2; + if (device->chipset == 0x50) { + magic2 = 0x00003e60; + } else if (!IS_NVA3F(device->chipset)) { + magic2 = 0x001ffe67; + } else { + magic2 = 0x00087e67; + } + xf_emit(ctx, 1, 0); /* f/7 MUTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + if (device->chipset >= 0xa0 && !IS_NVAAF(device->chipset)) + xf_emit(ctx, 1, 0x15); /* 000000ff */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ + xf_emit(ctx, 1, 0x10); /* 3ff/ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + if (device->chipset == 0x86 || device->chipset == 0x92 || device->chipset == 0x98 || device->chipset >= 0xa0) { + xf_emit(ctx, 3, 0); /* ff, ffffffff, ffffffff */ + xf_emit(ctx, 1, 4); /* 7 */ + xf_emit(ctx, 1, 0x400); /* fffffff */ + xf_emit(ctx, 1, 0x300); /* ffff */ + xf_emit(ctx, 1, 0x1001); /* 1fff */ + if (device->chipset != 0xa0) { + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 0); /* 0000000f UNK15C8 */ + else + xf_emit(ctx, 1, 0x15); /* ff */ + } + } + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ + xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ + xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000000f */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ + xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ + xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 0); /* 000000ff CLEAR_STENCIL */ + xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ + xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */ + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 2, 0); /* ffff0ff3, ffff */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ + xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ + if (device->chipset >= 0xa0) { + xf_emit(ctx, 2, 0); + xf_emit(ctx, 1, 0x1001); + xf_emit(ctx, 0xb, 0); + } else { + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + } + xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 1, 0x11); /* 3f/7f */ + xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ + if (device->chipset != 0x50) { + xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */ + xf_emit(ctx, 1, 0); /* 000000ff */ + } + xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ + xf_emit(ctx, 2, 1); /* 00000007 BLEND_EQUATION_RGB, ALPHA */ + xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK12E4 */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ + xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1140 */ + xf_emit(ctx, 2, 0); /* 00000001 */ + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, 0); /* 0000000f */ + xf_emit(ctx, 1, 0); /* 00000003 */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 2, 0); /* 00000001 */ + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + } else if (device->chipset >= 0xa0) { + xf_emit(ctx, 2, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0); /* 00000003 */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 2, 0); /* 00000001 */ + } else { + xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1430 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + } + xf_emit(ctx, 4, 0); /* ffffffff CLEAR_COLOR */ + xf_emit(ctx, 4, 0); /* ffffffff BLEND_COLOR A R G B */ + xf_emit(ctx, 1, 0); /* 00000fff eng2d UNK2B0 */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 2, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ + xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ + xf_emit(ctx, 1, 0); /* 00000001 UNK19C0 */ + xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 1, 0); /* 00000001 UNK12E4? NVA3+ only? */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK15C4 */ + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1140 */ + } + xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ + xf_emit(ctx, 1, 0); /* 00000007 PATTERN_COLOR_FORMAT */ + xf_emit(ctx, 2, 0); /* ffffffff PATTERN_MONO_COLOR */ + xf_emit(ctx, 1, 0); /* 00000001 PATTERN_MONO_FORMAT */ + xf_emit(ctx, 2, 0); /* ffffffff PATTERN_MONO_BITMAP */ + xf_emit(ctx, 1, 0); /* 00000003 PATTERN_SELECT */ + xf_emit(ctx, 1, 0); /* 000000ff ROP */ + xf_emit(ctx, 1, 0); /* ffffffff BETA1 */ + xf_emit(ctx, 1, 0); /* ffffffff BETA4 */ + xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ + xf_emit(ctx, 0x50, 0); /* 10x ffffff, ffffff, ffffff, ffffff, 3 PATTERN */ +} + +static void +nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int magic3; + switch (device->chipset) { + case 0x50: + magic3 = 0x1000; + break; + case 0x86: + case 0x98: + case 0xa8: + case 0xaa: + case 0xac: + case 0xaf: + magic3 = 0x1e00; + break; + default: + magic3 = 0; + } + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 7f/ff[NVA0+] VP_REG_ALLOC_RESULT */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 0); /* 111/113[NVA0+] */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 0x1f, 0); /* ffffffff */ + else if (device->chipset >= 0xa0) + xf_emit(ctx, 0x0f, 0); /* ffffffff */ + else + xf_emit(ctx, 0x10, 0); /* fffffff VP_RESULT_MAP_1 up */ + xf_emit(ctx, 2, 0); /* f/1f[NVA3], fffffff/ffffffff[NVA0+] */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 1, 0x03020100); /* ffffffff */ + else + xf_emit(ctx, 1, 0x00608080); /* fffffff VP_RESULT_MAP_0 */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 2, 0); /* 111/113, 7f/ff */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ + if (magic3) + xf_emit(ctx, 1, magic3); /* 00007fff tesla UNK141C */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 0); /* 111/113 */ + xf_emit(ctx, 0x1f, 0); /* ffffffff GP_RESULT_MAP_1 up */ + xf_emit(ctx, 1, 0); /* 0000001f */ + xf_emit(ctx, 1, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ + xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0x03020100); /* ffffffff GP_RESULT_MAP_0 */ + xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ + if (magic3) + xf_emit(ctx, 1, magic3); /* 7fff tesla UNK141C */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 0); /* 111/113 */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ + xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK13A0 */ + xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + xf_emit(ctx, 1, 0); /* 111/113 */ + if (device->chipset == 0x94 || device->chipset == 0x96) + xf_emit(ctx, 0x1020, 0); /* 4 x (0x400 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */ + else if (device->chipset < 0xa0) + xf_emit(ctx, 0xa20, 0); /* 4 x (0x280 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */ + else if (!IS_NVA3F(device->chipset)) + xf_emit(ctx, 0x210, 0); /* ffffffff */ + else + xf_emit(ctx, 0x410, 0); /* ffffffff */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ + xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ + xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ +} + +static void +nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int magic1, magic2; + if (device->chipset == 0x50) { + magic1 = 0x3ff; + magic2 = 0x00003e60; + } else if (!IS_NVA3F(device->chipset)) { + magic1 = 0x7ff; + magic2 = 0x001ffe67; + } else { + magic1 = 0x7ff; + magic2 = 0x00087e67; + } + xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* ffffffff ALPHA_TEST_REF */ + xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000000f UNK16A0 */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 4, 0); /* ffffffff BLEND_COLOR */ + xf_emit(ctx, 1, 0); /* 00000001 UNK19C0 */ + xf_emit(ctx, 1, 0); /* 00000001 UNK0FDC */ + xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ + xf_emit(ctx, 1, 0); /* ff[NV50]/3ff[NV84+] */ + xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ + xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ + xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ + xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ + xf_emit(ctx, 1, 0); /* 7 */ + xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff COLOR_KEY */ + xf_emit(ctx, 1, 0); /* 00000001 COLOR_KEY_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 COLOR_KEY_FORMAT */ + xf_emit(ctx, 2, 0); /* ffffffff SIFC_BITMAP_COLOR */ + xf_emit(ctx, 1, 1); /* 00000001 SIFC_BITMAP_WRITE_BIT0_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */ + xf_emit(ctx, 1, 0); /* 00000003 */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1298 */ + } else if (device->chipset >= 0xa0) { + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK16B4 */ + xf_emit(ctx, 1, 0); /* 00000003 */ + } else { + xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ + } + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ + xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_SRC_RGB */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_DST_RGB */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_SRC_ALPHA */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_DST_ALPHA */ + xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ + } + xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ + xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ + xf_emit(ctx, 1, 0); /* 7 */ + xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ + xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ + xf_emit(ctx, 1, 0xcf); /* 000000ff SIFC_FORMAT */ + xf_emit(ctx, 1, 0xcf); /* 000000ff DRAW_COLOR_FORMAT */ + xf_emit(ctx, 1, 0xcf); /* 000000ff SRC_FORMAT */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + xf_emit(ctx, 1, 0); /* 7/f[NVA3] MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ + xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 8, 1); /* 00000001 UNK19E0 */ + xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + if (device->chipset == 0x50) + xf_emit(ctx, 1, 0); /* ff */ + else + xf_emit(ctx, 3, 0); /* 1, 7, 3ff */ + xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ + xf_emit(ctx, 1, 0); /* 000fffff BLIT_DU_DX_FRACT */ + xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DU_DX_INT */ + xf_emit(ctx, 1, 0); /* 000fffff BLIT_DV_DY_FRACT */ + xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DV_DY_INT */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, magic1); /* 3ff/7ff tesla UNK0D68 */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 8, 0); /* 0000ffff DMA_COLOR */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_GLOBAL */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_LOCAL */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_STACK */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_DST */ + xf_emit(ctx, 1, 0); /* 7 */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 8, 0); /* 000000ff RT_ADDRESS_HIGH */ + xf_emit(ctx, 8, 0); /* ffffffff RT_LAYER_STRIDE */ + xf_emit(ctx, 8, 0); /* ffffffff RT_ADDRESS_LOW */ + xf_emit(ctx, 8, 8); /* 0000007f RT_TILE_MODE */ + xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 8, 0x400); /* 0fffffff RT_HORIZ */ + xf_emit(ctx, 8, 0x300); /* 0000ffff RT_VERT */ + xf_emit(ctx, 1, 1); /* 00001fff RT_ARRAY_MODE */ + xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 1, 0x20); /* 00000fff DST_TILE_MODE */ + xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ + xf_emit(ctx, 1, 0x100); /* 0001ffff DST_HEIGHT */ + xf_emit(ctx, 1, 0); /* 000007ff DST_LAYER */ + xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ + xf_emit(ctx, 1, 0); /* ffffffff DST_ADDRESS_LOW */ + xf_emit(ctx, 1, 0); /* 000000ff DST_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0x40); /* 0007ffff DST_PITCH */ + xf_emit(ctx, 1, 0x100); /* 0001ffff DST_WIDTH */ + xf_emit(ctx, 1, 0); /* 0000ffff */ + xf_emit(ctx, 1, 3); /* 00000003 tesla UNK15AC */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ + xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ + xf_emit(ctx, 1, 0); /* 00000007 */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_ZETA */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 2, 0); /* ffff, ff/3ff */ + xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0); /* ffffffff ZETA_LAYER_STRIDE */ + xf_emit(ctx, 1, 0); /* 000000ff ZETA_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff ZETA_ADDRESS_LOW */ + xf_emit(ctx, 1, 4); /* 00000007 ZETA_TILE_MODE */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + xf_emit(ctx, 1, 0x400); /* 0fffffff ZETA_HORIZ */ + xf_emit(ctx, 1, 0x300); /* 0000ffff ZETA_VERT */ + xf_emit(ctx, 1, 0x1001); /* 00001fff ZETA_ARRAY_MODE */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 0); /* 00000001 */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ + xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ + xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ + xf_emit(ctx, 1, 0); /* 7 */ + xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + } + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 1, 0x0fac6881); /* fffffff */ + xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ + xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ + xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ + xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, 0); /* 0000000f tesla UNK15C8 */ + } + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ + if (device->chipset >= 0xa0) { + xf_emit(ctx, 3, 0); /* 7/f, 1, ffff0ff3 */ + xf_emit(ctx, 1, 0xfac6881); /* fffffff */ + xf_emit(ctx, 4, 0); /* 1, 1, 1, 3ff */ + xf_emit(ctx, 1, 4); /* 7 */ + xf_emit(ctx, 1, 0); /* 1 */ + xf_emit(ctx, 2, 1); /* 1 */ + xf_emit(ctx, 2, 0); /* 7, f */ + xf_emit(ctx, 1, 1); /* 1 */ + xf_emit(ctx, 1, 0); /* 7/f */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 0x9, 0); /* 1 */ + else + xf_emit(ctx, 0x8, 0); /* 1 */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 8, 1); /* 1 */ + xf_emit(ctx, 1, 0x11); /* 7f */ + xf_emit(ctx, 7, 0); /* 7f */ + xf_emit(ctx, 1, 0xfac6881); /* fffffff */ + xf_emit(ctx, 1, 0xf); /* f */ + xf_emit(ctx, 7, 0); /* f */ + xf_emit(ctx, 1, 0x11); /* 7f */ + xf_emit(ctx, 1, 1); /* 1 */ + xf_emit(ctx, 5, 0); /* 1, 7, 3ff, 3, 7 */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + } + } +} + +static void +nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + xf_emit(ctx, 2, 0); /* 1 LINKED_TSC. yes, 2. */ + if (device->chipset != 0x50) + xf_emit(ctx, 1, 0); /* 3 */ + xf_emit(ctx, 1, 1); /* 1ffff BLIT_DU_DX_INT */ + xf_emit(ctx, 1, 0); /* fffff BLIT_DU_DX_FRACT */ + xf_emit(ctx, 1, 1); /* 1ffff BLIT_DV_DY_INT */ + xf_emit(ctx, 1, 0); /* fffff BLIT_DV_DY_FRACT */ + if (device->chipset == 0x50) + xf_emit(ctx, 1, 0); /* 3 BLIT_CONTROL */ + else + xf_emit(ctx, 2, 0); /* 3ff, 1 */ + xf_emit(ctx, 1, 0x2a712488); /* ffffffff SRC_TIC_0 */ + xf_emit(ctx, 1, 0); /* ffffffff SRC_TIC_1 */ + xf_emit(ctx, 1, 0x4085c000); /* ffffffff SRC_TIC_2 */ + xf_emit(ctx, 1, 0x40); /* ffffffff SRC_TIC_3 */ + xf_emit(ctx, 1, 0x100); /* ffffffff SRC_TIC_4 */ + xf_emit(ctx, 1, 0x10100); /* ffffffff SRC_TIC_5 */ + xf_emit(ctx, 1, 0x02800000); /* ffffffff SRC_TIC_6 */ + xf_emit(ctx, 1, 0); /* ffffffff SRC_TIC_7 */ + if (device->chipset == 0x50) { + xf_emit(ctx, 1, 0); /* 00000001 turing UNK358 */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */ + xf_emit(ctx, 1, 0); /* 00000003 turing UNK37C tesla UNK1690 */ + xf_emit(ctx, 1, 0); /* 00000003 BLIT_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000001 turing UNK32C tesla UNK0F94 */ + } else if (!IS_NVAAF(device->chipset)) { + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */ + xf_emit(ctx, 1, 0); /* 00000003 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + xf_emit(ctx, 1, 0); /* 00000003 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1664 / turing UNK03E8 */ + xf_emit(ctx, 1, 0); /* 00000003 */ + xf_emit(ctx, 1, 0); /* 000003ff */ + } else { + xf_emit(ctx, 0x6, 0); + } + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34 */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_TEXTURE */ + xf_emit(ctx, 1, 0); /* 0000ffff DMA_SRC */ +} + +static void +nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 2, 0); /* 7, ffff0ff3 */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE */ + xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0D64 */ + xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0DF4 */ + xf_emit(ctx, 1, 1); /* 00000001 UNK15B4 */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ + xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK0F98 */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1668 */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ + xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ + xf_emit(ctx, 1, 0); /* 00000001 POLYGON_SMOOTH_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1658 */ + xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ + xf_emit(ctx, 1, 0); /* ffff0ff3 */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE */ + xf_emit(ctx, 1, 1); /* 00000001 UNK15B4 */ + xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ + xf_emit(ctx, 1, 1); /* 00000001 tesla UNK165C */ + xf_emit(ctx, 1, 0x30201000); /* ffffffff tesla UNK1670 */ + xf_emit(ctx, 1, 0x70605040); /* ffffffff tesla UNK1670 */ + xf_emit(ctx, 1, 0xb8a89888); /* ffffffff tesla UNK1670 */ + xf_emit(ctx, 1, 0xf8e8d8c8); /* ffffffff tesla UNK1670 */ + xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ + xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ +} + +static void +nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + if (device->chipset < 0xa0) { + nv50_graph_construct_xfer_unk84xx(ctx); + nv50_graph_construct_xfer_tprop(ctx); + nv50_graph_construct_xfer_tex(ctx); + nv50_graph_construct_xfer_unk8cxx(ctx); + } else { + nv50_graph_construct_xfer_tex(ctx); + nv50_graph_construct_xfer_tprop(ctx); + nv50_graph_construct_xfer_unk8cxx(ctx); + nv50_graph_construct_xfer_unk84xx(ctx); + } +} + +static void +nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i, mpcnt = 2; + switch (device->chipset) { + case 0x98: + case 0xaa: + mpcnt = 1; + break; + case 0x50: + case 0x84: + case 0x86: + case 0x92: + case 0x94: + case 0x96: + case 0xa8: + case 0xac: + mpcnt = 2; + break; + case 0xa0: + case 0xa3: + case 0xa5: + case 0xaf: + mpcnt = 3; + break; + } + for (i = 0; i < mpcnt; i++) { + xf_emit(ctx, 1, 0); /* ff */ + xf_emit(ctx, 1, 0x80); /* ffffffff tesla UNK1404 */ + xf_emit(ctx, 1, 0x80007004); /* ffffffff tesla UNK12B0 */ + xf_emit(ctx, 1, 0x04000400); /* ffffffff */ + if (device->chipset >= 0xa0) + xf_emit(ctx, 1, 0xc0); /* 00007fff tesla UNK152C */ + xf_emit(ctx, 1, 0x1000); /* 0000ffff tesla UNK0D60 */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ + if (device->chipset == 0x86 || device->chipset == 0x98 || device->chipset == 0xa8 || IS_NVAAF(device->chipset)) { + xf_emit(ctx, 1, 0xe00); /* 7fff */ + xf_emit(ctx, 1, 0x1e00); /* 7fff */ + } + xf_emit(ctx, 1, 1); /* 000000ff VP_REG_ALLOC_TEMP */ + xf_emit(ctx, 1, 0); /* 00000001 LINKED_TSC */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + if (device->chipset == 0x50) + xf_emit(ctx, 2, 0x1000); /* 7fff tesla UNK141C */ + xf_emit(ctx, 1, 1); /* 000000ff GP_REG_ALLOC_TEMP */ + xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ + xf_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ + xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ + if (IS_NVAAF(device->chipset)) + xf_emit(ctx, 0xb, 0); /* RO */ + else if (device->chipset >= 0xa0) + xf_emit(ctx, 0xc, 0); /* RO */ + else + xf_emit(ctx, 0xa, 0); /* RO */ + } + xf_emit(ctx, 1, 0x08100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + if (device->chipset >= 0xa0) { + xf_emit(ctx, 1, 0x1fe21); /* 0003ffff tesla UNK0FAC */ + } + xf_emit(ctx, 3, 0); /* 7fff, 0, 0 */ + xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ + xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ + xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ + xf_emit(ctx, 1, 1); /* 00000001 LANES32 */ + xf_emit(ctx, 1, 0x10001); /* 00ffffff BLOCK_ALLOC */ + xf_emit(ctx, 1, 0x10001); /* ffffffff BLOCKDIM_XY */ + xf_emit(ctx, 1, 1); /* 0000ffff BLOCKDIM_Z */ + xf_emit(ctx, 1, 0); /* ffffffff SHARED_SIZE */ + xf_emit(ctx, 1, 0x1fe21); /* 1ffff/3ffff[NVA0+] tesla UNk0FAC */ + xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34 */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ + xf_emit(ctx, 1, 0); /* ff/3ff */ + xf_emit(ctx, 1, 0); /* 1 LINKED_TSC */ + xf_emit(ctx, 1, 0); /* ff FP_ADDRESS_HIGH */ + xf_emit(ctx, 1, 0); /* ffffffff FP_ADDRESS_LOW */ + xf_emit(ctx, 1, 0x08100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ + xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ + xf_emit(ctx, 1, 0); /* 000000ff FRAG_COLOR_CLAMP_EN */ + xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ + xf_emit(ctx, 1, 0x11); /* 0000007f RT_FORMAT */ + xf_emit(ctx, 7, 0); /* 0000007f RT_FORMAT */ + xf_emit(ctx, 1, 0); /* 00000007 */ + xf_emit(ctx, 1, 0xfac6881); /* 0fffffff RT_CONTROL */ + xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ + if (IS_NVA3F(device->chipset)) + xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */ + xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ + xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ + xf_emit(ctx, 1, 4); /* ffffffff tesla UNK1400 */ + xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ + xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ + xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ + xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ + if (IS_NVA3F(device->chipset)) { + xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ + xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ + xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ + xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ + xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1928 */ + xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ + } + xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */ + xf_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */ + /* XXX: demagic this part some day */ + if (device->chipset == 0x50) + xf_emit(ctx, 0x3a0, 0); + else if (device->chipset < 0x94) + xf_emit(ctx, 0x3a2, 0); + else if (device->chipset == 0x98 || device->chipset == 0xaa) + xf_emit(ctx, 0x39f, 0); + else + xf_emit(ctx, 0x3a3, 0); + xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ + xf_emit(ctx, 1, 0); /* 7 OPERATION */ + xf_emit(ctx, 1, 1); /* 1 DST_LINEAR */ + xf_emit(ctx, 0x2d, 0); +} + +static void +nv50_graph_construct_xfer2(struct nouveau_grctx *ctx) +{ + struct nouveau_device *device = ctx->device; + int i; + u32 offset; + u32 units = nv_rd32 (ctx->device, 0x1540); + int size = 0; + + offset = (ctx->ctxvals_pos+0x3f)&~0x3f; + + if (device->chipset < 0xa0) { + for (i = 0; i < 8; i++) { + ctx->ctxvals_pos = offset + i; + /* that little bugger belongs to csched. No idea + * what it's doing here. */ + if (i == 0) + xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */ + if (units & (1 << i)) + nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + } + } else { + /* Strand 0: TPs 0, 1 */ + ctx->ctxvals_pos = offset; + /* that little bugger belongs to csched. No idea + * what it's doing here. */ + xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */ + if (units & (1 << 0)) + nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 1)) + nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 1: TPs 2, 3 */ + ctx->ctxvals_pos = offset + 1; + if (units & (1 << 2)) + nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 3)) + nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 2: TPs 4, 5, 6 */ + ctx->ctxvals_pos = offset + 2; + if (units & (1 << 4)) + nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 5)) + nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 6)) + nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + + /* Strand 3: TPs 7, 8, 9 */ + ctx->ctxvals_pos = offset + 3; + if (units & (1 << 7)) + nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 8)) + nv50_graph_construct_xfer_mpc(ctx); + if (units & (1 << 9)) + nv50_graph_construct_xfer_mpc(ctx); + if ((ctx->ctxvals_pos-offset)/8 > size) + size = (ctx->ctxvals_pos-offset)/8; + } + ctx->ctxvals_pos = offset + size * 8; + ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f; + cp_lsr (ctx, offset); + cp_out (ctx, CP_SET_XFER_POINTER); + cp_lsr (ctx, size); + cp_out (ctx, CP_SEEK_2); + cp_out (ctx, CP_XFER_2); + cp_wait(ctx, XFER, BUSY); +} diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c new file mode 100644 index 00000000000..0b7951a8594 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c @@ -0,0 +1,3039 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nvc0.h" + +void +nv_icmd(struct nvc0_graph_priv *priv, u32 icmd, u32 data) +{ + nv_wr32(priv, 0x400204, data); + nv_wr32(priv, 0x400200, icmd); + while (nv_rd32(priv, 0x400700) & 2) {} +} + +int +nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) +{ + struct nouveau_bar *bar = nouveau_bar(priv); + struct nouveau_object *parent = nv_object(priv); + struct nouveau_gpuobj *chan; + u32 size = (0x80000 + priv->size + 4095) & ~4095; + int ret, i; + + /* allocate memory to for a "channel", which we'll use to generate + * the default context values + */ + ret = nouveau_gpuobj_new(parent, NULL, size, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC, &info->chan); + chan = info->chan; + if (ret) { + nv_error(priv, "failed to allocate channel memory, %d\n", ret); + return ret; + } + + /* PGD pointer */ + nv_wo32(chan, 0x0200, lower_32_bits(chan->addr + 0x1000)); + nv_wo32(chan, 0x0204, upper_32_bits(chan->addr + 0x1000)); + nv_wo32(chan, 0x0208, 0xffffffff); + nv_wo32(chan, 0x020c, 0x000000ff); + + /* PGT[0] pointer */ + nv_wo32(chan, 0x1000, 0x00000000); + nv_wo32(chan, 0x1004, 0x00000001 | (chan->addr + 0x2000) >> 8); + + /* identity-map the whole "channel" into its own vm */ + for (i = 0; i < size / 4096; i++) { + u64 addr = ((chan->addr + (i * 4096)) >> 8) | 1; + nv_wo32(chan, 0x2000 + (i * 8), lower_32_bits(addr)); + nv_wo32(chan, 0x2004 + (i * 8), upper_32_bits(addr)); + } + + /* context pointer (virt) */ + nv_wo32(chan, 0x0210, 0x00080004); + nv_wo32(chan, 0x0214, 0x00000000); + + bar->flush(bar); + + nv_wr32(priv, 0x100cb8, (chan->addr + 0x1000) >> 8); + nv_wr32(priv, 0x100cbc, 0x80000001); + nv_wait(priv, 0x100c80, 0x00008000, 0x00008000); + + /* setup default state for mmio list construction */ + info->data = priv->mmio_data; + info->mmio = priv->mmio_list; + info->addr = 0x2000 + (i * 8); + info->priv = priv; + info->buffer_nr = 0; + + if (priv->firmware) { + nv_wr32(priv, 0x409840, 0x00000030); + nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12); + nv_wr32(priv, 0x409504, 0x00000003); + if (!nv_wait(priv, 0x409800, 0x00000010, 0x00000010)) + nv_error(priv, "load_ctx timeout\n"); + + nv_wo32(chan, 0x8001c, 1); + nv_wo32(chan, 0x80020, 0); + nv_wo32(chan, 0x80028, 0); + nv_wo32(chan, 0x8002c, 0); + bar->flush(bar); + return 0; + } + + /* HUB_FUC(SET_CHAN) */ + nv_wr32(priv, 0x409840, 0x80000000); + nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12); + nv_wr32(priv, 0x409504, 0x00000001); + if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) { + nv_error(priv, "HUB_SET_CHAN timeout\n"); + nvc0_graph_ctxctl_debug(priv); + nouveau_gpuobj_ref(NULL, &info->chan); + return -EBUSY; + } + + return 0; +} + +void +nvc0_grctx_data(struct nvc0_grctx *info, u32 size, u32 align, u32 access) +{ + info->buffer[info->buffer_nr] = info->addr; + info->buffer[info->buffer_nr] += (align - 1); + info->buffer[info->buffer_nr] &= ~(align - 1); + info->addr = info->buffer[info->buffer_nr++] + size; + + info->data->size = size; + info->data->align = align; + info->data->access = access; + info->data++; +} + +void +nvc0_grctx_mmio(struct nvc0_grctx *info, u32 addr, u32 data, u32 shift, u32 buf) +{ + struct nvc0_graph_priv *priv = info->priv; + + info->mmio->addr = addr; + info->mmio->data = data; + info->mmio->shift = shift; + info->mmio->buffer = buf; + info->mmio++; + + if (shift) + data |= info->buffer[buf] >> shift; + nv_wr32(priv, addr, data); +} + +int +nvc0_grctx_fini(struct nvc0_grctx *info) +{ + struct nvc0_graph_priv *priv = info->priv; + int i; + + /* trigger a context unload by unsetting the "next channel valid" bit + * and faking a context switch interrupt + */ + nv_mask(priv, 0x409b04, 0x80000000, 0x00000000); + nv_wr32(priv, 0x409000, 0x00000100); + if (!nv_wait(priv, 0x409b00, 0x80000000, 0x00000000)) { + nv_error(priv, "grctx template channel unload timeout\n"); + return -EBUSY; + } + + priv->data = kmalloc(priv->size, GFP_KERNEL); + if (priv->data) { + for (i = 0; i < priv->size; i += 4) + priv->data[i / 4] = nv_ro32(info->chan, 0x80000 + i); + } + + nouveau_gpuobj_ref(NULL, &info->chan); + return priv->data ? 0 : -ENOMEM; +} + +static void +nvc0_grctx_generate_9097(struct nvc0_graph_priv *priv) +{ + u32 fermi = nvc0_graph_class(priv); + u32 mthd; + + nv_mthd(priv, 0x9097, 0x0800, 0x00000000); + nv_mthd(priv, 0x9097, 0x0840, 0x00000000); + nv_mthd(priv, 0x9097, 0x0880, 0x00000000); + nv_mthd(priv, 0x9097, 0x08c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0900, 0x00000000); + nv_mthd(priv, 0x9097, 0x0940, 0x00000000); + nv_mthd(priv, 0x9097, 0x0980, 0x00000000); + nv_mthd(priv, 0x9097, 0x09c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0804, 0x00000000); + nv_mthd(priv, 0x9097, 0x0844, 0x00000000); + nv_mthd(priv, 0x9097, 0x0884, 0x00000000); + nv_mthd(priv, 0x9097, 0x08c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0904, 0x00000000); + nv_mthd(priv, 0x9097, 0x0944, 0x00000000); + nv_mthd(priv, 0x9097, 0x0984, 0x00000000); + nv_mthd(priv, 0x9097, 0x09c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0808, 0x00000400); + nv_mthd(priv, 0x9097, 0x0848, 0x00000400); + nv_mthd(priv, 0x9097, 0x0888, 0x00000400); + nv_mthd(priv, 0x9097, 0x08c8, 0x00000400); + nv_mthd(priv, 0x9097, 0x0908, 0x00000400); + nv_mthd(priv, 0x9097, 0x0948, 0x00000400); + nv_mthd(priv, 0x9097, 0x0988, 0x00000400); + nv_mthd(priv, 0x9097, 0x09c8, 0x00000400); + nv_mthd(priv, 0x9097, 0x080c, 0x00000300); + nv_mthd(priv, 0x9097, 0x084c, 0x00000300); + nv_mthd(priv, 0x9097, 0x088c, 0x00000300); + nv_mthd(priv, 0x9097, 0x08cc, 0x00000300); + nv_mthd(priv, 0x9097, 0x090c, 0x00000300); + nv_mthd(priv, 0x9097, 0x094c, 0x00000300); + nv_mthd(priv, 0x9097, 0x098c, 0x00000300); + nv_mthd(priv, 0x9097, 0x09cc, 0x00000300); + nv_mthd(priv, 0x9097, 0x0810, 0x000000cf); + nv_mthd(priv, 0x9097, 0x0850, 0x00000000); + nv_mthd(priv, 0x9097, 0x0890, 0x00000000); + nv_mthd(priv, 0x9097, 0x08d0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0910, 0x00000000); + nv_mthd(priv, 0x9097, 0x0950, 0x00000000); + nv_mthd(priv, 0x9097, 0x0990, 0x00000000); + nv_mthd(priv, 0x9097, 0x09d0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0814, 0x00000040); + nv_mthd(priv, 0x9097, 0x0854, 0x00000040); + nv_mthd(priv, 0x9097, 0x0894, 0x00000040); + nv_mthd(priv, 0x9097, 0x08d4, 0x00000040); + nv_mthd(priv, 0x9097, 0x0914, 0x00000040); + nv_mthd(priv, 0x9097, 0x0954, 0x00000040); + nv_mthd(priv, 0x9097, 0x0994, 0x00000040); + nv_mthd(priv, 0x9097, 0x09d4, 0x00000040); + nv_mthd(priv, 0x9097, 0x0818, 0x00000001); + nv_mthd(priv, 0x9097, 0x0858, 0x00000001); + nv_mthd(priv, 0x9097, 0x0898, 0x00000001); + nv_mthd(priv, 0x9097, 0x08d8, 0x00000001); + nv_mthd(priv, 0x9097, 0x0918, 0x00000001); + nv_mthd(priv, 0x9097, 0x0958, 0x00000001); + nv_mthd(priv, 0x9097, 0x0998, 0x00000001); + nv_mthd(priv, 0x9097, 0x09d8, 0x00000001); + nv_mthd(priv, 0x9097, 0x081c, 0x00000000); + nv_mthd(priv, 0x9097, 0x085c, 0x00000000); + nv_mthd(priv, 0x9097, 0x089c, 0x00000000); + nv_mthd(priv, 0x9097, 0x08dc, 0x00000000); + nv_mthd(priv, 0x9097, 0x091c, 0x00000000); + nv_mthd(priv, 0x9097, 0x095c, 0x00000000); + nv_mthd(priv, 0x9097, 0x099c, 0x00000000); + nv_mthd(priv, 0x9097, 0x09dc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0820, 0x00000000); + nv_mthd(priv, 0x9097, 0x0860, 0x00000000); + nv_mthd(priv, 0x9097, 0x08a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x08e0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0920, 0x00000000); + nv_mthd(priv, 0x9097, 0x0960, 0x00000000); + nv_mthd(priv, 0x9097, 0x09a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x09e0, 0x00000000); + nv_mthd(priv, 0x9097, 0x2700, 0x00000000); + nv_mthd(priv, 0x9097, 0x2720, 0x00000000); + nv_mthd(priv, 0x9097, 0x2740, 0x00000000); + nv_mthd(priv, 0x9097, 0x2760, 0x00000000); + nv_mthd(priv, 0x9097, 0x2780, 0x00000000); + nv_mthd(priv, 0x9097, 0x27a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x27c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x27e0, 0x00000000); + nv_mthd(priv, 0x9097, 0x2704, 0x00000000); + nv_mthd(priv, 0x9097, 0x2724, 0x00000000); + nv_mthd(priv, 0x9097, 0x2744, 0x00000000); + nv_mthd(priv, 0x9097, 0x2764, 0x00000000); + nv_mthd(priv, 0x9097, 0x2784, 0x00000000); + nv_mthd(priv, 0x9097, 0x27a4, 0x00000000); + nv_mthd(priv, 0x9097, 0x27c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x27e4, 0x00000000); + nv_mthd(priv, 0x9097, 0x2708, 0x00000000); + nv_mthd(priv, 0x9097, 0x2728, 0x00000000); + nv_mthd(priv, 0x9097, 0x2748, 0x00000000); + nv_mthd(priv, 0x9097, 0x2768, 0x00000000); + nv_mthd(priv, 0x9097, 0x2788, 0x00000000); + nv_mthd(priv, 0x9097, 0x27a8, 0x00000000); + nv_mthd(priv, 0x9097, 0x27c8, 0x00000000); + nv_mthd(priv, 0x9097, 0x27e8, 0x00000000); + nv_mthd(priv, 0x9097, 0x270c, 0x00000000); + nv_mthd(priv, 0x9097, 0x272c, 0x00000000); + nv_mthd(priv, 0x9097, 0x274c, 0x00000000); + nv_mthd(priv, 0x9097, 0x276c, 0x00000000); + nv_mthd(priv, 0x9097, 0x278c, 0x00000000); + nv_mthd(priv, 0x9097, 0x27ac, 0x00000000); + nv_mthd(priv, 0x9097, 0x27cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x27ec, 0x00000000); + nv_mthd(priv, 0x9097, 0x2710, 0x00014000); + nv_mthd(priv, 0x9097, 0x2730, 0x00014000); + nv_mthd(priv, 0x9097, 0x2750, 0x00014000); + nv_mthd(priv, 0x9097, 0x2770, 0x00014000); + nv_mthd(priv, 0x9097, 0x2790, 0x00014000); + nv_mthd(priv, 0x9097, 0x27b0, 0x00014000); + nv_mthd(priv, 0x9097, 0x27d0, 0x00014000); + nv_mthd(priv, 0x9097, 0x27f0, 0x00014000); + nv_mthd(priv, 0x9097, 0x2714, 0x00000040); + nv_mthd(priv, 0x9097, 0x2734, 0x00000040); + nv_mthd(priv, 0x9097, 0x2754, 0x00000040); + nv_mthd(priv, 0x9097, 0x2774, 0x00000040); + nv_mthd(priv, 0x9097, 0x2794, 0x00000040); + nv_mthd(priv, 0x9097, 0x27b4, 0x00000040); + nv_mthd(priv, 0x9097, 0x27d4, 0x00000040); + nv_mthd(priv, 0x9097, 0x27f4, 0x00000040); + nv_mthd(priv, 0x9097, 0x1c00, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c10, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c20, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c30, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c40, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c50, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c60, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c70, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c80, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c90, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ca0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cb0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cc0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cd0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ce0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cf0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c04, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c14, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c24, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c34, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c44, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c54, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c64, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c74, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c84, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c94, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ca4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cb4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cc4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cd4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ce4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cf4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c08, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c18, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c28, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c38, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c48, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c58, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c68, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c78, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c88, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c98, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ca8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cb8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cc8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cd8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ce8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cf8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c0c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c1c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c2c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c3c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c4c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c5c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c6c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c7c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c8c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1c9c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cac, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cbc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ccc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cdc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cec, 0x00000000); + nv_mthd(priv, 0x9097, 0x1cfc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d00, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d10, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d20, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d30, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d40, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d50, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d60, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d70, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d80, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d90, 0x00000000); + nv_mthd(priv, 0x9097, 0x1da0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1db0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dc0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dd0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1de0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1df0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d04, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d14, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d24, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d34, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d44, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d54, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d64, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d74, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d84, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d94, 0x00000000); + nv_mthd(priv, 0x9097, 0x1da4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1db4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dc4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dd4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1de4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1df4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d08, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d18, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d28, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d38, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d48, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d58, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d68, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d78, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d88, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d98, 0x00000000); + nv_mthd(priv, 0x9097, 0x1da8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1db8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dc8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dd8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1de8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1df8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d0c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d1c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d2c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d3c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d4c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d5c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d6c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d7c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d8c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1d9c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dac, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dbc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dcc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ddc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dec, 0x00000000); + nv_mthd(priv, 0x9097, 0x1dfc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f00, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f08, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f10, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f18, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f20, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f28, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f30, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f38, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f40, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f48, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f50, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f58, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f60, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f68, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f70, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f78, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f04, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f0c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f14, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f1c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f24, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f2c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f34, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f3c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f44, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f4c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f54, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f5c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f64, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f6c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f74, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f7c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f80, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f88, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f90, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f98, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fa0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fa8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fb0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fb8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fc0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fc8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fd0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fd8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fe0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fe8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ff0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ff8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f84, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f8c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f94, 0x00000000); + nv_mthd(priv, 0x9097, 0x1f9c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fa4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fac, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fb4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fbc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fc4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fcc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fd4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fdc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fe4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1fec, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ff4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1ffc, 0x00000000); + nv_mthd(priv, 0x9097, 0x2200, 0x00000022); + nv_mthd(priv, 0x9097, 0x2210, 0x00000022); + nv_mthd(priv, 0x9097, 0x2220, 0x00000022); + nv_mthd(priv, 0x9097, 0x2230, 0x00000022); + nv_mthd(priv, 0x9097, 0x2240, 0x00000022); + nv_mthd(priv, 0x9097, 0x2000, 0x00000000); + nv_mthd(priv, 0x9097, 0x2040, 0x00000011); + nv_mthd(priv, 0x9097, 0x2080, 0x00000020); + nv_mthd(priv, 0x9097, 0x20c0, 0x00000030); + nv_mthd(priv, 0x9097, 0x2100, 0x00000040); + nv_mthd(priv, 0x9097, 0x2140, 0x00000051); + nv_mthd(priv, 0x9097, 0x200c, 0x00000001); + nv_mthd(priv, 0x9097, 0x204c, 0x00000001); + nv_mthd(priv, 0x9097, 0x208c, 0x00000001); + nv_mthd(priv, 0x9097, 0x20cc, 0x00000001); + nv_mthd(priv, 0x9097, 0x210c, 0x00000001); + nv_mthd(priv, 0x9097, 0x214c, 0x00000001); + nv_mthd(priv, 0x9097, 0x2010, 0x00000000); + nv_mthd(priv, 0x9097, 0x2050, 0x00000000); + nv_mthd(priv, 0x9097, 0x2090, 0x00000001); + nv_mthd(priv, 0x9097, 0x20d0, 0x00000002); + nv_mthd(priv, 0x9097, 0x2110, 0x00000003); + nv_mthd(priv, 0x9097, 0x2150, 0x00000004); + nv_mthd(priv, 0x9097, 0x0380, 0x00000000); + nv_mthd(priv, 0x9097, 0x03a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x03c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x03e0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0384, 0x00000000); + nv_mthd(priv, 0x9097, 0x03a4, 0x00000000); + nv_mthd(priv, 0x9097, 0x03c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x03e4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0388, 0x00000000); + nv_mthd(priv, 0x9097, 0x03a8, 0x00000000); + nv_mthd(priv, 0x9097, 0x03c8, 0x00000000); + nv_mthd(priv, 0x9097, 0x03e8, 0x00000000); + nv_mthd(priv, 0x9097, 0x038c, 0x00000000); + nv_mthd(priv, 0x9097, 0x03ac, 0x00000000); + nv_mthd(priv, 0x9097, 0x03cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x03ec, 0x00000000); + nv_mthd(priv, 0x9097, 0x0700, 0x00000000); + nv_mthd(priv, 0x9097, 0x0710, 0x00000000); + nv_mthd(priv, 0x9097, 0x0720, 0x00000000); + nv_mthd(priv, 0x9097, 0x0730, 0x00000000); + nv_mthd(priv, 0x9097, 0x0704, 0x00000000); + nv_mthd(priv, 0x9097, 0x0714, 0x00000000); + nv_mthd(priv, 0x9097, 0x0724, 0x00000000); + nv_mthd(priv, 0x9097, 0x0734, 0x00000000); + nv_mthd(priv, 0x9097, 0x0708, 0x00000000); + nv_mthd(priv, 0x9097, 0x0718, 0x00000000); + nv_mthd(priv, 0x9097, 0x0728, 0x00000000); + nv_mthd(priv, 0x9097, 0x0738, 0x00000000); + nv_mthd(priv, 0x9097, 0x2800, 0x00000000); + nv_mthd(priv, 0x9097, 0x2804, 0x00000000); + nv_mthd(priv, 0x9097, 0x2808, 0x00000000); + nv_mthd(priv, 0x9097, 0x280c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2810, 0x00000000); + nv_mthd(priv, 0x9097, 0x2814, 0x00000000); + nv_mthd(priv, 0x9097, 0x2818, 0x00000000); + nv_mthd(priv, 0x9097, 0x281c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2820, 0x00000000); + nv_mthd(priv, 0x9097, 0x2824, 0x00000000); + nv_mthd(priv, 0x9097, 0x2828, 0x00000000); + nv_mthd(priv, 0x9097, 0x282c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2830, 0x00000000); + nv_mthd(priv, 0x9097, 0x2834, 0x00000000); + nv_mthd(priv, 0x9097, 0x2838, 0x00000000); + nv_mthd(priv, 0x9097, 0x283c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2840, 0x00000000); + nv_mthd(priv, 0x9097, 0x2844, 0x00000000); + nv_mthd(priv, 0x9097, 0x2848, 0x00000000); + nv_mthd(priv, 0x9097, 0x284c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2850, 0x00000000); + nv_mthd(priv, 0x9097, 0x2854, 0x00000000); + nv_mthd(priv, 0x9097, 0x2858, 0x00000000); + nv_mthd(priv, 0x9097, 0x285c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2860, 0x00000000); + nv_mthd(priv, 0x9097, 0x2864, 0x00000000); + nv_mthd(priv, 0x9097, 0x2868, 0x00000000); + nv_mthd(priv, 0x9097, 0x286c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2870, 0x00000000); + nv_mthd(priv, 0x9097, 0x2874, 0x00000000); + nv_mthd(priv, 0x9097, 0x2878, 0x00000000); + nv_mthd(priv, 0x9097, 0x287c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2880, 0x00000000); + nv_mthd(priv, 0x9097, 0x2884, 0x00000000); + nv_mthd(priv, 0x9097, 0x2888, 0x00000000); + nv_mthd(priv, 0x9097, 0x288c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2890, 0x00000000); + nv_mthd(priv, 0x9097, 0x2894, 0x00000000); + nv_mthd(priv, 0x9097, 0x2898, 0x00000000); + nv_mthd(priv, 0x9097, 0x289c, 0x00000000); + nv_mthd(priv, 0x9097, 0x28a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x28a4, 0x00000000); + nv_mthd(priv, 0x9097, 0x28a8, 0x00000000); + nv_mthd(priv, 0x9097, 0x28ac, 0x00000000); + nv_mthd(priv, 0x9097, 0x28b0, 0x00000000); + nv_mthd(priv, 0x9097, 0x28b4, 0x00000000); + nv_mthd(priv, 0x9097, 0x28b8, 0x00000000); + nv_mthd(priv, 0x9097, 0x28bc, 0x00000000); + nv_mthd(priv, 0x9097, 0x28c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x28c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x28c8, 0x00000000); + nv_mthd(priv, 0x9097, 0x28cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x28d0, 0x00000000); + nv_mthd(priv, 0x9097, 0x28d4, 0x00000000); + nv_mthd(priv, 0x9097, 0x28d8, 0x00000000); + nv_mthd(priv, 0x9097, 0x28dc, 0x00000000); + nv_mthd(priv, 0x9097, 0x28e0, 0x00000000); + nv_mthd(priv, 0x9097, 0x28e4, 0x00000000); + nv_mthd(priv, 0x9097, 0x28e8, 0x00000000); + nv_mthd(priv, 0x9097, 0x28ec, 0x00000000); + nv_mthd(priv, 0x9097, 0x28f0, 0x00000000); + nv_mthd(priv, 0x9097, 0x28f4, 0x00000000); + nv_mthd(priv, 0x9097, 0x28f8, 0x00000000); + nv_mthd(priv, 0x9097, 0x28fc, 0x00000000); + nv_mthd(priv, 0x9097, 0x2900, 0x00000000); + nv_mthd(priv, 0x9097, 0x2904, 0x00000000); + nv_mthd(priv, 0x9097, 0x2908, 0x00000000); + nv_mthd(priv, 0x9097, 0x290c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2910, 0x00000000); + nv_mthd(priv, 0x9097, 0x2914, 0x00000000); + nv_mthd(priv, 0x9097, 0x2918, 0x00000000); + nv_mthd(priv, 0x9097, 0x291c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2920, 0x00000000); + nv_mthd(priv, 0x9097, 0x2924, 0x00000000); + nv_mthd(priv, 0x9097, 0x2928, 0x00000000); + nv_mthd(priv, 0x9097, 0x292c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2930, 0x00000000); + nv_mthd(priv, 0x9097, 0x2934, 0x00000000); + nv_mthd(priv, 0x9097, 0x2938, 0x00000000); + nv_mthd(priv, 0x9097, 0x293c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2940, 0x00000000); + nv_mthd(priv, 0x9097, 0x2944, 0x00000000); + nv_mthd(priv, 0x9097, 0x2948, 0x00000000); + nv_mthd(priv, 0x9097, 0x294c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2950, 0x00000000); + nv_mthd(priv, 0x9097, 0x2954, 0x00000000); + nv_mthd(priv, 0x9097, 0x2958, 0x00000000); + nv_mthd(priv, 0x9097, 0x295c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2960, 0x00000000); + nv_mthd(priv, 0x9097, 0x2964, 0x00000000); + nv_mthd(priv, 0x9097, 0x2968, 0x00000000); + nv_mthd(priv, 0x9097, 0x296c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2970, 0x00000000); + nv_mthd(priv, 0x9097, 0x2974, 0x00000000); + nv_mthd(priv, 0x9097, 0x2978, 0x00000000); + nv_mthd(priv, 0x9097, 0x297c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2980, 0x00000000); + nv_mthd(priv, 0x9097, 0x2984, 0x00000000); + nv_mthd(priv, 0x9097, 0x2988, 0x00000000); + nv_mthd(priv, 0x9097, 0x298c, 0x00000000); + nv_mthd(priv, 0x9097, 0x2990, 0x00000000); + nv_mthd(priv, 0x9097, 0x2994, 0x00000000); + nv_mthd(priv, 0x9097, 0x2998, 0x00000000); + nv_mthd(priv, 0x9097, 0x299c, 0x00000000); + nv_mthd(priv, 0x9097, 0x29a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x29a4, 0x00000000); + nv_mthd(priv, 0x9097, 0x29a8, 0x00000000); + nv_mthd(priv, 0x9097, 0x29ac, 0x00000000); + nv_mthd(priv, 0x9097, 0x29b0, 0x00000000); + nv_mthd(priv, 0x9097, 0x29b4, 0x00000000); + nv_mthd(priv, 0x9097, 0x29b8, 0x00000000); + nv_mthd(priv, 0x9097, 0x29bc, 0x00000000); + nv_mthd(priv, 0x9097, 0x29c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x29c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x29c8, 0x00000000); + nv_mthd(priv, 0x9097, 0x29cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x29d0, 0x00000000); + nv_mthd(priv, 0x9097, 0x29d4, 0x00000000); + nv_mthd(priv, 0x9097, 0x29d8, 0x00000000); + nv_mthd(priv, 0x9097, 0x29dc, 0x00000000); + nv_mthd(priv, 0x9097, 0x29e0, 0x00000000); + nv_mthd(priv, 0x9097, 0x29e4, 0x00000000); + nv_mthd(priv, 0x9097, 0x29e8, 0x00000000); + nv_mthd(priv, 0x9097, 0x29ec, 0x00000000); + nv_mthd(priv, 0x9097, 0x29f0, 0x00000000); + nv_mthd(priv, 0x9097, 0x29f4, 0x00000000); + nv_mthd(priv, 0x9097, 0x29f8, 0x00000000); + nv_mthd(priv, 0x9097, 0x29fc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a00, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a20, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a40, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a60, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a80, 0x00000000); + nv_mthd(priv, 0x9097, 0x0aa0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ac0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ae0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b00, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b20, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b40, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b60, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b80, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ba0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bc0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0be0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a04, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a24, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a44, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a64, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a84, 0x00000000); + nv_mthd(priv, 0x9097, 0x0aa4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ac4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ae4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b04, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b24, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b44, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b64, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b84, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ba4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bc4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0be4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a08, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a28, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a48, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a68, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a88, 0x00000000); + nv_mthd(priv, 0x9097, 0x0aa8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ac8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ae8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b08, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b28, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b48, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b68, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b88, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ba8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bc8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0be8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a0c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a2c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a4c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a6c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a8c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0aac, 0x00000000); + nv_mthd(priv, 0x9097, 0x0acc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0aec, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b0c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b2c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b4c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b6c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b8c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bac, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bcc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bec, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a10, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a30, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a50, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a70, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a90, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ab0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ad0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0af0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b10, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b30, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b50, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b70, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b90, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bb0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bd0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bf0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a14, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a34, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a54, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a74, 0x00000000); + nv_mthd(priv, 0x9097, 0x0a94, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ab4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ad4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0af4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b14, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b34, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b54, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b74, 0x00000000); + nv_mthd(priv, 0x9097, 0x0b94, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bb4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bd4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0bf4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c00, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c10, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c20, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c30, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c40, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c50, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c60, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c70, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c80, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c90, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ca0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cb0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cc0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cd0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ce0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cf0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c04, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c14, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c24, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c34, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c44, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c54, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c64, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c74, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c84, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c94, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ca4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cb4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cc4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cd4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ce4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cf4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c08, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c18, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c28, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c38, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c48, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c58, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c68, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c78, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c88, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c98, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ca8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cb8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cc8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cd8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ce8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0cf8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0c0c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c1c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c2c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c3c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c4c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c5c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c6c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c7c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c8c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0c9c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0cac, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0cbc, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0ccc, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0cdc, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0cec, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0cfc, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0d00, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d08, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d10, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d18, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d20, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d28, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d30, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d38, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d04, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d0c, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d14, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d1c, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d24, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d2c, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d34, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d3c, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e00, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e10, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e20, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e30, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e40, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e50, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e60, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e70, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e80, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e90, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ea0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0eb0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ec0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ed0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ee0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ef0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0e04, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e14, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e24, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e34, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e44, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e54, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e64, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e74, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e84, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e94, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ea4, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0eb4, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ec4, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ed4, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ee4, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ef4, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e08, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e18, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e28, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e38, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e48, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e58, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e68, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e78, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e88, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0e98, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ea8, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0eb8, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ec8, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ed8, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ee8, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0ef8, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d40, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d48, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d50, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d58, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d44, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d4c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d54, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d5c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1e00, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e20, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e40, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e60, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e80, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ea0, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ec0, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ee0, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e04, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e24, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e44, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e64, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e84, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ea4, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ec4, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ee4, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e08, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e28, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e48, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e68, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e88, 0x00000002); + nv_mthd(priv, 0x9097, 0x1ea8, 0x00000002); + nv_mthd(priv, 0x9097, 0x1ec8, 0x00000002); + nv_mthd(priv, 0x9097, 0x1ee8, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e0c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e2c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e4c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e6c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e8c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1eac, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ecc, 0x00000001); + nv_mthd(priv, 0x9097, 0x1eec, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e10, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e30, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e50, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e70, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e90, 0x00000001); + nv_mthd(priv, 0x9097, 0x1eb0, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ed0, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ef0, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e14, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e34, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e54, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e74, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e94, 0x00000002); + nv_mthd(priv, 0x9097, 0x1eb4, 0x00000002); + nv_mthd(priv, 0x9097, 0x1ed4, 0x00000002); + nv_mthd(priv, 0x9097, 0x1ef4, 0x00000002); + nv_mthd(priv, 0x9097, 0x1e18, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e38, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e58, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e78, 0x00000001); + nv_mthd(priv, 0x9097, 0x1e98, 0x00000001); + nv_mthd(priv, 0x9097, 0x1eb8, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ed8, 0x00000001); + nv_mthd(priv, 0x9097, 0x1ef8, 0x00000001); + if (fermi == 0x9097) { + for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4) + nv_mthd(priv, 0x9097, mthd, 0x00000000); + } + nv_mthd(priv, 0x9097, 0x030c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1944, 0x00000000); + nv_mthd(priv, 0x9097, 0x1514, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d68, 0x0000ffff); + nv_mthd(priv, 0x9097, 0x121c, 0x0fac6881); + nv_mthd(priv, 0x9097, 0x0fac, 0x00000001); + nv_mthd(priv, 0x9097, 0x1538, 0x00000001); + nv_mthd(priv, 0x9097, 0x0fe0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0fe4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0fe8, 0x00000014); + nv_mthd(priv, 0x9097, 0x0fec, 0x00000040); + nv_mthd(priv, 0x9097, 0x0ff0, 0x00000000); + nv_mthd(priv, 0x9097, 0x179c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1228, 0x00000400); + nv_mthd(priv, 0x9097, 0x122c, 0x00000300); + nv_mthd(priv, 0x9097, 0x1230, 0x00010001); + nv_mthd(priv, 0x9097, 0x07f8, 0x00000000); + nv_mthd(priv, 0x9097, 0x15b4, 0x00000001); + nv_mthd(priv, 0x9097, 0x15cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1534, 0x00000000); + nv_mthd(priv, 0x9097, 0x0fb0, 0x00000000); + nv_mthd(priv, 0x9097, 0x15d0, 0x00000000); + nv_mthd(priv, 0x9097, 0x153c, 0x00000000); + nv_mthd(priv, 0x9097, 0x16b4, 0x00000003); + nv_mthd(priv, 0x9097, 0x0fbc, 0x0000ffff); + nv_mthd(priv, 0x9097, 0x0fc0, 0x0000ffff); + nv_mthd(priv, 0x9097, 0x0fc4, 0x0000ffff); + nv_mthd(priv, 0x9097, 0x0fc8, 0x0000ffff); + nv_mthd(priv, 0x9097, 0x0df8, 0x00000000); + nv_mthd(priv, 0x9097, 0x0dfc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1948, 0x00000000); + nv_mthd(priv, 0x9097, 0x1970, 0x00000001); + nv_mthd(priv, 0x9097, 0x161c, 0x000009f0); + nv_mthd(priv, 0x9097, 0x0dcc, 0x00000010); + nv_mthd(priv, 0x9097, 0x163c, 0x00000000); + nv_mthd(priv, 0x9097, 0x15e4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1160, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1164, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1168, 0x25e00040); + nv_mthd(priv, 0x9097, 0x116c, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1170, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1174, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1178, 0x25e00040); + nv_mthd(priv, 0x9097, 0x117c, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1180, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1184, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1188, 0x25e00040); + nv_mthd(priv, 0x9097, 0x118c, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1190, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1194, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1198, 0x25e00040); + nv_mthd(priv, 0x9097, 0x119c, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11a0, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11a4, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11a8, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11ac, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11b0, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11b4, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11b8, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11bc, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11c0, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11c4, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11c8, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11cc, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11d0, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11d4, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11d8, 0x25e00040); + nv_mthd(priv, 0x9097, 0x11dc, 0x25e00040); + nv_mthd(priv, 0x9097, 0x1880, 0x00000000); + nv_mthd(priv, 0x9097, 0x1884, 0x00000000); + nv_mthd(priv, 0x9097, 0x1888, 0x00000000); + nv_mthd(priv, 0x9097, 0x188c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1890, 0x00000000); + nv_mthd(priv, 0x9097, 0x1894, 0x00000000); + nv_mthd(priv, 0x9097, 0x1898, 0x00000000); + nv_mthd(priv, 0x9097, 0x189c, 0x00000000); + nv_mthd(priv, 0x9097, 0x18a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x18a4, 0x00000000); + nv_mthd(priv, 0x9097, 0x18a8, 0x00000000); + nv_mthd(priv, 0x9097, 0x18ac, 0x00000000); + nv_mthd(priv, 0x9097, 0x18b0, 0x00000000); + nv_mthd(priv, 0x9097, 0x18b4, 0x00000000); + nv_mthd(priv, 0x9097, 0x18b8, 0x00000000); + nv_mthd(priv, 0x9097, 0x18bc, 0x00000000); + nv_mthd(priv, 0x9097, 0x18c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x18c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x18c8, 0x00000000); + nv_mthd(priv, 0x9097, 0x18cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x18d0, 0x00000000); + nv_mthd(priv, 0x9097, 0x18d4, 0x00000000); + nv_mthd(priv, 0x9097, 0x18d8, 0x00000000); + nv_mthd(priv, 0x9097, 0x18dc, 0x00000000); + nv_mthd(priv, 0x9097, 0x18e0, 0x00000000); + nv_mthd(priv, 0x9097, 0x18e4, 0x00000000); + nv_mthd(priv, 0x9097, 0x18e8, 0x00000000); + nv_mthd(priv, 0x9097, 0x18ec, 0x00000000); + nv_mthd(priv, 0x9097, 0x18f0, 0x00000000); + nv_mthd(priv, 0x9097, 0x18f4, 0x00000000); + nv_mthd(priv, 0x9097, 0x18f8, 0x00000000); + nv_mthd(priv, 0x9097, 0x18fc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f84, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f88, 0x00000000); + nv_mthd(priv, 0x9097, 0x17c8, 0x00000000); + nv_mthd(priv, 0x9097, 0x17cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x17d0, 0x000000ff); + nv_mthd(priv, 0x9097, 0x17d4, 0xffffffff); + nv_mthd(priv, 0x9097, 0x17d8, 0x00000002); + nv_mthd(priv, 0x9097, 0x17dc, 0x00000000); + nv_mthd(priv, 0x9097, 0x15f4, 0x00000000); + nv_mthd(priv, 0x9097, 0x15f8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1434, 0x00000000); + nv_mthd(priv, 0x9097, 0x1438, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d74, 0x00000000); + nv_mthd(priv, 0x9097, 0x0dec, 0x00000001); + nv_mthd(priv, 0x9097, 0x13a4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1318, 0x00000001); + nv_mthd(priv, 0x9097, 0x1644, 0x00000000); + nv_mthd(priv, 0x9097, 0x0748, 0x00000000); + nv_mthd(priv, 0x9097, 0x0de8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1648, 0x00000000); + nv_mthd(priv, 0x9097, 0x12a4, 0x00000000); + nv_mthd(priv, 0x9097, 0x1120, 0x00000000); + nv_mthd(priv, 0x9097, 0x1124, 0x00000000); + nv_mthd(priv, 0x9097, 0x1128, 0x00000000); + nv_mthd(priv, 0x9097, 0x112c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1118, 0x00000000); + nv_mthd(priv, 0x9097, 0x164c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1658, 0x00000000); + nv_mthd(priv, 0x9097, 0x1910, 0x00000290); + nv_mthd(priv, 0x9097, 0x1518, 0x00000000); + nv_mthd(priv, 0x9097, 0x165c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1520, 0x00000000); + nv_mthd(priv, 0x9097, 0x1604, 0x00000000); + nv_mthd(priv, 0x9097, 0x1570, 0x00000000); + nv_mthd(priv, 0x9097, 0x13b0, 0x3f800000); + nv_mthd(priv, 0x9097, 0x13b4, 0x3f800000); + nv_mthd(priv, 0x9097, 0x020c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1670, 0x30201000); + nv_mthd(priv, 0x9097, 0x1674, 0x70605040); + nv_mthd(priv, 0x9097, 0x1678, 0xb8a89888); + nv_mthd(priv, 0x9097, 0x167c, 0xf8e8d8c8); + nv_mthd(priv, 0x9097, 0x166c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1680, 0x00ffff00); + nv_mthd(priv, 0x9097, 0x12d0, 0x00000003); + nv_mthd(priv, 0x9097, 0x12d4, 0x00000002); + nv_mthd(priv, 0x9097, 0x1684, 0x00000000); + nv_mthd(priv, 0x9097, 0x1688, 0x00000000); + nv_mthd(priv, 0x9097, 0x0dac, 0x00001b02); + nv_mthd(priv, 0x9097, 0x0db0, 0x00001b02); + nv_mthd(priv, 0x9097, 0x0db4, 0x00000000); + nv_mthd(priv, 0x9097, 0x168c, 0x00000000); + nv_mthd(priv, 0x9097, 0x15bc, 0x00000000); + nv_mthd(priv, 0x9097, 0x156c, 0x00000000); + nv_mthd(priv, 0x9097, 0x187c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1110, 0x00000001); + nv_mthd(priv, 0x9097, 0x0dc0, 0x00000000); + nv_mthd(priv, 0x9097, 0x0dc4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0dc8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1234, 0x00000000); + nv_mthd(priv, 0x9097, 0x1690, 0x00000000); + nv_mthd(priv, 0x9097, 0x12ac, 0x00000001); + nv_mthd(priv, 0x9097, 0x02c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0790, 0x00000000); + nv_mthd(priv, 0x9097, 0x0794, 0x00000000); + nv_mthd(priv, 0x9097, 0x0798, 0x00000000); + nv_mthd(priv, 0x9097, 0x079c, 0x00000000); + nv_mthd(priv, 0x9097, 0x07a0, 0x00000000); + nv_mthd(priv, 0x9097, 0x077c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1000, 0x00000010); + nv_mthd(priv, 0x9097, 0x10fc, 0x00000000); + nv_mthd(priv, 0x9097, 0x1290, 0x00000000); + nv_mthd(priv, 0x9097, 0x0218, 0x00000010); + nv_mthd(priv, 0x9097, 0x12d8, 0x00000000); + nv_mthd(priv, 0x9097, 0x12dc, 0x00000010); + nv_mthd(priv, 0x9097, 0x0d94, 0x00000001); + nv_mthd(priv, 0x9097, 0x155c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1560, 0x00000000); + nv_mthd(priv, 0x9097, 0x1564, 0x00001fff); + nv_mthd(priv, 0x9097, 0x1574, 0x00000000); + nv_mthd(priv, 0x9097, 0x1578, 0x00000000); + nv_mthd(priv, 0x9097, 0x157c, 0x003fffff); + nv_mthd(priv, 0x9097, 0x1354, 0x00000000); + nv_mthd(priv, 0x9097, 0x1664, 0x00000000); + nv_mthd(priv, 0x9097, 0x1610, 0x00000012); + nv_mthd(priv, 0x9097, 0x1608, 0x00000000); + nv_mthd(priv, 0x9097, 0x160c, 0x00000000); + nv_mthd(priv, 0x9097, 0x162c, 0x00000003); + nv_mthd(priv, 0x9097, 0x0210, 0x00000000); + nv_mthd(priv, 0x9097, 0x0320, 0x00000000); + nv_mthd(priv, 0x9097, 0x0324, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0328, 0x3f800000); + nv_mthd(priv, 0x9097, 0x032c, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0330, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0334, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0338, 0x3f800000); + nv_mthd(priv, 0x9097, 0x0750, 0x00000000); + nv_mthd(priv, 0x9097, 0x0760, 0x39291909); + nv_mthd(priv, 0x9097, 0x0764, 0x79695949); + nv_mthd(priv, 0x9097, 0x0768, 0xb9a99989); + nv_mthd(priv, 0x9097, 0x076c, 0xf9e9d9c9); + nv_mthd(priv, 0x9097, 0x0770, 0x30201000); + nv_mthd(priv, 0x9097, 0x0774, 0x70605040); + nv_mthd(priv, 0x9097, 0x0778, 0x00009080); + nv_mthd(priv, 0x9097, 0x0780, 0x39291909); + nv_mthd(priv, 0x9097, 0x0784, 0x79695949); + nv_mthd(priv, 0x9097, 0x0788, 0xb9a99989); + nv_mthd(priv, 0x9097, 0x078c, 0xf9e9d9c9); + nv_mthd(priv, 0x9097, 0x07d0, 0x30201000); + nv_mthd(priv, 0x9097, 0x07d4, 0x70605040); + nv_mthd(priv, 0x9097, 0x07d8, 0x00009080); + nv_mthd(priv, 0x9097, 0x037c, 0x00000001); + nv_mthd(priv, 0x9097, 0x0740, 0x00000000); + nv_mthd(priv, 0x9097, 0x0744, 0x00000000); + nv_mthd(priv, 0x9097, 0x2600, 0x00000000); + nv_mthd(priv, 0x9097, 0x1918, 0x00000000); + nv_mthd(priv, 0x9097, 0x191c, 0x00000900); + nv_mthd(priv, 0x9097, 0x1920, 0x00000405); + nv_mthd(priv, 0x9097, 0x1308, 0x00000001); + nv_mthd(priv, 0x9097, 0x1924, 0x00000000); + nv_mthd(priv, 0x9097, 0x13ac, 0x00000000); + nv_mthd(priv, 0x9097, 0x192c, 0x00000001); + nv_mthd(priv, 0x9097, 0x193c, 0x00002c1c); + nv_mthd(priv, 0x9097, 0x0d7c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f8c, 0x00000000); + nv_mthd(priv, 0x9097, 0x02c0, 0x00000001); + nv_mthd(priv, 0x9097, 0x1510, 0x00000000); + nv_mthd(priv, 0x9097, 0x1940, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ff4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0ff8, 0x00000000); + nv_mthd(priv, 0x9097, 0x194c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1950, 0x00000000); + nv_mthd(priv, 0x9097, 0x1968, 0x00000000); + nv_mthd(priv, 0x9097, 0x1590, 0x0000003f); + nv_mthd(priv, 0x9097, 0x07e8, 0x00000000); + nv_mthd(priv, 0x9097, 0x07ec, 0x00000000); + nv_mthd(priv, 0x9097, 0x07f0, 0x00000000); + nv_mthd(priv, 0x9097, 0x07f4, 0x00000000); + nv_mthd(priv, 0x9097, 0x196c, 0x00000011); + nv_mthd(priv, 0x9097, 0x197c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0fcc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0fd0, 0x00000000); + nv_mthd(priv, 0x9097, 0x02d8, 0x00000040); + nv_mthd(priv, 0x9097, 0x1980, 0x00000080); + nv_mthd(priv, 0x9097, 0x1504, 0x00000080); + nv_mthd(priv, 0x9097, 0x1984, 0x00000000); + nv_mthd(priv, 0x9097, 0x0300, 0x00000001); + nv_mthd(priv, 0x9097, 0x13a8, 0x00000000); + nv_mthd(priv, 0x9097, 0x12ec, 0x00000000); + nv_mthd(priv, 0x9097, 0x1310, 0x00000000); + nv_mthd(priv, 0x9097, 0x1314, 0x00000001); + nv_mthd(priv, 0x9097, 0x1380, 0x00000000); + nv_mthd(priv, 0x9097, 0x1384, 0x00000001); + nv_mthd(priv, 0x9097, 0x1388, 0x00000001); + nv_mthd(priv, 0x9097, 0x138c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1390, 0x00000001); + nv_mthd(priv, 0x9097, 0x1394, 0x00000000); + nv_mthd(priv, 0x9097, 0x139c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1398, 0x00000000); + nv_mthd(priv, 0x9097, 0x1594, 0x00000000); + nv_mthd(priv, 0x9097, 0x1598, 0x00000001); + nv_mthd(priv, 0x9097, 0x159c, 0x00000001); + nv_mthd(priv, 0x9097, 0x15a0, 0x00000001); + nv_mthd(priv, 0x9097, 0x15a4, 0x00000001); + nv_mthd(priv, 0x9097, 0x0f54, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f58, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f5c, 0x00000000); + nv_mthd(priv, 0x9097, 0x19bc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f9c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0fa0, 0x00000000); + nv_mthd(priv, 0x9097, 0x12cc, 0x00000000); + nv_mthd(priv, 0x9097, 0x12e8, 0x00000000); + nv_mthd(priv, 0x9097, 0x130c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1360, 0x00000000); + nv_mthd(priv, 0x9097, 0x1364, 0x00000000); + nv_mthd(priv, 0x9097, 0x1368, 0x00000000); + nv_mthd(priv, 0x9097, 0x136c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1370, 0x00000000); + nv_mthd(priv, 0x9097, 0x1374, 0x00000000); + nv_mthd(priv, 0x9097, 0x1378, 0x00000000); + nv_mthd(priv, 0x9097, 0x137c, 0x00000000); + nv_mthd(priv, 0x9097, 0x133c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1340, 0x00000001); + nv_mthd(priv, 0x9097, 0x1344, 0x00000002); + nv_mthd(priv, 0x9097, 0x1348, 0x00000001); + nv_mthd(priv, 0x9097, 0x134c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1350, 0x00000002); + nv_mthd(priv, 0x9097, 0x1358, 0x00000001); + nv_mthd(priv, 0x9097, 0x12e4, 0x00000000); + nv_mthd(priv, 0x9097, 0x131c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1320, 0x00000000); + nv_mthd(priv, 0x9097, 0x1324, 0x00000000); + nv_mthd(priv, 0x9097, 0x1328, 0x00000000); + nv_mthd(priv, 0x9097, 0x19c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1140, 0x00000000); + nv_mthd(priv, 0x9097, 0x19c4, 0x00000000); + nv_mthd(priv, 0x9097, 0x19c8, 0x00001500); + nv_mthd(priv, 0x9097, 0x135c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f90, 0x00000000); + nv_mthd(priv, 0x9097, 0x19e0, 0x00000001); + nv_mthd(priv, 0x9097, 0x19e4, 0x00000001); + nv_mthd(priv, 0x9097, 0x19e8, 0x00000001); + nv_mthd(priv, 0x9097, 0x19ec, 0x00000001); + nv_mthd(priv, 0x9097, 0x19f0, 0x00000001); + nv_mthd(priv, 0x9097, 0x19f4, 0x00000001); + nv_mthd(priv, 0x9097, 0x19f8, 0x00000001); + nv_mthd(priv, 0x9097, 0x19fc, 0x00000001); + nv_mthd(priv, 0x9097, 0x19cc, 0x00000001); + nv_mthd(priv, 0x9097, 0x15b8, 0x00000000); + nv_mthd(priv, 0x9097, 0x1a00, 0x00001111); + nv_mthd(priv, 0x9097, 0x1a04, 0x00000000); + nv_mthd(priv, 0x9097, 0x1a08, 0x00000000); + nv_mthd(priv, 0x9097, 0x1a0c, 0x00000000); + nv_mthd(priv, 0x9097, 0x1a10, 0x00000000); + nv_mthd(priv, 0x9097, 0x1a14, 0x00000000); + nv_mthd(priv, 0x9097, 0x1a18, 0x00000000); + nv_mthd(priv, 0x9097, 0x1a1c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d6c, 0xffff0000); + nv_mthd(priv, 0x9097, 0x0d70, 0xffff0000); + nv_mthd(priv, 0x9097, 0x10f8, 0x00001010); + nv_mthd(priv, 0x9097, 0x0d80, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d84, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d88, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d8c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0d90, 0x00000000); + nv_mthd(priv, 0x9097, 0x0da0, 0x00000000); + nv_mthd(priv, 0x9097, 0x1508, 0x80000000); + nv_mthd(priv, 0x9097, 0x150c, 0x40000000); + nv_mthd(priv, 0x9097, 0x1668, 0x00000000); + nv_mthd(priv, 0x9097, 0x0318, 0x00000008); + nv_mthd(priv, 0x9097, 0x031c, 0x00000008); + nv_mthd(priv, 0x9097, 0x0d9c, 0x00000001); + nv_mthd(priv, 0x9097, 0x07dc, 0x00000000); + nv_mthd(priv, 0x9097, 0x074c, 0x00000055); + nv_mthd(priv, 0x9097, 0x1420, 0x00000003); + nv_mthd(priv, 0x9097, 0x17bc, 0x00000000); + nv_mthd(priv, 0x9097, 0x17c0, 0x00000000); + nv_mthd(priv, 0x9097, 0x17c4, 0x00000001); + nv_mthd(priv, 0x9097, 0x1008, 0x00000008); + nv_mthd(priv, 0x9097, 0x100c, 0x00000040); + nv_mthd(priv, 0x9097, 0x1010, 0x0000012c); + nv_mthd(priv, 0x9097, 0x0d60, 0x00000040); + nv_mthd(priv, 0x9097, 0x075c, 0x00000003); + nv_mthd(priv, 0x9097, 0x1018, 0x00000020); + nv_mthd(priv, 0x9097, 0x101c, 0x00000001); + nv_mthd(priv, 0x9097, 0x1020, 0x00000020); + nv_mthd(priv, 0x9097, 0x1024, 0x00000001); + nv_mthd(priv, 0x9097, 0x1444, 0x00000000); + nv_mthd(priv, 0x9097, 0x1448, 0x00000000); + nv_mthd(priv, 0x9097, 0x144c, 0x00000000); + nv_mthd(priv, 0x9097, 0x0360, 0x20164010); + nv_mthd(priv, 0x9097, 0x0364, 0x00000020); + nv_mthd(priv, 0x9097, 0x0368, 0x00000000); + nv_mthd(priv, 0x9097, 0x0de4, 0x00000000); + nv_mthd(priv, 0x9097, 0x0204, 0x00000006); + nv_mthd(priv, 0x9097, 0x0208, 0x00000000); + nv_mthd(priv, 0x9097, 0x02cc, 0x003fffff); + nv_mthd(priv, 0x9097, 0x02d0, 0x00000c48); + nv_mthd(priv, 0x9097, 0x1220, 0x00000005); + nv_mthd(priv, 0x9097, 0x0fdc, 0x00000000); + nv_mthd(priv, 0x9097, 0x0f98, 0x00300008); + nv_mthd(priv, 0x9097, 0x1284, 0x04000080); + nv_mthd(priv, 0x9097, 0x1450, 0x00300008); + nv_mthd(priv, 0x9097, 0x1454, 0x04000080); + nv_mthd(priv, 0x9097, 0x0214, 0x00000000); + /* in trace, right after 0x90c0, not here */ + nv_mthd(priv, 0x9097, 0x3410, 0x80002006); +} + +static void +nvc0_grctx_generate_9197(struct nvc0_graph_priv *priv) +{ + u32 fermi = nvc0_graph_class(priv); + u32 mthd; + + if (fermi == 0x9197) { + for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4) + nv_mthd(priv, 0x9197, mthd, 0x00000000); + } + nv_mthd(priv, 0x9197, 0x02e4, 0x0000b001); +} + +static void +nvc0_grctx_generate_9297(struct nvc0_graph_priv *priv) +{ + u32 fermi = nvc0_graph_class(priv); + u32 mthd; + + if (fermi == 0x9297) { + for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4) + nv_mthd(priv, 0x9297, mthd, 0x00000000); + } + nv_mthd(priv, 0x9297, 0x036c, 0x00000000); + nv_mthd(priv, 0x9297, 0x0370, 0x00000000); + nv_mthd(priv, 0x9297, 0x07a4, 0x00000000); + nv_mthd(priv, 0x9297, 0x07a8, 0x00000000); + nv_mthd(priv, 0x9297, 0x0374, 0x00000000); + nv_mthd(priv, 0x9297, 0x0378, 0x00000020); +} + +static void +nvc0_grctx_generate_902d(struct nvc0_graph_priv *priv) +{ + nv_mthd(priv, 0x902d, 0x0200, 0x000000cf); + nv_mthd(priv, 0x902d, 0x0204, 0x00000001); + nv_mthd(priv, 0x902d, 0x0208, 0x00000020); + nv_mthd(priv, 0x902d, 0x020c, 0x00000001); + nv_mthd(priv, 0x902d, 0x0210, 0x00000000); + nv_mthd(priv, 0x902d, 0x0214, 0x00000080); + nv_mthd(priv, 0x902d, 0x0218, 0x00000100); + nv_mthd(priv, 0x902d, 0x021c, 0x00000100); + nv_mthd(priv, 0x902d, 0x0220, 0x00000000); + nv_mthd(priv, 0x902d, 0x0224, 0x00000000); + nv_mthd(priv, 0x902d, 0x0230, 0x000000cf); + nv_mthd(priv, 0x902d, 0x0234, 0x00000001); + nv_mthd(priv, 0x902d, 0x0238, 0x00000020); + nv_mthd(priv, 0x902d, 0x023c, 0x00000001); + nv_mthd(priv, 0x902d, 0x0244, 0x00000080); + nv_mthd(priv, 0x902d, 0x0248, 0x00000100); + nv_mthd(priv, 0x902d, 0x024c, 0x00000100); +} + +static void +nvc0_grctx_generate_9039(struct nvc0_graph_priv *priv) +{ + nv_mthd(priv, 0x9039, 0x030c, 0x00000000); + nv_mthd(priv, 0x9039, 0x0310, 0x00000000); + nv_mthd(priv, 0x9039, 0x0314, 0x00000000); + nv_mthd(priv, 0x9039, 0x0320, 0x00000000); + nv_mthd(priv, 0x9039, 0x0238, 0x00000000); + nv_mthd(priv, 0x9039, 0x023c, 0x00000000); + nv_mthd(priv, 0x9039, 0x0318, 0x00000000); + nv_mthd(priv, 0x9039, 0x031c, 0x00000000); +} + +static void +nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv) +{ + int i; + + for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) { + nv_mthd(priv, 0x90c0, 0x2700 + (i * 0x40), 0x00000000); + nv_mthd(priv, 0x90c0, 0x2720 + (i * 0x40), 0x00000000); + nv_mthd(priv, 0x90c0, 0x2704 + (i * 0x40), 0x00000000); + nv_mthd(priv, 0x90c0, 0x2724 + (i * 0x40), 0x00000000); + nv_mthd(priv, 0x90c0, 0x2708 + (i * 0x40), 0x00000000); + nv_mthd(priv, 0x90c0, 0x2728 + (i * 0x40), 0x00000000); + } + nv_mthd(priv, 0x90c0, 0x270c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x272c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x274c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x276c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x278c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x27ac, 0x00000000); + nv_mthd(priv, 0x90c0, 0x27cc, 0x00000000); + nv_mthd(priv, 0x90c0, 0x27ec, 0x00000000); + for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) { + nv_mthd(priv, 0x90c0, 0x2710 + (i * 0x40), 0x00014000); + nv_mthd(priv, 0x90c0, 0x2730 + (i * 0x40), 0x00014000); + nv_mthd(priv, 0x90c0, 0x2714 + (i * 0x40), 0x00000040); + nv_mthd(priv, 0x90c0, 0x2734 + (i * 0x40), 0x00000040); + } + nv_mthd(priv, 0x90c0, 0x030c, 0x00000001); + nv_mthd(priv, 0x90c0, 0x1944, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0758, 0x00000100); + nv_mthd(priv, 0x90c0, 0x02c4, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0790, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0794, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0798, 0x00000000); + nv_mthd(priv, 0x90c0, 0x079c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x07a0, 0x00000000); + nv_mthd(priv, 0x90c0, 0x077c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0204, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0208, 0x00000000); + nv_mthd(priv, 0x90c0, 0x020c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0214, 0x00000000); + nv_mthd(priv, 0x90c0, 0x024c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x0d94, 0x00000001); + nv_mthd(priv, 0x90c0, 0x1608, 0x00000000); + nv_mthd(priv, 0x90c0, 0x160c, 0x00000000); + nv_mthd(priv, 0x90c0, 0x1664, 0x00000000); +} + +static void +nvc0_grctx_generate_dispatch(struct nvc0_graph_priv *priv) +{ + int i; + + nv_wr32(priv, 0x404004, 0x00000000); + nv_wr32(priv, 0x404008, 0x00000000); + nv_wr32(priv, 0x40400c, 0x00000000); + nv_wr32(priv, 0x404010, 0x00000000); + nv_wr32(priv, 0x404014, 0x00000000); + nv_wr32(priv, 0x404018, 0x00000000); + nv_wr32(priv, 0x40401c, 0x00000000); + nv_wr32(priv, 0x404020, 0x00000000); + nv_wr32(priv, 0x404024, 0x00000000); + nv_wr32(priv, 0x404028, 0x00000000); + nv_wr32(priv, 0x40402c, 0x00000000); + nv_wr32(priv, 0x404044, 0x00000000); + nv_wr32(priv, 0x404094, 0x00000000); + nv_wr32(priv, 0x404098, 0x00000000); + nv_wr32(priv, 0x40409c, 0x00000000); + nv_wr32(priv, 0x4040a0, 0x00000000); + nv_wr32(priv, 0x4040a4, 0x00000000); + nv_wr32(priv, 0x4040a8, 0x00000000); + nv_wr32(priv, 0x4040ac, 0x00000000); + nv_wr32(priv, 0x4040b0, 0x00000000); + nv_wr32(priv, 0x4040b4, 0x00000000); + nv_wr32(priv, 0x4040b8, 0x00000000); + nv_wr32(priv, 0x4040bc, 0x00000000); + nv_wr32(priv, 0x4040c0, 0x00000000); + nv_wr32(priv, 0x4040c4, 0x00000000); + nv_wr32(priv, 0x4040c8, 0xf0000087); + nv_wr32(priv, 0x4040d4, 0x00000000); + nv_wr32(priv, 0x4040d8, 0x00000000); + nv_wr32(priv, 0x4040dc, 0x00000000); + nv_wr32(priv, 0x4040e0, 0x00000000); + nv_wr32(priv, 0x4040e4, 0x00000000); + nv_wr32(priv, 0x4040e8, 0x00001000); + nv_wr32(priv, 0x4040f8, 0x00000000); + nv_wr32(priv, 0x404130, 0x00000000); + nv_wr32(priv, 0x404134, 0x00000000); + nv_wr32(priv, 0x404138, 0x20000040); + nv_wr32(priv, 0x404150, 0x0000002e); + nv_wr32(priv, 0x404154, 0x00000400); + nv_wr32(priv, 0x404158, 0x00000200); + nv_wr32(priv, 0x404164, 0x00000055); + nv_wr32(priv, 0x404168, 0x00000000); + nv_wr32(priv, 0x404174, 0x00000000); + nv_wr32(priv, 0x404178, 0x00000000); + nv_wr32(priv, 0x40417c, 0x00000000); + for (i = 0; i < 8; i++) + nv_wr32(priv, 0x404200 + (i * 4), 0x00000000); /* subc */ +} + +static void +nvc0_grctx_generate_macro(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x404404, 0x00000000); + nv_wr32(priv, 0x404408, 0x00000000); + nv_wr32(priv, 0x40440c, 0x00000000); + nv_wr32(priv, 0x404410, 0x00000000); + nv_wr32(priv, 0x404414, 0x00000000); + nv_wr32(priv, 0x404418, 0x00000000); + nv_wr32(priv, 0x40441c, 0x00000000); + nv_wr32(priv, 0x404420, 0x00000000); + nv_wr32(priv, 0x404424, 0x00000000); + nv_wr32(priv, 0x404428, 0x00000000); + nv_wr32(priv, 0x40442c, 0x00000000); + nv_wr32(priv, 0x404430, 0x00000000); + nv_wr32(priv, 0x404434, 0x00000000); + nv_wr32(priv, 0x404438, 0x00000000); + nv_wr32(priv, 0x404460, 0x00000000); + nv_wr32(priv, 0x404464, 0x00000000); + nv_wr32(priv, 0x404468, 0x00ffffff); + nv_wr32(priv, 0x40446c, 0x00000000); + nv_wr32(priv, 0x404480, 0x00000001); + nv_wr32(priv, 0x404498, 0x00000001); +} + +static void +nvc0_grctx_generate_m2mf(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x404604, 0x00000015); + nv_wr32(priv, 0x404608, 0x00000000); + nv_wr32(priv, 0x40460c, 0x00002e00); + nv_wr32(priv, 0x404610, 0x00000100); + nv_wr32(priv, 0x404618, 0x00000000); + nv_wr32(priv, 0x40461c, 0x00000000); + nv_wr32(priv, 0x404620, 0x00000000); + nv_wr32(priv, 0x404624, 0x00000000); + nv_wr32(priv, 0x404628, 0x00000000); + nv_wr32(priv, 0x40462c, 0x00000000); + nv_wr32(priv, 0x404630, 0x00000000); + nv_wr32(priv, 0x404634, 0x00000000); + nv_wr32(priv, 0x404638, 0x00000004); + nv_wr32(priv, 0x40463c, 0x00000000); + nv_wr32(priv, 0x404640, 0x00000000); + nv_wr32(priv, 0x404644, 0x00000000); + nv_wr32(priv, 0x404648, 0x00000000); + nv_wr32(priv, 0x40464c, 0x00000000); + nv_wr32(priv, 0x404650, 0x00000000); + nv_wr32(priv, 0x404654, 0x00000000); + nv_wr32(priv, 0x404658, 0x00000000); + nv_wr32(priv, 0x40465c, 0x007f0100); + nv_wr32(priv, 0x404660, 0x00000000); + nv_wr32(priv, 0x404664, 0x00000000); + nv_wr32(priv, 0x404668, 0x00000000); + nv_wr32(priv, 0x40466c, 0x00000000); + nv_wr32(priv, 0x404670, 0x00000000); + nv_wr32(priv, 0x404674, 0x00000000); + nv_wr32(priv, 0x404678, 0x00000000); + nv_wr32(priv, 0x40467c, 0x00000002); + nv_wr32(priv, 0x404680, 0x00000000); + nv_wr32(priv, 0x404684, 0x00000000); + nv_wr32(priv, 0x404688, 0x00000000); + nv_wr32(priv, 0x40468c, 0x00000000); + nv_wr32(priv, 0x404690, 0x00000000); + nv_wr32(priv, 0x404694, 0x00000000); + nv_wr32(priv, 0x404698, 0x00000000); + nv_wr32(priv, 0x40469c, 0x00000000); + nv_wr32(priv, 0x4046a0, 0x007f0080); + nv_wr32(priv, 0x4046a4, 0x00000000); + nv_wr32(priv, 0x4046a8, 0x00000000); + nv_wr32(priv, 0x4046ac, 0x00000000); + nv_wr32(priv, 0x4046b0, 0x00000000); + nv_wr32(priv, 0x4046b4, 0x00000000); + nv_wr32(priv, 0x4046b8, 0x00000000); + nv_wr32(priv, 0x4046bc, 0x00000000); + nv_wr32(priv, 0x4046c0, 0x00000000); + nv_wr32(priv, 0x4046c4, 0x00000000); + nv_wr32(priv, 0x4046c8, 0x00000000); + nv_wr32(priv, 0x4046cc, 0x00000000); + nv_wr32(priv, 0x4046d0, 0x00000000); + nv_wr32(priv, 0x4046d4, 0x00000000); + nv_wr32(priv, 0x4046d8, 0x00000000); + nv_wr32(priv, 0x4046dc, 0x00000000); + nv_wr32(priv, 0x4046e0, 0x00000000); + nv_wr32(priv, 0x4046e4, 0x00000000); + nv_wr32(priv, 0x4046e8, 0x00000000); + nv_wr32(priv, 0x4046f0, 0x00000000); + nv_wr32(priv, 0x4046f4, 0x00000000); +} + +static void +nvc0_grctx_generate_unk47xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x404700, 0x00000000); + nv_wr32(priv, 0x404704, 0x00000000); + nv_wr32(priv, 0x404708, 0x00000000); + nv_wr32(priv, 0x40470c, 0x00000000); + nv_wr32(priv, 0x404710, 0x00000000); + nv_wr32(priv, 0x404714, 0x00000000); + nv_wr32(priv, 0x404718, 0x00000000); + nv_wr32(priv, 0x40471c, 0x00000000); + nv_wr32(priv, 0x404720, 0x00000000); + nv_wr32(priv, 0x404724, 0x00000000); + nv_wr32(priv, 0x404728, 0x00000000); + nv_wr32(priv, 0x40472c, 0x00000000); + nv_wr32(priv, 0x404730, 0x00000000); + nv_wr32(priv, 0x404734, 0x00000100); + nv_wr32(priv, 0x404738, 0x00000000); + nv_wr32(priv, 0x40473c, 0x00000000); + nv_wr32(priv, 0x404740, 0x00000000); + nv_wr32(priv, 0x404744, 0x00000000); + nv_wr32(priv, 0x404748, 0x00000000); + nv_wr32(priv, 0x40474c, 0x00000000); + nv_wr32(priv, 0x404750, 0x00000000); + nv_wr32(priv, 0x404754, 0x00000000); +} + +static void +nvc0_grctx_generate_shaders(struct nvc0_graph_priv *priv) +{ + + if (nv_device(priv)->chipset == 0xd9) { + nv_wr32(priv, 0x405800, 0x0f8000bf); + nv_wr32(priv, 0x405830, 0x02180218); + nv_wr32(priv, 0x405834, 0x08000000); + } else + if (nv_device(priv)->chipset == 0xc1) { + nv_wr32(priv, 0x405800, 0x0f8000bf); + nv_wr32(priv, 0x405830, 0x02180218); + nv_wr32(priv, 0x405834, 0x00000000); + } else { + nv_wr32(priv, 0x405800, 0x078000bf); + nv_wr32(priv, 0x405830, 0x02180000); + nv_wr32(priv, 0x405834, 0x00000000); + } + nv_wr32(priv, 0x405838, 0x00000000); + nv_wr32(priv, 0x405854, 0x00000000); + nv_wr32(priv, 0x405870, 0x00000001); + nv_wr32(priv, 0x405874, 0x00000001); + nv_wr32(priv, 0x405878, 0x00000001); + nv_wr32(priv, 0x40587c, 0x00000001); + nv_wr32(priv, 0x405a00, 0x00000000); + nv_wr32(priv, 0x405a04, 0x00000000); + nv_wr32(priv, 0x405a18, 0x00000000); +} + +static void +nvc0_grctx_generate_unk60xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x406020, 0x000103c1); + nv_wr32(priv, 0x406028, 0x00000001); + nv_wr32(priv, 0x40602c, 0x00000001); + nv_wr32(priv, 0x406030, 0x00000001); + nv_wr32(priv, 0x406034, 0x00000001); +} + +static void +nvc0_grctx_generate_unk64xx(struct nvc0_graph_priv *priv) +{ + + nv_wr32(priv, 0x4064a8, 0x00000000); + nv_wr32(priv, 0x4064ac, 0x00003fff); + nv_wr32(priv, 0x4064b4, 0x00000000); + nv_wr32(priv, 0x4064b8, 0x00000000); + if (nv_device(priv)->chipset == 0xd9) + nv_wr32(priv, 0x4064bc, 0x00000000); + if (nv_device(priv)->chipset == 0xc1 || + nv_device(priv)->chipset == 0xd9) { + nv_wr32(priv, 0x4064c0, 0x80140078); + nv_wr32(priv, 0x4064c4, 0x0086ffff); + } +} + +static void +nvc0_grctx_generate_tpbus(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x407804, 0x00000023); + nv_wr32(priv, 0x40780c, 0x0a418820); + nv_wr32(priv, 0x407810, 0x062080e6); + nv_wr32(priv, 0x407814, 0x020398a4); + nv_wr32(priv, 0x407818, 0x0e629062); + nv_wr32(priv, 0x40781c, 0x0a418820); + nv_wr32(priv, 0x407820, 0x000000e6); + nv_wr32(priv, 0x4078bc, 0x00000103); +} + +static void +nvc0_grctx_generate_ccache(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x408000, 0x00000000); + nv_wr32(priv, 0x408004, 0x00000000); + nv_wr32(priv, 0x408008, 0x00000018); + nv_wr32(priv, 0x40800c, 0x00000000); + nv_wr32(priv, 0x408010, 0x00000000); + nv_wr32(priv, 0x408014, 0x00000069); + nv_wr32(priv, 0x408018, 0xe100e100); + nv_wr32(priv, 0x408064, 0x00000000); +} + +static void +nvc0_grctx_generate_rop(struct nvc0_graph_priv *priv) +{ + int chipset = nv_device(priv)->chipset; + + /* ROPC_BROADCAST */ + nv_wr32(priv, 0x408800, 0x02802a3c); + nv_wr32(priv, 0x408804, 0x00000040); + if (chipset == 0xd9) { + nv_wr32(priv, 0x408808, 0x1043e005); + nv_wr32(priv, 0x408900, 0x3080b801); + nv_wr32(priv, 0x408904, 0x1043e005); + nv_wr32(priv, 0x408908, 0x00c8102f); + } else + if (chipset == 0xc1) { + nv_wr32(priv, 0x408808, 0x1003e005); + nv_wr32(priv, 0x408900, 0x3080b801); + nv_wr32(priv, 0x408904, 0x62000001); + nv_wr32(priv, 0x408908, 0x00c80929); + } else { + nv_wr32(priv, 0x408808, 0x0003e00d); + nv_wr32(priv, 0x408900, 0x3080b801); + nv_wr32(priv, 0x408904, 0x02000001); + nv_wr32(priv, 0x408908, 0x00c80929); + } + nv_wr32(priv, 0x40890c, 0x00000000); + nv_wr32(priv, 0x408980, 0x0000011d); +} + +static void +nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv) +{ + int chipset = nv_device(priv)->chipset; + int i; + + /* GPC_BROADCAST */ + nv_wr32(priv, 0x418380, 0x00000016); + nv_wr32(priv, 0x418400, 0x38004e00); + nv_wr32(priv, 0x418404, 0x71e0ffff); + nv_wr32(priv, 0x418408, 0x00000000); + nv_wr32(priv, 0x41840c, 0x00001008); + nv_wr32(priv, 0x418410, 0x0fff0fff); + nv_wr32(priv, 0x418414, chipset != 0xd9 ? 0x00200fff : 0x02200fff); + nv_wr32(priv, 0x418450, 0x00000000); + nv_wr32(priv, 0x418454, 0x00000000); + nv_wr32(priv, 0x418458, 0x00000000); + nv_wr32(priv, 0x41845c, 0x00000000); + nv_wr32(priv, 0x418460, 0x00000000); + nv_wr32(priv, 0x418464, 0x00000000); + nv_wr32(priv, 0x418468, 0x00000001); + nv_wr32(priv, 0x41846c, 0x00000000); + nv_wr32(priv, 0x418470, 0x00000000); + nv_wr32(priv, 0x418600, 0x0000001f); + nv_wr32(priv, 0x418684, 0x0000000f); + nv_wr32(priv, 0x418700, 0x00000002); + nv_wr32(priv, 0x418704, 0x00000080); + nv_wr32(priv, 0x418708, 0x00000000); + nv_wr32(priv, 0x41870c, chipset != 0xd9 ? 0x07c80000 : 0x00000000); + nv_wr32(priv, 0x418710, 0x00000000); + nv_wr32(priv, 0x418800, chipset != 0xd9 ? 0x0006860a : 0x7006860a); + nv_wr32(priv, 0x418808, 0x00000000); + nv_wr32(priv, 0x41880c, 0x00000000); + nv_wr32(priv, 0x418810, 0x00000000); + nv_wr32(priv, 0x418828, 0x00008442); + if (chipset == 0xc1 || chipset == 0xd9) + nv_wr32(priv, 0x418830, 0x10000001); + else + nv_wr32(priv, 0x418830, 0x00000001); + nv_wr32(priv, 0x4188d8, 0x00000008); + nv_wr32(priv, 0x4188e0, 0x01000000); + nv_wr32(priv, 0x4188e8, 0x00000000); + nv_wr32(priv, 0x4188ec, 0x00000000); + nv_wr32(priv, 0x4188f0, 0x00000000); + nv_wr32(priv, 0x4188f4, 0x00000000); + nv_wr32(priv, 0x4188f8, 0x00000000); + if (chipset == 0xd9) + nv_wr32(priv, 0x4188fc, 0x20100008); + else if (chipset == 0xc1) + nv_wr32(priv, 0x4188fc, 0x00100018); + else + nv_wr32(priv, 0x4188fc, 0x00100000); + nv_wr32(priv, 0x41891c, 0x00ff00ff); + nv_wr32(priv, 0x418924, 0x00000000); + nv_wr32(priv, 0x418928, 0x00ffff00); + nv_wr32(priv, 0x41892c, 0x0000ff00); + for (i = 0; i < 8; i++) { + nv_wr32(priv, 0x418a00 + (i * 0x20), 0x00000000); + nv_wr32(priv, 0x418a04 + (i * 0x20), 0x00000000); + nv_wr32(priv, 0x418a08 + (i * 0x20), 0x00000000); + nv_wr32(priv, 0x418a0c + (i * 0x20), 0x00010000); + nv_wr32(priv, 0x418a10 + (i * 0x20), 0x00000000); + nv_wr32(priv, 0x418a14 + (i * 0x20), 0x00000000); + nv_wr32(priv, 0x418a18 + (i * 0x20), 0x00000000); + } + nv_wr32(priv, 0x418b00, chipset != 0xd9 ? 0x00000000 : 0x00000006); + nv_wr32(priv, 0x418b08, 0x0a418820); + nv_wr32(priv, 0x418b0c, 0x062080e6); + nv_wr32(priv, 0x418b10, 0x020398a4); + nv_wr32(priv, 0x418b14, 0x0e629062); + nv_wr32(priv, 0x418b18, 0x0a418820); + nv_wr32(priv, 0x418b1c, 0x000000e6); + nv_wr32(priv, 0x418bb8, 0x00000103); + nv_wr32(priv, 0x418c08, 0x00000001); + nv_wr32(priv, 0x418c10, 0x00000000); + nv_wr32(priv, 0x418c14, 0x00000000); + nv_wr32(priv, 0x418c18, 0x00000000); + nv_wr32(priv, 0x418c1c, 0x00000000); + nv_wr32(priv, 0x418c20, 0x00000000); + nv_wr32(priv, 0x418c24, 0x00000000); + nv_wr32(priv, 0x418c28, 0x00000000); + nv_wr32(priv, 0x418c2c, 0x00000000); + if (chipset == 0xc1 || chipset == 0xd9) + nv_wr32(priv, 0x418c6c, 0x00000001); + nv_wr32(priv, 0x418c80, 0x20200004); + nv_wr32(priv, 0x418c8c, 0x00000001); + nv_wr32(priv, 0x419000, 0x00000780); + nv_wr32(priv, 0x419004, 0x00000000); + nv_wr32(priv, 0x419008, 0x00000000); + nv_wr32(priv, 0x419014, 0x00000004); +} + +static void +nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) +{ + int chipset = nv_device(priv)->chipset; + + /* GPC_BROADCAST.TP_BROADCAST */ + nv_wr32(priv, 0x419818, 0x00000000); + nv_wr32(priv, 0x41983c, 0x00038bc7); + nv_wr32(priv, 0x419848, 0x00000000); + if (chipset == 0xc1 || chipset == 0xd9) + nv_wr32(priv, 0x419864, 0x00000129); + else + nv_wr32(priv, 0x419864, 0x0000012a); + nv_wr32(priv, 0x419888, 0x00000000); + nv_wr32(priv, 0x419a00, 0x000001f0); + nv_wr32(priv, 0x419a04, 0x00000001); + nv_wr32(priv, 0x419a08, 0x00000023); + nv_wr32(priv, 0x419a0c, 0x00020000); + nv_wr32(priv, 0x419a10, 0x00000000); + nv_wr32(priv, 0x419a14, 0x00000200); + nv_wr32(priv, 0x419a1c, 0x00000000); + nv_wr32(priv, 0x419a20, 0x00000800); + if (chipset == 0xd9) + nv_wr32(priv, 0x00419ac4, 0x0017f440); + else if (chipset != 0xc0 && chipset != 0xc8) + nv_wr32(priv, 0x00419ac4, 0x0007f440); + nv_wr32(priv, 0x419b00, 0x0a418820); + nv_wr32(priv, 0x419b04, 0x062080e6); + nv_wr32(priv, 0x419b08, 0x020398a4); + nv_wr32(priv, 0x419b0c, 0x0e629062); + nv_wr32(priv, 0x419b10, 0x0a418820); + nv_wr32(priv, 0x419b14, 0x000000e6); + nv_wr32(priv, 0x419bd0, 0x00900103); + if (chipset == 0xc1 || chipset == 0xd9) + nv_wr32(priv, 0x419be0, 0x00400001); + else + nv_wr32(priv, 0x419be0, 0x00000001); + nv_wr32(priv, 0x419be4, 0x00000000); + nv_wr32(priv, 0x419c00, chipset != 0xd9 ? 0x00000002 : 0x0000000a); + nv_wr32(priv, 0x419c04, 0x00000006); + nv_wr32(priv, 0x419c08, 0x00000002); + nv_wr32(priv, 0x419c20, 0x00000000); + if (nv_device(priv)->chipset == 0xd9) { + nv_wr32(priv, 0x419c24, 0x00084210); + nv_wr32(priv, 0x419c28, 0x3cf3cf3c); + nv_wr32(priv, 0x419cb0, 0x00020048); + } else + if (chipset == 0xce || chipset == 0xcf) { + nv_wr32(priv, 0x419cb0, 0x00020048); + } else { + nv_wr32(priv, 0x419cb0, 0x00060048); + } + nv_wr32(priv, 0x419ce8, 0x00000000); + nv_wr32(priv, 0x419cf4, 0x00000183); + if (chipset == 0xc1 || chipset == 0xd9) + nv_wr32(priv, 0x419d20, 0x12180000); + else + nv_wr32(priv, 0x419d20, 0x02180000); + nv_wr32(priv, 0x419d24, 0x00001fff); + if (chipset == 0xc1 || chipset == 0xd9) + nv_wr32(priv, 0x419d44, 0x02180218); + nv_wr32(priv, 0x419e04, 0x00000000); + nv_wr32(priv, 0x419e08, 0x00000000); + nv_wr32(priv, 0x419e0c, 0x00000000); + nv_wr32(priv, 0x419e10, 0x00000002); + nv_wr32(priv, 0x419e44, 0x001beff2); + nv_wr32(priv, 0x419e48, 0x00000000); + nv_wr32(priv, 0x419e4c, 0x0000000f); + nv_wr32(priv, 0x419e50, 0x00000000); + nv_wr32(priv, 0x419e54, 0x00000000); + nv_wr32(priv, 0x419e58, 0x00000000); + nv_wr32(priv, 0x419e5c, 0x00000000); + nv_wr32(priv, 0x419e60, 0x00000000); + nv_wr32(priv, 0x419e64, 0x00000000); + nv_wr32(priv, 0x419e68, 0x00000000); + nv_wr32(priv, 0x419e6c, 0x00000000); + nv_wr32(priv, 0x419e70, 0x00000000); + nv_wr32(priv, 0x419e74, 0x00000000); + nv_wr32(priv, 0x419e78, 0x00000000); + nv_wr32(priv, 0x419e7c, 0x00000000); + nv_wr32(priv, 0x419e80, 0x00000000); + nv_wr32(priv, 0x419e84, 0x00000000); + nv_wr32(priv, 0x419e88, 0x00000000); + nv_wr32(priv, 0x419e8c, 0x00000000); + nv_wr32(priv, 0x419e90, 0x00000000); + nv_wr32(priv, 0x419e98, 0x00000000); + if (chipset != 0xc0 && chipset != 0xc8) + nv_wr32(priv, 0x419ee0, 0x00011110); + nv_wr32(priv, 0x419f50, 0x00000000); + nv_wr32(priv, 0x419f54, 0x00000000); + if (chipset != 0xc0 && chipset != 0xc8) + nv_wr32(priv, 0x419f58, 0x00000000); +} + +int +nvc0_grctx_generate(struct nvc0_graph_priv *priv) +{ + struct nvc0_grctx info; + int ret, i, gpc, tpc, id; + u32 fermi = nvc0_graph_class(priv); + u32 r000260, tmp; + + ret = nvc0_grctx_init(priv, &info); + if (ret) + return ret; + + r000260 = nv_rd32(priv, 0x000260); + nv_wr32(priv, 0x000260, r000260 & ~1); + nv_wr32(priv, 0x400208, 0x00000000); + + nvc0_grctx_generate_dispatch(priv); + nvc0_grctx_generate_macro(priv); + nvc0_grctx_generate_m2mf(priv); + nvc0_grctx_generate_unk47xx(priv); + nvc0_grctx_generate_shaders(priv); + nvc0_grctx_generate_unk60xx(priv); + nvc0_grctx_generate_unk64xx(priv); + nvc0_grctx_generate_tpbus(priv); + nvc0_grctx_generate_ccache(priv); + nvc0_grctx_generate_rop(priv); + nvc0_grctx_generate_gpc(priv); + nvc0_grctx_generate_tp(priv); + + nv_wr32(priv, 0x404154, 0x00000000); + + /* generate per-context mmio list data */ + mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); + mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); + mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); + mmio_list(0x408004, 0x00000000, 8, 0); + mmio_list(0x408008, 0x80000018, 0, 0); + mmio_list(0x40800c, 0x00000000, 8, 1); + mmio_list(0x408010, 0x80000000, 0, 0); + mmio_list(0x418810, 0x80000000, 12, 2); + mmio_list(0x419848, 0x10000000, 12, 2); + mmio_list(0x419004, 0x00000000, 8, 1); + mmio_list(0x419008, 0x00000000, 0, 0); + mmio_list(0x418808, 0x00000000, 8, 0); + mmio_list(0x41880c, 0x80000018, 0, 0); + if (nv_device(priv)->chipset != 0xc1) { + tmp = 0x02180000; + mmio_list(0x405830, tmp, 0, 0); + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { + u32 reg = TPC_UNIT(gpc, tpc, 0x0520); + mmio_list(reg, tmp, 0, 0); + tmp += 0x0324; + } + } + } else { + tmp = 0x02180000; + mmio_list(0x405830, 0x00000218 | tmp, 0, 0); + mmio_list(0x4064c4, 0x0086ffff, 0, 0); + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { + u32 reg = TPC_UNIT(gpc, tpc, 0x0520); + mmio_list(reg, 0x10000000 | tmp, 0, 0); + tmp += 0x0324; + } + for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { + u32 reg = TPC_UNIT(gpc, tpc, 0x0544); + mmio_list(reg, tmp, 0, 0); + tmp += 0x0324; + } + } + } + + for (tpc = 0, id = 0; tpc < 4; tpc++) { + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + if (tpc < priv->tpc_nr[gpc]) { + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x698), id); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x4e8), id); + nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x088), id); + id++; + } + + nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]); + nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]); + } + } + + tmp = 0; + for (i = 0; i < priv->gpc_nr; i++) + tmp |= priv->tpc_nr[i] << (i * 4); + nv_wr32(priv, 0x406028, tmp); + nv_wr32(priv, 0x405870, tmp); + + nv_wr32(priv, 0x40602c, 0x00000000); + nv_wr32(priv, 0x405874, 0x00000000); + nv_wr32(priv, 0x406030, 0x00000000); + nv_wr32(priv, 0x405878, 0x00000000); + nv_wr32(priv, 0x406034, 0x00000000); + nv_wr32(priv, 0x40587c, 0x00000000); + + if (1) { + u8 tpcnr[GPC_MAX], data[TPC_MAX]; + + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + memset(data, 0x1f, sizeof(data)); + + gpc = -1; + for (tpc = 0; tpc < priv->tpc_total; tpc++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpcnr[gpc]--; + data[tpc] = gpc; + } + + for (i = 0; i < 4; i++) + nv_wr32(priv, 0x4060a8 + (i * 4), ((u32 *)data)[i]); + } + + if (1) { + u32 data[6] = {}, data2[2] = {}; + u8 tpcnr[GPC_MAX]; + u8 shift, ntpcv; + + /* calculate first set of magics */ + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + + gpc = -1; + for (tpc = 0; tpc < priv->tpc_total; tpc++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpcnr[gpc]--; + + data[tpc / 6] |= gpc << ((tpc % 6) * 5); + } + + for (; tpc < 32; tpc++) + data[tpc / 6] |= 7 << ((tpc % 6) * 5); + + /* and the second... */ + shift = 0; + ntpcv = priv->tpc_total; + while (!(ntpcv & (1 << 4))) { + ntpcv <<= 1; + shift++; + } + + data2[0] = (ntpcv << 16); + data2[0] |= (shift << 21); + data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); + for (i = 1; i < 7; i++) + data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); + + /* GPC_BROADCAST */ + nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) | + priv->magic_not_rop_nr); + for (i = 0; i < 6; i++) + nv_wr32(priv, 0x418b08 + (i * 4), data[i]); + + /* GPC_BROADCAST.TP_BROADCAST */ + nv_wr32(priv, 0x419bd0, (priv->tpc_total << 8) | + priv->magic_not_rop_nr | + data2[0]); + nv_wr32(priv, 0x419be4, data2[1]); + for (i = 0; i < 6; i++) + nv_wr32(priv, 0x419b00 + (i * 4), data[i]); + + /* UNK78xx */ + nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) | + priv->magic_not_rop_nr); + for (i = 0; i < 6; i++) + nv_wr32(priv, 0x40780c + (i * 4), data[i]); + } + + if (1) { + u32 tpc_mask = 0, tpc_set = 0; + u8 tpcnr[GPC_MAX], a, b; + + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + for (gpc = 0; gpc < priv->gpc_nr; gpc++) + tpc_mask |= ((1 << priv->tpc_nr[gpc]) - 1) << (gpc * 8); + + for (i = 0, gpc = -1, b = -1; i < 32; i++) { + a = (i * (priv->tpc_total - 1)) / 32; + if (a != b) { + b = a; + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; + + tpc_set |= 1 << ((gpc * 8) + tpc); + } + + nv_wr32(priv, 0x406800 + (i * 0x20), tpc_set); + nv_wr32(priv, 0x406c00 + (i * 0x20), tpc_set ^ tpc_mask); + } + } + + nv_wr32(priv, 0x400208, 0x80000000); + + nv_icmd(priv, 0x00001000, 0x00000004); + nv_icmd(priv, 0x000000a9, 0x0000ffff); + nv_icmd(priv, 0x00000038, 0x0fac6881); + nv_icmd(priv, 0x0000003d, 0x00000001); + nv_icmd(priv, 0x000000e8, 0x00000400); + nv_icmd(priv, 0x000000e9, 0x00000400); + nv_icmd(priv, 0x000000ea, 0x00000400); + nv_icmd(priv, 0x000000eb, 0x00000400); + nv_icmd(priv, 0x000000ec, 0x00000400); + nv_icmd(priv, 0x000000ed, 0x00000400); + nv_icmd(priv, 0x000000ee, 0x00000400); + nv_icmd(priv, 0x000000ef, 0x00000400); + nv_icmd(priv, 0x00000078, 0x00000300); + nv_icmd(priv, 0x00000079, 0x00000300); + nv_icmd(priv, 0x0000007a, 0x00000300); + nv_icmd(priv, 0x0000007b, 0x00000300); + nv_icmd(priv, 0x0000007c, 0x00000300); + nv_icmd(priv, 0x0000007d, 0x00000300); + nv_icmd(priv, 0x0000007e, 0x00000300); + nv_icmd(priv, 0x0000007f, 0x00000300); + nv_icmd(priv, 0x00000050, 0x00000011); + nv_icmd(priv, 0x00000058, 0x00000008); + nv_icmd(priv, 0x00000059, 0x00000008); + nv_icmd(priv, 0x0000005a, 0x00000008); + nv_icmd(priv, 0x0000005b, 0x00000008); + nv_icmd(priv, 0x0000005c, 0x00000008); + nv_icmd(priv, 0x0000005d, 0x00000008); + nv_icmd(priv, 0x0000005e, 0x00000008); + nv_icmd(priv, 0x0000005f, 0x00000008); + nv_icmd(priv, 0x00000208, 0x00000001); + nv_icmd(priv, 0x00000209, 0x00000001); + nv_icmd(priv, 0x0000020a, 0x00000001); + nv_icmd(priv, 0x0000020b, 0x00000001); + nv_icmd(priv, 0x0000020c, 0x00000001); + nv_icmd(priv, 0x0000020d, 0x00000001); + nv_icmd(priv, 0x0000020e, 0x00000001); + nv_icmd(priv, 0x0000020f, 0x00000001); + nv_icmd(priv, 0x00000081, 0x00000001); + nv_icmd(priv, 0x00000085, 0x00000004); + nv_icmd(priv, 0x00000088, 0x00000400); + nv_icmd(priv, 0x00000090, 0x00000300); + nv_icmd(priv, 0x00000098, 0x00001001); + nv_icmd(priv, 0x000000e3, 0x00000001); + nv_icmd(priv, 0x000000da, 0x00000001); + nv_icmd(priv, 0x000000f8, 0x00000003); + nv_icmd(priv, 0x000000fa, 0x00000001); + nv_icmd(priv, 0x0000009f, 0x0000ffff); + nv_icmd(priv, 0x000000a0, 0x0000ffff); + nv_icmd(priv, 0x000000a1, 0x0000ffff); + nv_icmd(priv, 0x000000a2, 0x0000ffff); + nv_icmd(priv, 0x000000b1, 0x00000001); + nv_icmd(priv, 0x000000b2, 0x00000000); + nv_icmd(priv, 0x000000b3, 0x00000000); + nv_icmd(priv, 0x000000b4, 0x00000000); + nv_icmd(priv, 0x000000b5, 0x00000000); + nv_icmd(priv, 0x000000b6, 0x00000000); + nv_icmd(priv, 0x000000b7, 0x00000000); + nv_icmd(priv, 0x000000b8, 0x00000000); + nv_icmd(priv, 0x000000b9, 0x00000000); + nv_icmd(priv, 0x000000ba, 0x00000000); + nv_icmd(priv, 0x000000bb, 0x00000000); + nv_icmd(priv, 0x000000bc, 0x00000000); + nv_icmd(priv, 0x000000bd, 0x00000000); + nv_icmd(priv, 0x000000be, 0x00000000); + nv_icmd(priv, 0x000000bf, 0x00000000); + nv_icmd(priv, 0x000000c0, 0x00000000); + nv_icmd(priv, 0x000000c1, 0x00000000); + nv_icmd(priv, 0x000000c2, 0x00000000); + nv_icmd(priv, 0x000000c3, 0x00000000); + nv_icmd(priv, 0x000000c4, 0x00000000); + nv_icmd(priv, 0x000000c5, 0x00000000); + nv_icmd(priv, 0x000000c6, 0x00000000); + nv_icmd(priv, 0x000000c7, 0x00000000); + nv_icmd(priv, 0x000000c8, 0x00000000); + nv_icmd(priv, 0x000000c9, 0x00000000); + nv_icmd(priv, 0x000000ca, 0x00000000); + nv_icmd(priv, 0x000000cb, 0x00000000); + nv_icmd(priv, 0x000000cc, 0x00000000); + nv_icmd(priv, 0x000000cd, 0x00000000); + nv_icmd(priv, 0x000000ce, 0x00000000); + nv_icmd(priv, 0x000000cf, 0x00000000); + nv_icmd(priv, 0x000000d0, 0x00000000); + nv_icmd(priv, 0x000000d1, 0x00000000); + nv_icmd(priv, 0x000000d2, 0x00000000); + nv_icmd(priv, 0x000000d3, 0x00000000); + nv_icmd(priv, 0x000000d4, 0x00000000); + nv_icmd(priv, 0x000000d5, 0x00000000); + nv_icmd(priv, 0x000000d6, 0x00000000); + nv_icmd(priv, 0x000000d7, 0x00000000); + nv_icmd(priv, 0x000000d8, 0x00000000); + nv_icmd(priv, 0x000000d9, 0x00000000); + nv_icmd(priv, 0x00000210, 0x00000040); + nv_icmd(priv, 0x00000211, 0x00000040); + nv_icmd(priv, 0x00000212, 0x00000040); + nv_icmd(priv, 0x00000213, 0x00000040); + nv_icmd(priv, 0x00000214, 0x00000040); + nv_icmd(priv, 0x00000215, 0x00000040); + nv_icmd(priv, 0x00000216, 0x00000040); + nv_icmd(priv, 0x00000217, 0x00000040); + if (nv_device(priv)->chipset == 0xd9) { + for (i = 0x0400; i <= 0x0417; i++) + nv_icmd(priv, i, 0x00000040); + } + nv_icmd(priv, 0x00000218, 0x0000c080); + nv_icmd(priv, 0x00000219, 0x0000c080); + nv_icmd(priv, 0x0000021a, 0x0000c080); + nv_icmd(priv, 0x0000021b, 0x0000c080); + nv_icmd(priv, 0x0000021c, 0x0000c080); + nv_icmd(priv, 0x0000021d, 0x0000c080); + nv_icmd(priv, 0x0000021e, 0x0000c080); + nv_icmd(priv, 0x0000021f, 0x0000c080); + if (nv_device(priv)->chipset == 0xd9) { + for (i = 0x0440; i <= 0x0457; i++) + nv_icmd(priv, i, 0x0000c080); + } + nv_icmd(priv, 0x000000ad, 0x0000013e); + nv_icmd(priv, 0x000000e1, 0x00000010); + nv_icmd(priv, 0x00000290, 0x00000000); + nv_icmd(priv, 0x00000291, 0x00000000); + nv_icmd(priv, 0x00000292, 0x00000000); + nv_icmd(priv, 0x00000293, 0x00000000); + nv_icmd(priv, 0x00000294, 0x00000000); + nv_icmd(priv, 0x00000295, 0x00000000); + nv_icmd(priv, 0x00000296, 0x00000000); + nv_icmd(priv, 0x00000297, 0x00000000); + nv_icmd(priv, 0x00000298, 0x00000000); + nv_icmd(priv, 0x00000299, 0x00000000); + nv_icmd(priv, 0x0000029a, 0x00000000); + nv_icmd(priv, 0x0000029b, 0x00000000); + nv_icmd(priv, 0x0000029c, 0x00000000); + nv_icmd(priv, 0x0000029d, 0x00000000); + nv_icmd(priv, 0x0000029e, 0x00000000); + nv_icmd(priv, 0x0000029f, 0x00000000); + nv_icmd(priv, 0x000003b0, 0x00000000); + nv_icmd(priv, 0x000003b1, 0x00000000); + nv_icmd(priv, 0x000003b2, 0x00000000); + nv_icmd(priv, 0x000003b3, 0x00000000); + nv_icmd(priv, 0x000003b4, 0x00000000); + nv_icmd(priv, 0x000003b5, 0x00000000); + nv_icmd(priv, 0x000003b6, 0x00000000); + nv_icmd(priv, 0x000003b7, 0x00000000); + nv_icmd(priv, 0x000003b8, 0x00000000); + nv_icmd(priv, 0x000003b9, 0x00000000); + nv_icmd(priv, 0x000003ba, 0x00000000); + nv_icmd(priv, 0x000003bb, 0x00000000); + nv_icmd(priv, 0x000003bc, 0x00000000); + nv_icmd(priv, 0x000003bd, 0x00000000); + nv_icmd(priv, 0x000003be, 0x00000000); + nv_icmd(priv, 0x000003bf, 0x00000000); + nv_icmd(priv, 0x000002a0, 0x00000000); + nv_icmd(priv, 0x000002a1, 0x00000000); + nv_icmd(priv, 0x000002a2, 0x00000000); + nv_icmd(priv, 0x000002a3, 0x00000000); + nv_icmd(priv, 0x000002a4, 0x00000000); + nv_icmd(priv, 0x000002a5, 0x00000000); + nv_icmd(priv, 0x000002a6, 0x00000000); + nv_icmd(priv, 0x000002a7, 0x00000000); + nv_icmd(priv, 0x000002a8, 0x00000000); + nv_icmd(priv, 0x000002a9, 0x00000000); + nv_icmd(priv, 0x000002aa, 0x00000000); + nv_icmd(priv, 0x000002ab, 0x00000000); + nv_icmd(priv, 0x000002ac, 0x00000000); + nv_icmd(priv, 0x000002ad, 0x00000000); + nv_icmd(priv, 0x000002ae, 0x00000000); + nv_icmd(priv, 0x000002af, 0x00000000); + nv_icmd(priv, 0x00000420, 0x00000000); + nv_icmd(priv, 0x00000421, 0x00000000); + nv_icmd(priv, 0x00000422, 0x00000000); + nv_icmd(priv, 0x00000423, 0x00000000); + nv_icmd(priv, 0x00000424, 0x00000000); + nv_icmd(priv, 0x00000425, 0x00000000); + nv_icmd(priv, 0x00000426, 0x00000000); + nv_icmd(priv, 0x00000427, 0x00000000); + nv_icmd(priv, 0x00000428, 0x00000000); + nv_icmd(priv, 0x00000429, 0x00000000); + nv_icmd(priv, 0x0000042a, 0x00000000); + nv_icmd(priv, 0x0000042b, 0x00000000); + nv_icmd(priv, 0x0000042c, 0x00000000); + nv_icmd(priv, 0x0000042d, 0x00000000); + nv_icmd(priv, 0x0000042e, 0x00000000); + nv_icmd(priv, 0x0000042f, 0x00000000); + nv_icmd(priv, 0x000002b0, 0x00000000); + nv_icmd(priv, 0x000002b1, 0x00000000); + nv_icmd(priv, 0x000002b2, 0x00000000); + nv_icmd(priv, 0x000002b3, 0x00000000); + nv_icmd(priv, 0x000002b4, 0x00000000); + nv_icmd(priv, 0x000002b5, 0x00000000); + nv_icmd(priv, 0x000002b6, 0x00000000); + nv_icmd(priv, 0x000002b7, 0x00000000); + nv_icmd(priv, 0x000002b8, 0x00000000); + nv_icmd(priv, 0x000002b9, 0x00000000); + nv_icmd(priv, 0x000002ba, 0x00000000); + nv_icmd(priv, 0x000002bb, 0x00000000); + nv_icmd(priv, 0x000002bc, 0x00000000); + nv_icmd(priv, 0x000002bd, 0x00000000); + nv_icmd(priv, 0x000002be, 0x00000000); + nv_icmd(priv, 0x000002bf, 0x00000000); + nv_icmd(priv, 0x00000430, 0x00000000); + nv_icmd(priv, 0x00000431, 0x00000000); + nv_icmd(priv, 0x00000432, 0x00000000); + nv_icmd(priv, 0x00000433, 0x00000000); + nv_icmd(priv, 0x00000434, 0x00000000); + nv_icmd(priv, 0x00000435, 0x00000000); + nv_icmd(priv, 0x00000436, 0x00000000); + nv_icmd(priv, 0x00000437, 0x00000000); + nv_icmd(priv, 0x00000438, 0x00000000); + nv_icmd(priv, 0x00000439, 0x00000000); + nv_icmd(priv, 0x0000043a, 0x00000000); + nv_icmd(priv, 0x0000043b, 0x00000000); + nv_icmd(priv, 0x0000043c, 0x00000000); + nv_icmd(priv, 0x0000043d, 0x00000000); + nv_icmd(priv, 0x0000043e, 0x00000000); + nv_icmd(priv, 0x0000043f, 0x00000000); + nv_icmd(priv, 0x000002c0, 0x00000000); + nv_icmd(priv, 0x000002c1, 0x00000000); + nv_icmd(priv, 0x000002c2, 0x00000000); + nv_icmd(priv, 0x000002c3, 0x00000000); + nv_icmd(priv, 0x000002c4, 0x00000000); + nv_icmd(priv, 0x000002c5, 0x00000000); + nv_icmd(priv, 0x000002c6, 0x00000000); + nv_icmd(priv, 0x000002c7, 0x00000000); + nv_icmd(priv, 0x000002c8, 0x00000000); + nv_icmd(priv, 0x000002c9, 0x00000000); + nv_icmd(priv, 0x000002ca, 0x00000000); + nv_icmd(priv, 0x000002cb, 0x00000000); + nv_icmd(priv, 0x000002cc, 0x00000000); + nv_icmd(priv, 0x000002cd, 0x00000000); + nv_icmd(priv, 0x000002ce, 0x00000000); + nv_icmd(priv, 0x000002cf, 0x00000000); + nv_icmd(priv, 0x000004d0, 0x00000000); + nv_icmd(priv, 0x000004d1, 0x00000000); + nv_icmd(priv, 0x000004d2, 0x00000000); + nv_icmd(priv, 0x000004d3, 0x00000000); + nv_icmd(priv, 0x000004d4, 0x00000000); + nv_icmd(priv, 0x000004d5, 0x00000000); + nv_icmd(priv, 0x000004d6, 0x00000000); + nv_icmd(priv, 0x000004d7, 0x00000000); + nv_icmd(priv, 0x000004d8, 0x00000000); + nv_icmd(priv, 0x000004d9, 0x00000000); + nv_icmd(priv, 0x000004da, 0x00000000); + nv_icmd(priv, 0x000004db, 0x00000000); + nv_icmd(priv, 0x000004dc, 0x00000000); + nv_icmd(priv, 0x000004dd, 0x00000000); + nv_icmd(priv, 0x000004de, 0x00000000); + nv_icmd(priv, 0x000004df, 0x00000000); + nv_icmd(priv, 0x00000720, 0x00000000); + nv_icmd(priv, 0x00000721, 0x00000000); + nv_icmd(priv, 0x00000722, 0x00000000); + nv_icmd(priv, 0x00000723, 0x00000000); + nv_icmd(priv, 0x00000724, 0x00000000); + nv_icmd(priv, 0x00000725, 0x00000000); + nv_icmd(priv, 0x00000726, 0x00000000); + nv_icmd(priv, 0x00000727, 0x00000000); + nv_icmd(priv, 0x00000728, 0x00000000); + nv_icmd(priv, 0x00000729, 0x00000000); + nv_icmd(priv, 0x0000072a, 0x00000000); + nv_icmd(priv, 0x0000072b, 0x00000000); + nv_icmd(priv, 0x0000072c, 0x00000000); + nv_icmd(priv, 0x0000072d, 0x00000000); + nv_icmd(priv, 0x0000072e, 0x00000000); + nv_icmd(priv, 0x0000072f, 0x00000000); + nv_icmd(priv, 0x000008c0, 0x00000000); + nv_icmd(priv, 0x000008c1, 0x00000000); + nv_icmd(priv, 0x000008c2, 0x00000000); + nv_icmd(priv, 0x000008c3, 0x00000000); + nv_icmd(priv, 0x000008c4, 0x00000000); + nv_icmd(priv, 0x000008c5, 0x00000000); + nv_icmd(priv, 0x000008c6, 0x00000000); + nv_icmd(priv, 0x000008c7, 0x00000000); + nv_icmd(priv, 0x000008c8, 0x00000000); + nv_icmd(priv, 0x000008c9, 0x00000000); + nv_icmd(priv, 0x000008ca, 0x00000000); + nv_icmd(priv, 0x000008cb, 0x00000000); + nv_icmd(priv, 0x000008cc, 0x00000000); + nv_icmd(priv, 0x000008cd, 0x00000000); + nv_icmd(priv, 0x000008ce, 0x00000000); + nv_icmd(priv, 0x000008cf, 0x00000000); + nv_icmd(priv, 0x00000890, 0x00000000); + nv_icmd(priv, 0x00000891, 0x00000000); + nv_icmd(priv, 0x00000892, 0x00000000); + nv_icmd(priv, 0x00000893, 0x00000000); + nv_icmd(priv, 0x00000894, 0x00000000); + nv_icmd(priv, 0x00000895, 0x00000000); + nv_icmd(priv, 0x00000896, 0x00000000); + nv_icmd(priv, 0x00000897, 0x00000000); + nv_icmd(priv, 0x00000898, 0x00000000); + nv_icmd(priv, 0x00000899, 0x00000000); + nv_icmd(priv, 0x0000089a, 0x00000000); + nv_icmd(priv, 0x0000089b, 0x00000000); + nv_icmd(priv, 0x0000089c, 0x00000000); + nv_icmd(priv, 0x0000089d, 0x00000000); + nv_icmd(priv, 0x0000089e, 0x00000000); + nv_icmd(priv, 0x0000089f, 0x00000000); + nv_icmd(priv, 0x000008e0, 0x00000000); + nv_icmd(priv, 0x000008e1, 0x00000000); + nv_icmd(priv, 0x000008e2, 0x00000000); + nv_icmd(priv, 0x000008e3, 0x00000000); + nv_icmd(priv, 0x000008e4, 0x00000000); + nv_icmd(priv, 0x000008e5, 0x00000000); + nv_icmd(priv, 0x000008e6, 0x00000000); + nv_icmd(priv, 0x000008e7, 0x00000000); + nv_icmd(priv, 0x000008e8, 0x00000000); + nv_icmd(priv, 0x000008e9, 0x00000000); + nv_icmd(priv, 0x000008ea, 0x00000000); + nv_icmd(priv, 0x000008eb, 0x00000000); + nv_icmd(priv, 0x000008ec, 0x00000000); + nv_icmd(priv, 0x000008ed, 0x00000000); + nv_icmd(priv, 0x000008ee, 0x00000000); + nv_icmd(priv, 0x000008ef, 0x00000000); + nv_icmd(priv, 0x000008a0, 0x00000000); + nv_icmd(priv, 0x000008a1, 0x00000000); + nv_icmd(priv, 0x000008a2, 0x00000000); + nv_icmd(priv, 0x000008a3, 0x00000000); + nv_icmd(priv, 0x000008a4, 0x00000000); + nv_icmd(priv, 0x000008a5, 0x00000000); + nv_icmd(priv, 0x000008a6, 0x00000000); + nv_icmd(priv, 0x000008a7, 0x00000000); + nv_icmd(priv, 0x000008a8, 0x00000000); + nv_icmd(priv, 0x000008a9, 0x00000000); + nv_icmd(priv, 0x000008aa, 0x00000000); + nv_icmd(priv, 0x000008ab, 0x00000000); + nv_icmd(priv, 0x000008ac, 0x00000000); + nv_icmd(priv, 0x000008ad, 0x00000000); + nv_icmd(priv, 0x000008ae, 0x00000000); + nv_icmd(priv, 0x000008af, 0x00000000); + nv_icmd(priv, 0x000008f0, 0x00000000); + nv_icmd(priv, 0x000008f1, 0x00000000); + nv_icmd(priv, 0x000008f2, 0x00000000); + nv_icmd(priv, 0x000008f3, 0x00000000); + nv_icmd(priv, 0x000008f4, 0x00000000); + nv_icmd(priv, 0x000008f5, 0x00000000); + nv_icmd(priv, 0x000008f6, 0x00000000); + nv_icmd(priv, 0x000008f7, 0x00000000); + nv_icmd(priv, 0x000008f8, 0x00000000); + nv_icmd(priv, 0x000008f9, 0x00000000); + nv_icmd(priv, 0x000008fa, 0x00000000); + nv_icmd(priv, 0x000008fb, 0x00000000); + nv_icmd(priv, 0x000008fc, 0x00000000); + nv_icmd(priv, 0x000008fd, 0x00000000); + nv_icmd(priv, 0x000008fe, 0x00000000); + nv_icmd(priv, 0x000008ff, 0x00000000); + nv_icmd(priv, 0x0000094c, 0x000000ff); + nv_icmd(priv, 0x0000094d, 0xffffffff); + nv_icmd(priv, 0x0000094e, 0x00000002); + nv_icmd(priv, 0x000002ec, 0x00000001); + nv_icmd(priv, 0x00000303, 0x00000001); + nv_icmd(priv, 0x000002e6, 0x00000001); + nv_icmd(priv, 0x00000466, 0x00000052); + nv_icmd(priv, 0x00000301, 0x3f800000); + nv_icmd(priv, 0x00000304, 0x30201000); + nv_icmd(priv, 0x00000305, 0x70605040); + nv_icmd(priv, 0x00000306, 0xb8a89888); + nv_icmd(priv, 0x00000307, 0xf8e8d8c8); + nv_icmd(priv, 0x0000030a, 0x00ffff00); + nv_icmd(priv, 0x0000030b, 0x0000001a); + nv_icmd(priv, 0x0000030c, 0x00000001); + nv_icmd(priv, 0x00000318, 0x00000001); + nv_icmd(priv, 0x00000340, 0x00000000); + nv_icmd(priv, 0x00000375, 0x00000001); + nv_icmd(priv, 0x00000351, 0x00000100); + nv_icmd(priv, 0x0000037d, 0x00000006); + nv_icmd(priv, 0x000003a0, 0x00000002); + nv_icmd(priv, 0x000003aa, 0x00000001); + nv_icmd(priv, 0x000003a9, 0x00000001); + nv_icmd(priv, 0x00000380, 0x00000001); + nv_icmd(priv, 0x00000360, 0x00000040); + nv_icmd(priv, 0x00000366, 0x00000000); + nv_icmd(priv, 0x00000367, 0x00000000); + nv_icmd(priv, 0x00000368, 0x00001fff); + nv_icmd(priv, 0x00000370, 0x00000000); + nv_icmd(priv, 0x00000371, 0x00000000); + nv_icmd(priv, 0x00000372, 0x003fffff); + nv_icmd(priv, 0x0000037a, 0x00000012); + nv_icmd(priv, 0x000005e0, 0x00000022); + nv_icmd(priv, 0x000005e1, 0x00000022); + nv_icmd(priv, 0x000005e2, 0x00000022); + nv_icmd(priv, 0x000005e3, 0x00000022); + nv_icmd(priv, 0x000005e4, 0x00000022); + nv_icmd(priv, 0x00000619, 0x00000003); + nv_icmd(priv, 0x00000811, 0x00000003); + nv_icmd(priv, 0x00000812, 0x00000004); + nv_icmd(priv, 0x00000813, 0x00000006); + nv_icmd(priv, 0x00000814, 0x00000008); + nv_icmd(priv, 0x00000815, 0x0000000b); + nv_icmd(priv, 0x00000800, 0x00000001); + nv_icmd(priv, 0x00000801, 0x00000001); + nv_icmd(priv, 0x00000802, 0x00000001); + nv_icmd(priv, 0x00000803, 0x00000001); + nv_icmd(priv, 0x00000804, 0x00000001); + nv_icmd(priv, 0x00000805, 0x00000001); + nv_icmd(priv, 0x00000632, 0x00000001); + nv_icmd(priv, 0x00000633, 0x00000002); + nv_icmd(priv, 0x00000634, 0x00000003); + nv_icmd(priv, 0x00000635, 0x00000004); + nv_icmd(priv, 0x00000654, 0x3f800000); + nv_icmd(priv, 0x00000657, 0x3f800000); + nv_icmd(priv, 0x00000655, 0x3f800000); + nv_icmd(priv, 0x00000656, 0x3f800000); + nv_icmd(priv, 0x000006cd, 0x3f800000); + nv_icmd(priv, 0x000007f5, 0x3f800000); + nv_icmd(priv, 0x000007dc, 0x39291909); + nv_icmd(priv, 0x000007dd, 0x79695949); + nv_icmd(priv, 0x000007de, 0xb9a99989); + nv_icmd(priv, 0x000007df, 0xf9e9d9c9); + nv_icmd(priv, 0x000007e8, 0x00003210); + nv_icmd(priv, 0x000007e9, 0x00007654); + nv_icmd(priv, 0x000007ea, 0x00000098); + nv_icmd(priv, 0x000007ec, 0x39291909); + nv_icmd(priv, 0x000007ed, 0x79695949); + nv_icmd(priv, 0x000007ee, 0xb9a99989); + nv_icmd(priv, 0x000007ef, 0xf9e9d9c9); + nv_icmd(priv, 0x000007f0, 0x00003210); + nv_icmd(priv, 0x000007f1, 0x00007654); + nv_icmd(priv, 0x000007f2, 0x00000098); + nv_icmd(priv, 0x000005a5, 0x00000001); + nv_icmd(priv, 0x00000980, 0x00000000); + nv_icmd(priv, 0x00000981, 0x00000000); + nv_icmd(priv, 0x00000982, 0x00000000); + nv_icmd(priv, 0x00000983, 0x00000000); + nv_icmd(priv, 0x00000984, 0x00000000); + nv_icmd(priv, 0x00000985, 0x00000000); + nv_icmd(priv, 0x00000986, 0x00000000); + nv_icmd(priv, 0x00000987, 0x00000000); + nv_icmd(priv, 0x00000988, 0x00000000); + nv_icmd(priv, 0x00000989, 0x00000000); + nv_icmd(priv, 0x0000098a, 0x00000000); + nv_icmd(priv, 0x0000098b, 0x00000000); + nv_icmd(priv, 0x0000098c, 0x00000000); + nv_icmd(priv, 0x0000098d, 0x00000000); + nv_icmd(priv, 0x0000098e, 0x00000000); + nv_icmd(priv, 0x0000098f, 0x00000000); + nv_icmd(priv, 0x00000990, 0x00000000); + nv_icmd(priv, 0x00000991, 0x00000000); + nv_icmd(priv, 0x00000992, 0x00000000); + nv_icmd(priv, 0x00000993, 0x00000000); + nv_icmd(priv, 0x00000994, 0x00000000); + nv_icmd(priv, 0x00000995, 0x00000000); + nv_icmd(priv, 0x00000996, 0x00000000); + nv_icmd(priv, 0x00000997, 0x00000000); + nv_icmd(priv, 0x00000998, 0x00000000); + nv_icmd(priv, 0x00000999, 0x00000000); + nv_icmd(priv, 0x0000099a, 0x00000000); + nv_icmd(priv, 0x0000099b, 0x00000000); + nv_icmd(priv, 0x0000099c, 0x00000000); + nv_icmd(priv, 0x0000099d, 0x00000000); + nv_icmd(priv, 0x0000099e, 0x00000000); + nv_icmd(priv, 0x0000099f, 0x00000000); + nv_icmd(priv, 0x000009a0, 0x00000000); + nv_icmd(priv, 0x000009a1, 0x00000000); + nv_icmd(priv, 0x000009a2, 0x00000000); + nv_icmd(priv, 0x000009a3, 0x00000000); + nv_icmd(priv, 0x000009a4, 0x00000000); + nv_icmd(priv, 0x000009a5, 0x00000000); + nv_icmd(priv, 0x000009a6, 0x00000000); + nv_icmd(priv, 0x000009a7, 0x00000000); + nv_icmd(priv, 0x000009a8, 0x00000000); + nv_icmd(priv, 0x000009a9, 0x00000000); + nv_icmd(priv, 0x000009aa, 0x00000000); + nv_icmd(priv, 0x000009ab, 0x00000000); + nv_icmd(priv, 0x000009ac, 0x00000000); + nv_icmd(priv, 0x000009ad, 0x00000000); + nv_icmd(priv, 0x000009ae, 0x00000000); + nv_icmd(priv, 0x000009af, 0x00000000); + nv_icmd(priv, 0x000009b0, 0x00000000); + nv_icmd(priv, 0x000009b1, 0x00000000); + nv_icmd(priv, 0x000009b2, 0x00000000); + nv_icmd(priv, 0x000009b3, 0x00000000); + nv_icmd(priv, 0x000009b4, 0x00000000); + nv_icmd(priv, 0x000009b5, 0x00000000); + nv_icmd(priv, 0x000009b6, 0x00000000); + nv_icmd(priv, 0x000009b7, 0x00000000); + nv_icmd(priv, 0x000009b8, 0x00000000); + nv_icmd(priv, 0x000009b9, 0x00000000); + nv_icmd(priv, 0x000009ba, 0x00000000); + nv_icmd(priv, 0x000009bb, 0x00000000); + nv_icmd(priv, 0x000009bc, 0x00000000); + nv_icmd(priv, 0x000009bd, 0x00000000); + nv_icmd(priv, 0x000009be, 0x00000000); + nv_icmd(priv, 0x000009bf, 0x00000000); + nv_icmd(priv, 0x000009c0, 0x00000000); + nv_icmd(priv, 0x000009c1, 0x00000000); + nv_icmd(priv, 0x000009c2, 0x00000000); + nv_icmd(priv, 0x000009c3, 0x00000000); + nv_icmd(priv, 0x000009c4, 0x00000000); + nv_icmd(priv, 0x000009c5, 0x00000000); + nv_icmd(priv, 0x000009c6, 0x00000000); + nv_icmd(priv, 0x000009c7, 0x00000000); + nv_icmd(priv, 0x000009c8, 0x00000000); + nv_icmd(priv, 0x000009c9, 0x00000000); + nv_icmd(priv, 0x000009ca, 0x00000000); + nv_icmd(priv, 0x000009cb, 0x00000000); + nv_icmd(priv, 0x000009cc, 0x00000000); + nv_icmd(priv, 0x000009cd, 0x00000000); + nv_icmd(priv, 0x000009ce, 0x00000000); + nv_icmd(priv, 0x000009cf, 0x00000000); + nv_icmd(priv, 0x000009d0, 0x00000000); + nv_icmd(priv, 0x000009d1, 0x00000000); + nv_icmd(priv, 0x000009d2, 0x00000000); + nv_icmd(priv, 0x000009d3, 0x00000000); + nv_icmd(priv, 0x000009d4, 0x00000000); + nv_icmd(priv, 0x000009d5, 0x00000000); + nv_icmd(priv, 0x000009d6, 0x00000000); + nv_icmd(priv, 0x000009d7, 0x00000000); + nv_icmd(priv, 0x000009d8, 0x00000000); + nv_icmd(priv, 0x000009d9, 0x00000000); + nv_icmd(priv, 0x000009da, 0x00000000); + nv_icmd(priv, 0x000009db, 0x00000000); + nv_icmd(priv, 0x000009dc, 0x00000000); + nv_icmd(priv, 0x000009dd, 0x00000000); + nv_icmd(priv, 0x000009de, 0x00000000); + nv_icmd(priv, 0x000009df, 0x00000000); + nv_icmd(priv, 0x000009e0, 0x00000000); + nv_icmd(priv, 0x000009e1, 0x00000000); + nv_icmd(priv, 0x000009e2, 0x00000000); + nv_icmd(priv, 0x000009e3, 0x00000000); + nv_icmd(priv, 0x000009e4, 0x00000000); + nv_icmd(priv, 0x000009e5, 0x00000000); + nv_icmd(priv, 0x000009e6, 0x00000000); + nv_icmd(priv, 0x000009e7, 0x00000000); + nv_icmd(priv, 0x000009e8, 0x00000000); + nv_icmd(priv, 0x000009e9, 0x00000000); + nv_icmd(priv, 0x000009ea, 0x00000000); + nv_icmd(priv, 0x000009eb, 0x00000000); + nv_icmd(priv, 0x000009ec, 0x00000000); + nv_icmd(priv, 0x000009ed, 0x00000000); + nv_icmd(priv, 0x000009ee, 0x00000000); + nv_icmd(priv, 0x000009ef, 0x00000000); + nv_icmd(priv, 0x000009f0, 0x00000000); + nv_icmd(priv, 0x000009f1, 0x00000000); + nv_icmd(priv, 0x000009f2, 0x00000000); + nv_icmd(priv, 0x000009f3, 0x00000000); + nv_icmd(priv, 0x000009f4, 0x00000000); + nv_icmd(priv, 0x000009f5, 0x00000000); + nv_icmd(priv, 0x000009f6, 0x00000000); + nv_icmd(priv, 0x000009f7, 0x00000000); + nv_icmd(priv, 0x000009f8, 0x00000000); + nv_icmd(priv, 0x000009f9, 0x00000000); + nv_icmd(priv, 0x000009fa, 0x00000000); + nv_icmd(priv, 0x000009fb, 0x00000000); + nv_icmd(priv, 0x000009fc, 0x00000000); + nv_icmd(priv, 0x000009fd, 0x00000000); + nv_icmd(priv, 0x000009fe, 0x00000000); + nv_icmd(priv, 0x000009ff, 0x00000000); + nv_icmd(priv, 0x00000468, 0x00000004); + nv_icmd(priv, 0x0000046c, 0x00000001); + nv_icmd(priv, 0x00000470, 0x00000000); + nv_icmd(priv, 0x00000471, 0x00000000); + nv_icmd(priv, 0x00000472, 0x00000000); + nv_icmd(priv, 0x00000473, 0x00000000); + nv_icmd(priv, 0x00000474, 0x00000000); + nv_icmd(priv, 0x00000475, 0x00000000); + nv_icmd(priv, 0x00000476, 0x00000000); + nv_icmd(priv, 0x00000477, 0x00000000); + nv_icmd(priv, 0x00000478, 0x00000000); + nv_icmd(priv, 0x00000479, 0x00000000); + nv_icmd(priv, 0x0000047a, 0x00000000); + nv_icmd(priv, 0x0000047b, 0x00000000); + nv_icmd(priv, 0x0000047c, 0x00000000); + nv_icmd(priv, 0x0000047d, 0x00000000); + nv_icmd(priv, 0x0000047e, 0x00000000); + nv_icmd(priv, 0x0000047f, 0x00000000); + nv_icmd(priv, 0x00000480, 0x00000000); + nv_icmd(priv, 0x00000481, 0x00000000); + nv_icmd(priv, 0x00000482, 0x00000000); + nv_icmd(priv, 0x00000483, 0x00000000); + nv_icmd(priv, 0x00000484, 0x00000000); + nv_icmd(priv, 0x00000485, 0x00000000); + nv_icmd(priv, 0x00000486, 0x00000000); + nv_icmd(priv, 0x00000487, 0x00000000); + nv_icmd(priv, 0x00000488, 0x00000000); + nv_icmd(priv, 0x00000489, 0x00000000); + nv_icmd(priv, 0x0000048a, 0x00000000); + nv_icmd(priv, 0x0000048b, 0x00000000); + nv_icmd(priv, 0x0000048c, 0x00000000); + nv_icmd(priv, 0x0000048d, 0x00000000); + nv_icmd(priv, 0x0000048e, 0x00000000); + nv_icmd(priv, 0x0000048f, 0x00000000); + nv_icmd(priv, 0x00000490, 0x00000000); + nv_icmd(priv, 0x00000491, 0x00000000); + nv_icmd(priv, 0x00000492, 0x00000000); + nv_icmd(priv, 0x00000493, 0x00000000); + nv_icmd(priv, 0x00000494, 0x00000000); + nv_icmd(priv, 0x00000495, 0x00000000); + nv_icmd(priv, 0x00000496, 0x00000000); + nv_icmd(priv, 0x00000497, 0x00000000); + nv_icmd(priv, 0x00000498, 0x00000000); + nv_icmd(priv, 0x00000499, 0x00000000); + nv_icmd(priv, 0x0000049a, 0x00000000); + nv_icmd(priv, 0x0000049b, 0x00000000); + nv_icmd(priv, 0x0000049c, 0x00000000); + nv_icmd(priv, 0x0000049d, 0x00000000); + nv_icmd(priv, 0x0000049e, 0x00000000); + nv_icmd(priv, 0x0000049f, 0x00000000); + nv_icmd(priv, 0x000004a0, 0x00000000); + nv_icmd(priv, 0x000004a1, 0x00000000); + nv_icmd(priv, 0x000004a2, 0x00000000); + nv_icmd(priv, 0x000004a3, 0x00000000); + nv_icmd(priv, 0x000004a4, 0x00000000); + nv_icmd(priv, 0x000004a5, 0x00000000); + nv_icmd(priv, 0x000004a6, 0x00000000); + nv_icmd(priv, 0x000004a7, 0x00000000); + nv_icmd(priv, 0x000004a8, 0x00000000); + nv_icmd(priv, 0x000004a9, 0x00000000); + nv_icmd(priv, 0x000004aa, 0x00000000); + nv_icmd(priv, 0x000004ab, 0x00000000); + nv_icmd(priv, 0x000004ac, 0x00000000); + nv_icmd(priv, 0x000004ad, 0x00000000); + nv_icmd(priv, 0x000004ae, 0x00000000); + nv_icmd(priv, 0x000004af, 0x00000000); + nv_icmd(priv, 0x000004b0, 0x00000000); + nv_icmd(priv, 0x000004b1, 0x00000000); + nv_icmd(priv, 0x000004b2, 0x00000000); + nv_icmd(priv, 0x000004b3, 0x00000000); + nv_icmd(priv, 0x000004b4, 0x00000000); + nv_icmd(priv, 0x000004b5, 0x00000000); + nv_icmd(priv, 0x000004b6, 0x00000000); + nv_icmd(priv, 0x000004b7, 0x00000000); + nv_icmd(priv, 0x000004b8, 0x00000000); + nv_icmd(priv, 0x000004b9, 0x00000000); + nv_icmd(priv, 0x000004ba, 0x00000000); + nv_icmd(priv, 0x000004bb, 0x00000000); + nv_icmd(priv, 0x000004bc, 0x00000000); + nv_icmd(priv, 0x000004bd, 0x00000000); + nv_icmd(priv, 0x000004be, 0x00000000); + nv_icmd(priv, 0x000004bf, 0x00000000); + nv_icmd(priv, 0x000004c0, 0x00000000); + nv_icmd(priv, 0x000004c1, 0x00000000); + nv_icmd(priv, 0x000004c2, 0x00000000); + nv_icmd(priv, 0x000004c3, 0x00000000); + nv_icmd(priv, 0x000004c4, 0x00000000); + nv_icmd(priv, 0x000004c5, 0x00000000); + nv_icmd(priv, 0x000004c6, 0x00000000); + nv_icmd(priv, 0x000004c7, 0x00000000); + nv_icmd(priv, 0x000004c8, 0x00000000); + nv_icmd(priv, 0x000004c9, 0x00000000); + nv_icmd(priv, 0x000004ca, 0x00000000); + nv_icmd(priv, 0x000004cb, 0x00000000); + nv_icmd(priv, 0x000004cc, 0x00000000); + nv_icmd(priv, 0x000004cd, 0x00000000); + nv_icmd(priv, 0x000004ce, 0x00000000); + nv_icmd(priv, 0x000004cf, 0x00000000); + nv_icmd(priv, 0x00000510, 0x3f800000); + nv_icmd(priv, 0x00000511, 0x3f800000); + nv_icmd(priv, 0x00000512, 0x3f800000); + nv_icmd(priv, 0x00000513, 0x3f800000); + nv_icmd(priv, 0x00000514, 0x3f800000); + nv_icmd(priv, 0x00000515, 0x3f800000); + nv_icmd(priv, 0x00000516, 0x3f800000); + nv_icmd(priv, 0x00000517, 0x3f800000); + nv_icmd(priv, 0x00000518, 0x3f800000); + nv_icmd(priv, 0x00000519, 0x3f800000); + nv_icmd(priv, 0x0000051a, 0x3f800000); + nv_icmd(priv, 0x0000051b, 0x3f800000); + nv_icmd(priv, 0x0000051c, 0x3f800000); + nv_icmd(priv, 0x0000051d, 0x3f800000); + nv_icmd(priv, 0x0000051e, 0x3f800000); + nv_icmd(priv, 0x0000051f, 0x3f800000); + nv_icmd(priv, 0x00000520, 0x000002b6); + nv_icmd(priv, 0x00000529, 0x00000001); + nv_icmd(priv, 0x00000530, 0xffff0000); + nv_icmd(priv, 0x00000531, 0xffff0000); + nv_icmd(priv, 0x00000532, 0xffff0000); + nv_icmd(priv, 0x00000533, 0xffff0000); + nv_icmd(priv, 0x00000534, 0xffff0000); + nv_icmd(priv, 0x00000535, 0xffff0000); + nv_icmd(priv, 0x00000536, 0xffff0000); + nv_icmd(priv, 0x00000537, 0xffff0000); + nv_icmd(priv, 0x00000538, 0xffff0000); + nv_icmd(priv, 0x00000539, 0xffff0000); + nv_icmd(priv, 0x0000053a, 0xffff0000); + nv_icmd(priv, 0x0000053b, 0xffff0000); + nv_icmd(priv, 0x0000053c, 0xffff0000); + nv_icmd(priv, 0x0000053d, 0xffff0000); + nv_icmd(priv, 0x0000053e, 0xffff0000); + nv_icmd(priv, 0x0000053f, 0xffff0000); + nv_icmd(priv, 0x00000585, 0x0000003f); + nv_icmd(priv, 0x00000576, 0x00000003); + if (nv_device(priv)->chipset == 0xc1 || + nv_device(priv)->chipset == 0xd9) + nv_icmd(priv, 0x0000057b, 0x00000059); + nv_icmd(priv, 0x00000586, 0x00000040); + nv_icmd(priv, 0x00000582, 0x00000080); + nv_icmd(priv, 0x00000583, 0x00000080); + nv_icmd(priv, 0x000005c2, 0x00000001); + nv_icmd(priv, 0x00000638, 0x00000001); + nv_icmd(priv, 0x00000639, 0x00000001); + nv_icmd(priv, 0x0000063a, 0x00000002); + nv_icmd(priv, 0x0000063b, 0x00000001); + nv_icmd(priv, 0x0000063c, 0x00000001); + nv_icmd(priv, 0x0000063d, 0x00000002); + nv_icmd(priv, 0x0000063e, 0x00000001); + nv_icmd(priv, 0x000008b8, 0x00000001); + nv_icmd(priv, 0x000008b9, 0x00000001); + nv_icmd(priv, 0x000008ba, 0x00000001); + nv_icmd(priv, 0x000008bb, 0x00000001); + nv_icmd(priv, 0x000008bc, 0x00000001); + nv_icmd(priv, 0x000008bd, 0x00000001); + nv_icmd(priv, 0x000008be, 0x00000001); + nv_icmd(priv, 0x000008bf, 0x00000001); + nv_icmd(priv, 0x00000900, 0x00000001); + nv_icmd(priv, 0x00000901, 0x00000001); + nv_icmd(priv, 0x00000902, 0x00000001); + nv_icmd(priv, 0x00000903, 0x00000001); + nv_icmd(priv, 0x00000904, 0x00000001); + nv_icmd(priv, 0x00000905, 0x00000001); + nv_icmd(priv, 0x00000906, 0x00000001); + nv_icmd(priv, 0x00000907, 0x00000001); + nv_icmd(priv, 0x00000908, 0x00000002); + nv_icmd(priv, 0x00000909, 0x00000002); + nv_icmd(priv, 0x0000090a, 0x00000002); + nv_icmd(priv, 0x0000090b, 0x00000002); + nv_icmd(priv, 0x0000090c, 0x00000002); + nv_icmd(priv, 0x0000090d, 0x00000002); + nv_icmd(priv, 0x0000090e, 0x00000002); + nv_icmd(priv, 0x0000090f, 0x00000002); + nv_icmd(priv, 0x00000910, 0x00000001); + nv_icmd(priv, 0x00000911, 0x00000001); + nv_icmd(priv, 0x00000912, 0x00000001); + nv_icmd(priv, 0x00000913, 0x00000001); + nv_icmd(priv, 0x00000914, 0x00000001); + nv_icmd(priv, 0x00000915, 0x00000001); + nv_icmd(priv, 0x00000916, 0x00000001); + nv_icmd(priv, 0x00000917, 0x00000001); + nv_icmd(priv, 0x00000918, 0x00000001); + nv_icmd(priv, 0x00000919, 0x00000001); + nv_icmd(priv, 0x0000091a, 0x00000001); + nv_icmd(priv, 0x0000091b, 0x00000001); + nv_icmd(priv, 0x0000091c, 0x00000001); + nv_icmd(priv, 0x0000091d, 0x00000001); + nv_icmd(priv, 0x0000091e, 0x00000001); + nv_icmd(priv, 0x0000091f, 0x00000001); + nv_icmd(priv, 0x00000920, 0x00000002); + nv_icmd(priv, 0x00000921, 0x00000002); + nv_icmd(priv, 0x00000922, 0x00000002); + nv_icmd(priv, 0x00000923, 0x00000002); + nv_icmd(priv, 0x00000924, 0x00000002); + nv_icmd(priv, 0x00000925, 0x00000002); + nv_icmd(priv, 0x00000926, 0x00000002); + nv_icmd(priv, 0x00000927, 0x00000002); + nv_icmd(priv, 0x00000928, 0x00000001); + nv_icmd(priv, 0x00000929, 0x00000001); + nv_icmd(priv, 0x0000092a, 0x00000001); + nv_icmd(priv, 0x0000092b, 0x00000001); + nv_icmd(priv, 0x0000092c, 0x00000001); + nv_icmd(priv, 0x0000092d, 0x00000001); + nv_icmd(priv, 0x0000092e, 0x00000001); + nv_icmd(priv, 0x0000092f, 0x00000001); + nv_icmd(priv, 0x00000648, 0x00000001); + nv_icmd(priv, 0x00000649, 0x00000001); + nv_icmd(priv, 0x0000064a, 0x00000001); + nv_icmd(priv, 0x0000064b, 0x00000001); + nv_icmd(priv, 0x0000064c, 0x00000001); + nv_icmd(priv, 0x0000064d, 0x00000001); + nv_icmd(priv, 0x0000064e, 0x00000001); + nv_icmd(priv, 0x0000064f, 0x00000001); + nv_icmd(priv, 0x00000650, 0x00000001); + nv_icmd(priv, 0x00000658, 0x0000000f); + nv_icmd(priv, 0x000007ff, 0x0000000a); + nv_icmd(priv, 0x0000066a, 0x40000000); + nv_icmd(priv, 0x0000066b, 0x10000000); + nv_icmd(priv, 0x0000066c, 0xffff0000); + nv_icmd(priv, 0x0000066d, 0xffff0000); + nv_icmd(priv, 0x000007af, 0x00000008); + nv_icmd(priv, 0x000007b0, 0x00000008); + nv_icmd(priv, 0x000007f6, 0x00000001); + nv_icmd(priv, 0x000006b2, 0x00000055); + nv_icmd(priv, 0x000007ad, 0x00000003); + nv_icmd(priv, 0x00000937, 0x00000001); + nv_icmd(priv, 0x00000971, 0x00000008); + nv_icmd(priv, 0x00000972, 0x00000040); + nv_icmd(priv, 0x00000973, 0x0000012c); + nv_icmd(priv, 0x0000097c, 0x00000040); + nv_icmd(priv, 0x00000979, 0x00000003); + nv_icmd(priv, 0x00000975, 0x00000020); + nv_icmd(priv, 0x00000976, 0x00000001); + nv_icmd(priv, 0x00000977, 0x00000020); + nv_icmd(priv, 0x00000978, 0x00000001); + nv_icmd(priv, 0x00000957, 0x00000003); + nv_icmd(priv, 0x0000095e, 0x20164010); + nv_icmd(priv, 0x0000095f, 0x00000020); + if (nv_device(priv)->chipset == 0xd9) + nv_icmd(priv, 0x0000097d, 0x00000020); + nv_icmd(priv, 0x00000683, 0x00000006); + nv_icmd(priv, 0x00000685, 0x003fffff); + nv_icmd(priv, 0x00000687, 0x00000c48); + nv_icmd(priv, 0x000006a0, 0x00000005); + nv_icmd(priv, 0x00000840, 0x00300008); + nv_icmd(priv, 0x00000841, 0x04000080); + nv_icmd(priv, 0x00000842, 0x00300008); + nv_icmd(priv, 0x00000843, 0x04000080); + nv_icmd(priv, 0x00000818, 0x00000000); + nv_icmd(priv, 0x00000819, 0x00000000); + nv_icmd(priv, 0x0000081a, 0x00000000); + nv_icmd(priv, 0x0000081b, 0x00000000); + nv_icmd(priv, 0x0000081c, 0x00000000); + nv_icmd(priv, 0x0000081d, 0x00000000); + nv_icmd(priv, 0x0000081e, 0x00000000); + nv_icmd(priv, 0x0000081f, 0x00000000); + nv_icmd(priv, 0x00000848, 0x00000000); + nv_icmd(priv, 0x00000849, 0x00000000); + nv_icmd(priv, 0x0000084a, 0x00000000); + nv_icmd(priv, 0x0000084b, 0x00000000); + nv_icmd(priv, 0x0000084c, 0x00000000); + nv_icmd(priv, 0x0000084d, 0x00000000); + nv_icmd(priv, 0x0000084e, 0x00000000); + nv_icmd(priv, 0x0000084f, 0x00000000); + nv_icmd(priv, 0x00000850, 0x00000000); + nv_icmd(priv, 0x00000851, 0x00000000); + nv_icmd(priv, 0x00000852, 0x00000000); + nv_icmd(priv, 0x00000853, 0x00000000); + nv_icmd(priv, 0x00000854, 0x00000000); + nv_icmd(priv, 0x00000855, 0x00000000); + nv_icmd(priv, 0x00000856, 0x00000000); + nv_icmd(priv, 0x00000857, 0x00000000); + nv_icmd(priv, 0x00000738, 0x00000000); + nv_icmd(priv, 0x000006aa, 0x00000001); + nv_icmd(priv, 0x000006ab, 0x00000002); + nv_icmd(priv, 0x000006ac, 0x00000080); + nv_icmd(priv, 0x000006ad, 0x00000100); + nv_icmd(priv, 0x000006ae, 0x00000100); + nv_icmd(priv, 0x000006b1, 0x00000011); + nv_icmd(priv, 0x000006bb, 0x000000cf); + nv_icmd(priv, 0x000006ce, 0x2a712488); + nv_icmd(priv, 0x00000739, 0x4085c000); + nv_icmd(priv, 0x0000073a, 0x00000080); + nv_icmd(priv, 0x00000786, 0x80000100); + nv_icmd(priv, 0x0000073c, 0x00010100); + nv_icmd(priv, 0x0000073d, 0x02800000); + nv_icmd(priv, 0x00000787, 0x000000cf); + nv_icmd(priv, 0x0000078c, 0x00000008); + nv_icmd(priv, 0x00000792, 0x00000001); + nv_icmd(priv, 0x00000794, 0x00000001); + nv_icmd(priv, 0x00000795, 0x00000001); + nv_icmd(priv, 0x00000796, 0x00000001); + nv_icmd(priv, 0x00000797, 0x000000cf); + nv_icmd(priv, 0x00000836, 0x00000001); + nv_icmd(priv, 0x0000079a, 0x00000002); + nv_icmd(priv, 0x00000833, 0x04444480); + nv_icmd(priv, 0x000007a1, 0x00000001); + nv_icmd(priv, 0x000007a3, 0x00000001); + nv_icmd(priv, 0x000007a4, 0x00000001); + nv_icmd(priv, 0x000007a5, 0x00000001); + nv_icmd(priv, 0x00000831, 0x00000004); + nv_icmd(priv, 0x0000080c, 0x00000002); + nv_icmd(priv, 0x0000080d, 0x00000100); + nv_icmd(priv, 0x0000080e, 0x00000100); + nv_icmd(priv, 0x0000080f, 0x00000001); + nv_icmd(priv, 0x00000823, 0x00000002); + nv_icmd(priv, 0x00000824, 0x00000100); + nv_icmd(priv, 0x00000825, 0x00000100); + nv_icmd(priv, 0x00000826, 0x00000001); + nv_icmd(priv, 0x0000095d, 0x00000001); + nv_icmd(priv, 0x0000082b, 0x00000004); + nv_icmd(priv, 0x00000942, 0x00010001); + nv_icmd(priv, 0x00000943, 0x00000001); + nv_icmd(priv, 0x00000944, 0x00000022); + nv_icmd(priv, 0x000007c5, 0x00010001); + nv_icmd(priv, 0x00000834, 0x00000001); + nv_icmd(priv, 0x000007c7, 0x00000001); + nv_icmd(priv, 0x0000c1b0, 0x0000000f); + nv_icmd(priv, 0x0000c1b1, 0x0000000f); + nv_icmd(priv, 0x0000c1b2, 0x0000000f); + nv_icmd(priv, 0x0000c1b3, 0x0000000f); + nv_icmd(priv, 0x0000c1b4, 0x0000000f); + nv_icmd(priv, 0x0000c1b5, 0x0000000f); + nv_icmd(priv, 0x0000c1b6, 0x0000000f); + nv_icmd(priv, 0x0000c1b7, 0x0000000f); + nv_icmd(priv, 0x0000c1b8, 0x0fac6881); + nv_icmd(priv, 0x0000c1b9, 0x00fac688); + nv_icmd(priv, 0x0001e100, 0x00000001); + nv_icmd(priv, 0x00001000, 0x00000002); + nv_icmd(priv, 0x000006aa, 0x00000001); + nv_icmd(priv, 0x000006ad, 0x00000100); + nv_icmd(priv, 0x000006ae, 0x00000100); + nv_icmd(priv, 0x000006b1, 0x00000011); + nv_icmd(priv, 0x0000078c, 0x00000008); + nv_icmd(priv, 0x00000792, 0x00000001); + nv_icmd(priv, 0x00000794, 0x00000001); + nv_icmd(priv, 0x00000795, 0x00000001); + nv_icmd(priv, 0x00000796, 0x00000001); + nv_icmd(priv, 0x00000797, 0x000000cf); + nv_icmd(priv, 0x0000079a, 0x00000002); + nv_icmd(priv, 0x00000833, 0x04444480); + nv_icmd(priv, 0x000007a1, 0x00000001); + nv_icmd(priv, 0x000007a3, 0x00000001); + nv_icmd(priv, 0x000007a4, 0x00000001); + nv_icmd(priv, 0x000007a5, 0x00000001); + nv_icmd(priv, 0x00000831, 0x00000004); + nv_icmd(priv, 0x0001e100, 0x00000001); + nv_icmd(priv, 0x00001000, 0x00000014); + nv_icmd(priv, 0x00000351, 0x00000100); + nv_icmd(priv, 0x00000957, 0x00000003); + nv_icmd(priv, 0x0000095d, 0x00000001); + nv_icmd(priv, 0x0000082b, 0x00000004); + nv_icmd(priv, 0x00000942, 0x00010001); + nv_icmd(priv, 0x00000943, 0x00000001); + nv_icmd(priv, 0x000007c5, 0x00010001); + nv_icmd(priv, 0x00000834, 0x00000001); + nv_icmd(priv, 0x000007c7, 0x00000001); + nv_icmd(priv, 0x0001e100, 0x00000001); + nv_icmd(priv, 0x00001000, 0x00000001); + nv_icmd(priv, 0x0000080c, 0x00000002); + nv_icmd(priv, 0x0000080d, 0x00000100); + nv_icmd(priv, 0x0000080e, 0x00000100); + nv_icmd(priv, 0x0000080f, 0x00000001); + nv_icmd(priv, 0x00000823, 0x00000002); + nv_icmd(priv, 0x00000824, 0x00000100); + nv_icmd(priv, 0x00000825, 0x00000100); + nv_icmd(priv, 0x00000826, 0x00000001); + nv_icmd(priv, 0x0001e100, 0x00000001); + nv_wr32(priv, 0x400208, 0x00000000); + nv_wr32(priv, 0x404154, 0x00000400); + + nvc0_grctx_generate_9097(priv); + if (fermi >= 0x9197) + nvc0_grctx_generate_9197(priv); + if (fermi >= 0x9297) + nvc0_grctx_generate_9297(priv); + nvc0_grctx_generate_902d(priv); + nvc0_grctx_generate_9039(priv); + nvc0_grctx_generate_90c0(priv); + + nv_wr32(priv, 0x000260, r000260); + + return nvc0_grctx_fini(&info); +} diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c new file mode 100644 index 00000000000..6d8c63931ee --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c @@ -0,0 +1,2788 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nvc0.h" + +static void +nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x400208, 0x80000000); + nv_icmd(priv, 0x001000, 0x00000004); + nv_icmd(priv, 0x000039, 0x00000000); + nv_icmd(priv, 0x00003a, 0x00000000); + nv_icmd(priv, 0x00003b, 0x00000000); + nv_icmd(priv, 0x0000a9, 0x0000ffff); + nv_icmd(priv, 0x000038, 0x0fac6881); + nv_icmd(priv, 0x00003d, 0x00000001); + nv_icmd(priv, 0x0000e8, 0x00000400); + nv_icmd(priv, 0x0000e9, 0x00000400); + nv_icmd(priv, 0x0000ea, 0x00000400); + nv_icmd(priv, 0x0000eb, 0x00000400); + nv_icmd(priv, 0x0000ec, 0x00000400); + nv_icmd(priv, 0x0000ed, 0x00000400); + nv_icmd(priv, 0x0000ee, 0x00000400); + nv_icmd(priv, 0x0000ef, 0x00000400); + nv_icmd(priv, 0x000078, 0x00000300); + nv_icmd(priv, 0x000079, 0x00000300); + nv_icmd(priv, 0x00007a, 0x00000300); + nv_icmd(priv, 0x00007b, 0x00000300); + nv_icmd(priv, 0x00007c, 0x00000300); + nv_icmd(priv, 0x00007d, 0x00000300); + nv_icmd(priv, 0x00007e, 0x00000300); + nv_icmd(priv, 0x00007f, 0x00000300); + nv_icmd(priv, 0x000050, 0x00000011); + nv_icmd(priv, 0x000058, 0x00000008); + nv_icmd(priv, 0x000059, 0x00000008); + nv_icmd(priv, 0x00005a, 0x00000008); + nv_icmd(priv, 0x00005b, 0x00000008); + nv_icmd(priv, 0x00005c, 0x00000008); + nv_icmd(priv, 0x00005d, 0x00000008); + nv_icmd(priv, 0x00005e, 0x00000008); + nv_icmd(priv, 0x00005f, 0x00000008); + nv_icmd(priv, 0x000208, 0x00000001); + nv_icmd(priv, 0x000209, 0x00000001); + nv_icmd(priv, 0x00020a, 0x00000001); + nv_icmd(priv, 0x00020b, 0x00000001); + nv_icmd(priv, 0x00020c, 0x00000001); + nv_icmd(priv, 0x00020d, 0x00000001); + nv_icmd(priv, 0x00020e, 0x00000001); + nv_icmd(priv, 0x00020f, 0x00000001); + nv_icmd(priv, 0x000081, 0x00000001); + nv_icmd(priv, 0x000085, 0x00000004); + nv_icmd(priv, 0x000088, 0x00000400); + nv_icmd(priv, 0x000090, 0x00000300); + nv_icmd(priv, 0x000098, 0x00001001); + nv_icmd(priv, 0x0000e3, 0x00000001); + nv_icmd(priv, 0x0000da, 0x00000001); + nv_icmd(priv, 0x0000f8, 0x00000003); + nv_icmd(priv, 0x0000fa, 0x00000001); + nv_icmd(priv, 0x00009f, 0x0000ffff); + nv_icmd(priv, 0x0000a0, 0x0000ffff); + nv_icmd(priv, 0x0000a1, 0x0000ffff); + nv_icmd(priv, 0x0000a2, 0x0000ffff); + nv_icmd(priv, 0x0000b1, 0x00000001); + nv_icmd(priv, 0x0000ad, 0x0000013e); + nv_icmd(priv, 0x0000e1, 0x00000010); + nv_icmd(priv, 0x000290, 0x00000000); + nv_icmd(priv, 0x000291, 0x00000000); + nv_icmd(priv, 0x000292, 0x00000000); + nv_icmd(priv, 0x000293, 0x00000000); + nv_icmd(priv, 0x000294, 0x00000000); + nv_icmd(priv, 0x000295, 0x00000000); + nv_icmd(priv, 0x000296, 0x00000000); + nv_icmd(priv, 0x000297, 0x00000000); + nv_icmd(priv, 0x000298, 0x00000000); + nv_icmd(priv, 0x000299, 0x00000000); + nv_icmd(priv, 0x00029a, 0x00000000); + nv_icmd(priv, 0x00029b, 0x00000000); + nv_icmd(priv, 0x00029c, 0x00000000); + nv_icmd(priv, 0x00029d, 0x00000000); + nv_icmd(priv, 0x00029e, 0x00000000); + nv_icmd(priv, 0x00029f, 0x00000000); + nv_icmd(priv, 0x0003b0, 0x00000000); + nv_icmd(priv, 0x0003b1, 0x00000000); + nv_icmd(priv, 0x0003b2, 0x00000000); + nv_icmd(priv, 0x0003b3, 0x00000000); + nv_icmd(priv, 0x0003b4, 0x00000000); + nv_icmd(priv, 0x0003b5, 0x00000000); + nv_icmd(priv, 0x0003b6, 0x00000000); + nv_icmd(priv, 0x0003b7, 0x00000000); + nv_icmd(priv, 0x0003b8, 0x00000000); + nv_icmd(priv, 0x0003b9, 0x00000000); + nv_icmd(priv, 0x0003ba, 0x00000000); + nv_icmd(priv, 0x0003bb, 0x00000000); + nv_icmd(priv, 0x0003bc, 0x00000000); + nv_icmd(priv, 0x0003bd, 0x00000000); + nv_icmd(priv, 0x0003be, 0x00000000); + nv_icmd(priv, 0x0003bf, 0x00000000); + nv_icmd(priv, 0x0002a0, 0x00000000); + nv_icmd(priv, 0x0002a1, 0x00000000); + nv_icmd(priv, 0x0002a2, 0x00000000); + nv_icmd(priv, 0x0002a3, 0x00000000); + nv_icmd(priv, 0x0002a4, 0x00000000); + nv_icmd(priv, 0x0002a5, 0x00000000); + nv_icmd(priv, 0x0002a6, 0x00000000); + nv_icmd(priv, 0x0002a7, 0x00000000); + nv_icmd(priv, 0x0002a8, 0x00000000); + nv_icmd(priv, 0x0002a9, 0x00000000); + nv_icmd(priv, 0x0002aa, 0x00000000); + nv_icmd(priv, 0x0002ab, 0x00000000); + nv_icmd(priv, 0x0002ac, 0x00000000); + nv_icmd(priv, 0x0002ad, 0x00000000); + nv_icmd(priv, 0x0002ae, 0x00000000); + nv_icmd(priv, 0x0002af, 0x00000000); + nv_icmd(priv, 0x000420, 0x00000000); + nv_icmd(priv, 0x000421, 0x00000000); + nv_icmd(priv, 0x000422, 0x00000000); + nv_icmd(priv, 0x000423, 0x00000000); + nv_icmd(priv, 0x000424, 0x00000000); + nv_icmd(priv, 0x000425, 0x00000000); + nv_icmd(priv, 0x000426, 0x00000000); + nv_icmd(priv, 0x000427, 0x00000000); + nv_icmd(priv, 0x000428, 0x00000000); + nv_icmd(priv, 0x000429, 0x00000000); + nv_icmd(priv, 0x00042a, 0x00000000); + nv_icmd(priv, 0x00042b, 0x00000000); + nv_icmd(priv, 0x00042c, 0x00000000); + nv_icmd(priv, 0x00042d, 0x00000000); + nv_icmd(priv, 0x00042e, 0x00000000); + nv_icmd(priv, 0x00042f, 0x00000000); + nv_icmd(priv, 0x0002b0, 0x00000000); + nv_icmd(priv, 0x0002b1, 0x00000000); + nv_icmd(priv, 0x0002b2, 0x00000000); + nv_icmd(priv, 0x0002b3, 0x00000000); + nv_icmd(priv, 0x0002b4, 0x00000000); + nv_icmd(priv, 0x0002b5, 0x00000000); + nv_icmd(priv, 0x0002b6, 0x00000000); + nv_icmd(priv, 0x0002b7, 0x00000000); + nv_icmd(priv, 0x0002b8, 0x00000000); + nv_icmd(priv, 0x0002b9, 0x00000000); + nv_icmd(priv, 0x0002ba, 0x00000000); + nv_icmd(priv, 0x0002bb, 0x00000000); + nv_icmd(priv, 0x0002bc, 0x00000000); + nv_icmd(priv, 0x0002bd, 0x00000000); + nv_icmd(priv, 0x0002be, 0x00000000); + nv_icmd(priv, 0x0002bf, 0x00000000); + nv_icmd(priv, 0x000430, 0x00000000); + nv_icmd(priv, 0x000431, 0x00000000); + nv_icmd(priv, 0x000432, 0x00000000); + nv_icmd(priv, 0x000433, 0x00000000); + nv_icmd(priv, 0x000434, 0x00000000); + nv_icmd(priv, 0x000435, 0x00000000); + nv_icmd(priv, 0x000436, 0x00000000); + nv_icmd(priv, 0x000437, 0x00000000); + nv_icmd(priv, 0x000438, 0x00000000); + nv_icmd(priv, 0x000439, 0x00000000); + nv_icmd(priv, 0x00043a, 0x00000000); + nv_icmd(priv, 0x00043b, 0x00000000); + nv_icmd(priv, 0x00043c, 0x00000000); + nv_icmd(priv, 0x00043d, 0x00000000); + nv_icmd(priv, 0x00043e, 0x00000000); + nv_icmd(priv, 0x00043f, 0x00000000); + nv_icmd(priv, 0x0002c0, 0x00000000); + nv_icmd(priv, 0x0002c1, 0x00000000); + nv_icmd(priv, 0x0002c2, 0x00000000); + nv_icmd(priv, 0x0002c3, 0x00000000); + nv_icmd(priv, 0x0002c4, 0x00000000); + nv_icmd(priv, 0x0002c5, 0x00000000); + nv_icmd(priv, 0x0002c6, 0x00000000); + nv_icmd(priv, 0x0002c7, 0x00000000); + nv_icmd(priv, 0x0002c8, 0x00000000); + nv_icmd(priv, 0x0002c9, 0x00000000); + nv_icmd(priv, 0x0002ca, 0x00000000); + nv_icmd(priv, 0x0002cb, 0x00000000); + nv_icmd(priv, 0x0002cc, 0x00000000); + nv_icmd(priv, 0x0002cd, 0x00000000); + nv_icmd(priv, 0x0002ce, 0x00000000); + nv_icmd(priv, 0x0002cf, 0x00000000); + nv_icmd(priv, 0x0004d0, 0x00000000); + nv_icmd(priv, 0x0004d1, 0x00000000); + nv_icmd(priv, 0x0004d2, 0x00000000); + nv_icmd(priv, 0x0004d3, 0x00000000); + nv_icmd(priv, 0x0004d4, 0x00000000); + nv_icmd(priv, 0x0004d5, 0x00000000); + nv_icmd(priv, 0x0004d6, 0x00000000); + nv_icmd(priv, 0x0004d7, 0x00000000); + nv_icmd(priv, 0x0004d8, 0x00000000); + nv_icmd(priv, 0x0004d9, 0x00000000); + nv_icmd(priv, 0x0004da, 0x00000000); + nv_icmd(priv, 0x0004db, 0x00000000); + nv_icmd(priv, 0x0004dc, 0x00000000); + nv_icmd(priv, 0x0004dd, 0x00000000); + nv_icmd(priv, 0x0004de, 0x00000000); + nv_icmd(priv, 0x0004df, 0x00000000); + nv_icmd(priv, 0x000720, 0x00000000); + nv_icmd(priv, 0x000721, 0x00000000); + nv_icmd(priv, 0x000722, 0x00000000); + nv_icmd(priv, 0x000723, 0x00000000); + nv_icmd(priv, 0x000724, 0x00000000); + nv_icmd(priv, 0x000725, 0x00000000); + nv_icmd(priv, 0x000726, 0x00000000); + nv_icmd(priv, 0x000727, 0x00000000); + nv_icmd(priv, 0x000728, 0x00000000); + nv_icmd(priv, 0x000729, 0x00000000); + nv_icmd(priv, 0x00072a, 0x00000000); + nv_icmd(priv, 0x00072b, 0x00000000); + nv_icmd(priv, 0x00072c, 0x00000000); + nv_icmd(priv, 0x00072d, 0x00000000); + nv_icmd(priv, 0x00072e, 0x00000000); + nv_icmd(priv, 0x00072f, 0x00000000); + nv_icmd(priv, 0x0008c0, 0x00000000); + nv_icmd(priv, 0x0008c1, 0x00000000); + nv_icmd(priv, 0x0008c2, 0x00000000); + nv_icmd(priv, 0x0008c3, 0x00000000); + nv_icmd(priv, 0x0008c4, 0x00000000); + nv_icmd(priv, 0x0008c5, 0x00000000); + nv_icmd(priv, 0x0008c6, 0x00000000); + nv_icmd(priv, 0x0008c7, 0x00000000); + nv_icmd(priv, 0x0008c8, 0x00000000); + nv_icmd(priv, 0x0008c9, 0x00000000); + nv_icmd(priv, 0x0008ca, 0x00000000); + nv_icmd(priv, 0x0008cb, 0x00000000); + nv_icmd(priv, 0x0008cc, 0x00000000); + nv_icmd(priv, 0x0008cd, 0x00000000); + nv_icmd(priv, 0x0008ce, 0x00000000); + nv_icmd(priv, 0x0008cf, 0x00000000); + nv_icmd(priv, 0x000890, 0x00000000); + nv_icmd(priv, 0x000891, 0x00000000); + nv_icmd(priv, 0x000892, 0x00000000); + nv_icmd(priv, 0x000893, 0x00000000); + nv_icmd(priv, 0x000894, 0x00000000); + nv_icmd(priv, 0x000895, 0x00000000); + nv_icmd(priv, 0x000896, 0x00000000); + nv_icmd(priv, 0x000897, 0x00000000); + nv_icmd(priv, 0x000898, 0x00000000); + nv_icmd(priv, 0x000899, 0x00000000); + nv_icmd(priv, 0x00089a, 0x00000000); + nv_icmd(priv, 0x00089b, 0x00000000); + nv_icmd(priv, 0x00089c, 0x00000000); + nv_icmd(priv, 0x00089d, 0x00000000); + nv_icmd(priv, 0x00089e, 0x00000000); + nv_icmd(priv, 0x00089f, 0x00000000); + nv_icmd(priv, 0x0008e0, 0x00000000); + nv_icmd(priv, 0x0008e1, 0x00000000); + nv_icmd(priv, 0x0008e2, 0x00000000); + nv_icmd(priv, 0x0008e3, 0x00000000); + nv_icmd(priv, 0x0008e4, 0x00000000); + nv_icmd(priv, 0x0008e5, 0x00000000); + nv_icmd(priv, 0x0008e6, 0x00000000); + nv_icmd(priv, 0x0008e7, 0x00000000); + nv_icmd(priv, 0x0008e8, 0x00000000); + nv_icmd(priv, 0x0008e9, 0x00000000); + nv_icmd(priv, 0x0008ea, 0x00000000); + nv_icmd(priv, 0x0008eb, 0x00000000); + nv_icmd(priv, 0x0008ec, 0x00000000); + nv_icmd(priv, 0x0008ed, 0x00000000); + nv_icmd(priv, 0x0008ee, 0x00000000); + nv_icmd(priv, 0x0008ef, 0x00000000); + nv_icmd(priv, 0x0008a0, 0x00000000); + nv_icmd(priv, 0x0008a1, 0x00000000); + nv_icmd(priv, 0x0008a2, 0x00000000); + nv_icmd(priv, 0x0008a3, 0x00000000); + nv_icmd(priv, 0x0008a4, 0x00000000); + nv_icmd(priv, 0x0008a5, 0x00000000); + nv_icmd(priv, 0x0008a6, 0x00000000); + nv_icmd(priv, 0x0008a7, 0x00000000); + nv_icmd(priv, 0x0008a8, 0x00000000); + nv_icmd(priv, 0x0008a9, 0x00000000); + nv_icmd(priv, 0x0008aa, 0x00000000); + nv_icmd(priv, 0x0008ab, 0x00000000); + nv_icmd(priv, 0x0008ac, 0x00000000); + nv_icmd(priv, 0x0008ad, 0x00000000); + nv_icmd(priv, 0x0008ae, 0x00000000); + nv_icmd(priv, 0x0008af, 0x00000000); + nv_icmd(priv, 0x0008f0, 0x00000000); + nv_icmd(priv, 0x0008f1, 0x00000000); + nv_icmd(priv, 0x0008f2, 0x00000000); + nv_icmd(priv, 0x0008f3, 0x00000000); + nv_icmd(priv, 0x0008f4, 0x00000000); + nv_icmd(priv, 0x0008f5, 0x00000000); + nv_icmd(priv, 0x0008f6, 0x00000000); + nv_icmd(priv, 0x0008f7, 0x00000000); + nv_icmd(priv, 0x0008f8, 0x00000000); + nv_icmd(priv, 0x0008f9, 0x00000000); + nv_icmd(priv, 0x0008fa, 0x00000000); + nv_icmd(priv, 0x0008fb, 0x00000000); + nv_icmd(priv, 0x0008fc, 0x00000000); + nv_icmd(priv, 0x0008fd, 0x00000000); + nv_icmd(priv, 0x0008fe, 0x00000000); + nv_icmd(priv, 0x0008ff, 0x00000000); + nv_icmd(priv, 0x00094c, 0x000000ff); + nv_icmd(priv, 0x00094d, 0xffffffff); + nv_icmd(priv, 0x00094e, 0x00000002); + nv_icmd(priv, 0x0002ec, 0x00000001); + nv_icmd(priv, 0x000303, 0x00000001); + nv_icmd(priv, 0x0002e6, 0x00000001); + nv_icmd(priv, 0x000466, 0x00000052); + nv_icmd(priv, 0x000301, 0x3f800000); + nv_icmd(priv, 0x000304, 0x30201000); + nv_icmd(priv, 0x000305, 0x70605040); + nv_icmd(priv, 0x000306, 0xb8a89888); + nv_icmd(priv, 0x000307, 0xf8e8d8c8); + nv_icmd(priv, 0x00030a, 0x00ffff00); + nv_icmd(priv, 0x00030b, 0x0000001a); + nv_icmd(priv, 0x00030c, 0x00000001); + nv_icmd(priv, 0x000318, 0x00000001); + nv_icmd(priv, 0x000340, 0x00000000); + nv_icmd(priv, 0x000375, 0x00000001); + nv_icmd(priv, 0x00037d, 0x00000006); + nv_icmd(priv, 0x0003a0, 0x00000002); + nv_icmd(priv, 0x0003aa, 0x00000001); + nv_icmd(priv, 0x0003a9, 0x00000001); + nv_icmd(priv, 0x000380, 0x00000001); + nv_icmd(priv, 0x000383, 0x00000011); + nv_icmd(priv, 0x000360, 0x00000040); + nv_icmd(priv, 0x000366, 0x00000000); + nv_icmd(priv, 0x000367, 0x00000000); + nv_icmd(priv, 0x000368, 0x00000fff); + nv_icmd(priv, 0x000370, 0x00000000); + nv_icmd(priv, 0x000371, 0x00000000); + nv_icmd(priv, 0x000372, 0x000fffff); + nv_icmd(priv, 0x00037a, 0x00000012); + nv_icmd(priv, 0x000619, 0x00000003); + nv_icmd(priv, 0x000811, 0x00000003); + nv_icmd(priv, 0x000812, 0x00000004); + nv_icmd(priv, 0x000813, 0x00000006); + nv_icmd(priv, 0x000814, 0x00000008); + nv_icmd(priv, 0x000815, 0x0000000b); + nv_icmd(priv, 0x000800, 0x00000001); + nv_icmd(priv, 0x000801, 0x00000001); + nv_icmd(priv, 0x000802, 0x00000001); + nv_icmd(priv, 0x000803, 0x00000001); + nv_icmd(priv, 0x000804, 0x00000001); + nv_icmd(priv, 0x000805, 0x00000001); + nv_icmd(priv, 0x000632, 0x00000001); + nv_icmd(priv, 0x000633, 0x00000002); + nv_icmd(priv, 0x000634, 0x00000003); + nv_icmd(priv, 0x000635, 0x00000004); + nv_icmd(priv, 0x000654, 0x3f800000); + nv_icmd(priv, 0x000657, 0x3f800000); + nv_icmd(priv, 0x000655, 0x3f800000); + nv_icmd(priv, 0x000656, 0x3f800000); + nv_icmd(priv, 0x0006cd, 0x3f800000); + nv_icmd(priv, 0x0007f5, 0x3f800000); + nv_icmd(priv, 0x0007dc, 0x39291909); + nv_icmd(priv, 0x0007dd, 0x79695949); + nv_icmd(priv, 0x0007de, 0xb9a99989); + nv_icmd(priv, 0x0007df, 0xf9e9d9c9); + nv_icmd(priv, 0x0007e8, 0x00003210); + nv_icmd(priv, 0x0007e9, 0x00007654); + nv_icmd(priv, 0x0007ea, 0x00000098); + nv_icmd(priv, 0x0007ec, 0x39291909); + nv_icmd(priv, 0x0007ed, 0x79695949); + nv_icmd(priv, 0x0007ee, 0xb9a99989); + nv_icmd(priv, 0x0007ef, 0xf9e9d9c9); + nv_icmd(priv, 0x0007f0, 0x00003210); + nv_icmd(priv, 0x0007f1, 0x00007654); + nv_icmd(priv, 0x0007f2, 0x00000098); + nv_icmd(priv, 0x0005a5, 0x00000001); + nv_icmd(priv, 0x000980, 0x00000000); + nv_icmd(priv, 0x000981, 0x00000000); + nv_icmd(priv, 0x000982, 0x00000000); + nv_icmd(priv, 0x000983, 0x00000000); + nv_icmd(priv, 0x000984, 0x00000000); + nv_icmd(priv, 0x000985, 0x00000000); + nv_icmd(priv, 0x000986, 0x00000000); + nv_icmd(priv, 0x000987, 0x00000000); + nv_icmd(priv, 0x000988, 0x00000000); + nv_icmd(priv, 0x000989, 0x00000000); + nv_icmd(priv, 0x00098a, 0x00000000); + nv_icmd(priv, 0x00098b, 0x00000000); + nv_icmd(priv, 0x00098c, 0x00000000); + nv_icmd(priv, 0x00098d, 0x00000000); + nv_icmd(priv, 0x00098e, 0x00000000); + nv_icmd(priv, 0x00098f, 0x00000000); + nv_icmd(priv, 0x000990, 0x00000000); + nv_icmd(priv, 0x000991, 0x00000000); + nv_icmd(priv, 0x000992, 0x00000000); + nv_icmd(priv, 0x000993, 0x00000000); + nv_icmd(priv, 0x000994, 0x00000000); + nv_icmd(priv, 0x000995, 0x00000000); + nv_icmd(priv, 0x000996, 0x00000000); + nv_icmd(priv, 0x000997, 0x00000000); + nv_icmd(priv, 0x000998, 0x00000000); + nv_icmd(priv, 0x000999, 0x00000000); + nv_icmd(priv, 0x00099a, 0x00000000); + nv_icmd(priv, 0x00099b, 0x00000000); + nv_icmd(priv, 0x00099c, 0x00000000); + nv_icmd(priv, 0x00099d, 0x00000000); + nv_icmd(priv, 0x00099e, 0x00000000); + nv_icmd(priv, 0x00099f, 0x00000000); + nv_icmd(priv, 0x0009a0, 0x00000000); + nv_icmd(priv, 0x0009a1, 0x00000000); + nv_icmd(priv, 0x0009a2, 0x00000000); + nv_icmd(priv, 0x0009a3, 0x00000000); + nv_icmd(priv, 0x0009a4, 0x00000000); + nv_icmd(priv, 0x0009a5, 0x00000000); + nv_icmd(priv, 0x0009a6, 0x00000000); + nv_icmd(priv, 0x0009a7, 0x00000000); + nv_icmd(priv, 0x0009a8, 0x00000000); + nv_icmd(priv, 0x0009a9, 0x00000000); + nv_icmd(priv, 0x0009aa, 0x00000000); + nv_icmd(priv, 0x0009ab, 0x00000000); + nv_icmd(priv, 0x0009ac, 0x00000000); + nv_icmd(priv, 0x0009ad, 0x00000000); + nv_icmd(priv, 0x0009ae, 0x00000000); + nv_icmd(priv, 0x0009af, 0x00000000); + nv_icmd(priv, 0x0009b0, 0x00000000); + nv_icmd(priv, 0x0009b1, 0x00000000); + nv_icmd(priv, 0x0009b2, 0x00000000); + nv_icmd(priv, 0x0009b3, 0x00000000); + nv_icmd(priv, 0x0009b4, 0x00000000); + nv_icmd(priv, 0x0009b5, 0x00000000); + nv_icmd(priv, 0x0009b6, 0x00000000); + nv_icmd(priv, 0x0009b7, 0x00000000); + nv_icmd(priv, 0x0009b8, 0x00000000); + nv_icmd(priv, 0x0009b9, 0x00000000); + nv_icmd(priv, 0x0009ba, 0x00000000); + nv_icmd(priv, 0x0009bb, 0x00000000); + nv_icmd(priv, 0x0009bc, 0x00000000); + nv_icmd(priv, 0x0009bd, 0x00000000); + nv_icmd(priv, 0x0009be, 0x00000000); + nv_icmd(priv, 0x0009bf, 0x00000000); + nv_icmd(priv, 0x0009c0, 0x00000000); + nv_icmd(priv, 0x0009c1, 0x00000000); + nv_icmd(priv, 0x0009c2, 0x00000000); + nv_icmd(priv, 0x0009c3, 0x00000000); + nv_icmd(priv, 0x0009c4, 0x00000000); + nv_icmd(priv, 0x0009c5, 0x00000000); + nv_icmd(priv, 0x0009c6, 0x00000000); + nv_icmd(priv, 0x0009c7, 0x00000000); + nv_icmd(priv, 0x0009c8, 0x00000000); + nv_icmd(priv, 0x0009c9, 0x00000000); + nv_icmd(priv, 0x0009ca, 0x00000000); + nv_icmd(priv, 0x0009cb, 0x00000000); + nv_icmd(priv, 0x0009cc, 0x00000000); + nv_icmd(priv, 0x0009cd, 0x00000000); + nv_icmd(priv, 0x0009ce, 0x00000000); + nv_icmd(priv, 0x0009cf, 0x00000000); + nv_icmd(priv, 0x0009d0, 0x00000000); + nv_icmd(priv, 0x0009d1, 0x00000000); + nv_icmd(priv, 0x0009d2, 0x00000000); + nv_icmd(priv, 0x0009d3, 0x00000000); + nv_icmd(priv, 0x0009d4, 0x00000000); + nv_icmd(priv, 0x0009d5, 0x00000000); + nv_icmd(priv, 0x0009d6, 0x00000000); + nv_icmd(priv, 0x0009d7, 0x00000000); + nv_icmd(priv, 0x0009d8, 0x00000000); + nv_icmd(priv, 0x0009d9, 0x00000000); + nv_icmd(priv, 0x0009da, 0x00000000); + nv_icmd(priv, 0x0009db, 0x00000000); + nv_icmd(priv, 0x0009dc, 0x00000000); + nv_icmd(priv, 0x0009dd, 0x00000000); + nv_icmd(priv, 0x0009de, 0x00000000); + nv_icmd(priv, 0x0009df, 0x00000000); + nv_icmd(priv, 0x0009e0, 0x00000000); + nv_icmd(priv, 0x0009e1, 0x00000000); + nv_icmd(priv, 0x0009e2, 0x00000000); + nv_icmd(priv, 0x0009e3, 0x00000000); + nv_icmd(priv, 0x0009e4, 0x00000000); + nv_icmd(priv, 0x0009e5, 0x00000000); + nv_icmd(priv, 0x0009e6, 0x00000000); + nv_icmd(priv, 0x0009e7, 0x00000000); + nv_icmd(priv, 0x0009e8, 0x00000000); + nv_icmd(priv, 0x0009e9, 0x00000000); + nv_icmd(priv, 0x0009ea, 0x00000000); + nv_icmd(priv, 0x0009eb, 0x00000000); + nv_icmd(priv, 0x0009ec, 0x00000000); + nv_icmd(priv, 0x0009ed, 0x00000000); + nv_icmd(priv, 0x0009ee, 0x00000000); + nv_icmd(priv, 0x0009ef, 0x00000000); + nv_icmd(priv, 0x0009f0, 0x00000000); + nv_icmd(priv, 0x0009f1, 0x00000000); + nv_icmd(priv, 0x0009f2, 0x00000000); + nv_icmd(priv, 0x0009f3, 0x00000000); + nv_icmd(priv, 0x0009f4, 0x00000000); + nv_icmd(priv, 0x0009f5, 0x00000000); + nv_icmd(priv, 0x0009f6, 0x00000000); + nv_icmd(priv, 0x0009f7, 0x00000000); + nv_icmd(priv, 0x0009f8, 0x00000000); + nv_icmd(priv, 0x0009f9, 0x00000000); + nv_icmd(priv, 0x0009fa, 0x00000000); + nv_icmd(priv, 0x0009fb, 0x00000000); + nv_icmd(priv, 0x0009fc, 0x00000000); + nv_icmd(priv, 0x0009fd, 0x00000000); + nv_icmd(priv, 0x0009fe, 0x00000000); + nv_icmd(priv, 0x0009ff, 0x00000000); + nv_icmd(priv, 0x000468, 0x00000004); + nv_icmd(priv, 0x00046c, 0x00000001); + nv_icmd(priv, 0x000470, 0x00000000); + nv_icmd(priv, 0x000471, 0x00000000); + nv_icmd(priv, 0x000472, 0x00000000); + nv_icmd(priv, 0x000473, 0x00000000); + nv_icmd(priv, 0x000474, 0x00000000); + nv_icmd(priv, 0x000475, 0x00000000); + nv_icmd(priv, 0x000476, 0x00000000); + nv_icmd(priv, 0x000477, 0x00000000); + nv_icmd(priv, 0x000478, 0x00000000); + nv_icmd(priv, 0x000479, 0x00000000); + nv_icmd(priv, 0x00047a, 0x00000000); + nv_icmd(priv, 0x00047b, 0x00000000); + nv_icmd(priv, 0x00047c, 0x00000000); + nv_icmd(priv, 0x00047d, 0x00000000); + nv_icmd(priv, 0x00047e, 0x00000000); + nv_icmd(priv, 0x00047f, 0x00000000); + nv_icmd(priv, 0x000480, 0x00000000); + nv_icmd(priv, 0x000481, 0x00000000); + nv_icmd(priv, 0x000482, 0x00000000); + nv_icmd(priv, 0x000483, 0x00000000); + nv_icmd(priv, 0x000484, 0x00000000); + nv_icmd(priv, 0x000485, 0x00000000); + nv_icmd(priv, 0x000486, 0x00000000); + nv_icmd(priv, 0x000487, 0x00000000); + nv_icmd(priv, 0x000488, 0x00000000); + nv_icmd(priv, 0x000489, 0x00000000); + nv_icmd(priv, 0x00048a, 0x00000000); + nv_icmd(priv, 0x00048b, 0x00000000); + nv_icmd(priv, 0x00048c, 0x00000000); + nv_icmd(priv, 0x00048d, 0x00000000); + nv_icmd(priv, 0x00048e, 0x00000000); + nv_icmd(priv, 0x00048f, 0x00000000); + nv_icmd(priv, 0x000490, 0x00000000); + nv_icmd(priv, 0x000491, 0x00000000); + nv_icmd(priv, 0x000492, 0x00000000); + nv_icmd(priv, 0x000493, 0x00000000); + nv_icmd(priv, 0x000494, 0x00000000); + nv_icmd(priv, 0x000495, 0x00000000); + nv_icmd(priv, 0x000496, 0x00000000); + nv_icmd(priv, 0x000497, 0x00000000); + nv_icmd(priv, 0x000498, 0x00000000); + nv_icmd(priv, 0x000499, 0x00000000); + nv_icmd(priv, 0x00049a, 0x00000000); + nv_icmd(priv, 0x00049b, 0x00000000); + nv_icmd(priv, 0x00049c, 0x00000000); + nv_icmd(priv, 0x00049d, 0x00000000); + nv_icmd(priv, 0x00049e, 0x00000000); + nv_icmd(priv, 0x00049f, 0x00000000); + nv_icmd(priv, 0x0004a0, 0x00000000); + nv_icmd(priv, 0x0004a1, 0x00000000); + nv_icmd(priv, 0x0004a2, 0x00000000); + nv_icmd(priv, 0x0004a3, 0x00000000); + nv_icmd(priv, 0x0004a4, 0x00000000); + nv_icmd(priv, 0x0004a5, 0x00000000); + nv_icmd(priv, 0x0004a6, 0x00000000); + nv_icmd(priv, 0x0004a7, 0x00000000); + nv_icmd(priv, 0x0004a8, 0x00000000); + nv_icmd(priv, 0x0004a9, 0x00000000); + nv_icmd(priv, 0x0004aa, 0x00000000); + nv_icmd(priv, 0x0004ab, 0x00000000); + nv_icmd(priv, 0x0004ac, 0x00000000); + nv_icmd(priv, 0x0004ad, 0x00000000); + nv_icmd(priv, 0x0004ae, 0x00000000); + nv_icmd(priv, 0x0004af, 0x00000000); + nv_icmd(priv, 0x0004b0, 0x00000000); + nv_icmd(priv, 0x0004b1, 0x00000000); + nv_icmd(priv, 0x0004b2, 0x00000000); + nv_icmd(priv, 0x0004b3, 0x00000000); + nv_icmd(priv, 0x0004b4, 0x00000000); + nv_icmd(priv, 0x0004b5, 0x00000000); + nv_icmd(priv, 0x0004b6, 0x00000000); + nv_icmd(priv, 0x0004b7, 0x00000000); + nv_icmd(priv, 0x0004b8, 0x00000000); + nv_icmd(priv, 0x0004b9, 0x00000000); + nv_icmd(priv, 0x0004ba, 0x00000000); + nv_icmd(priv, 0x0004bb, 0x00000000); + nv_icmd(priv, 0x0004bc, 0x00000000); + nv_icmd(priv, 0x0004bd, 0x00000000); + nv_icmd(priv, 0x0004be, 0x00000000); + nv_icmd(priv, 0x0004bf, 0x00000000); + nv_icmd(priv, 0x0004c0, 0x00000000); + nv_icmd(priv, 0x0004c1, 0x00000000); + nv_icmd(priv, 0x0004c2, 0x00000000); + nv_icmd(priv, 0x0004c3, 0x00000000); + nv_icmd(priv, 0x0004c4, 0x00000000); + nv_icmd(priv, 0x0004c5, 0x00000000); + nv_icmd(priv, 0x0004c6, 0x00000000); + nv_icmd(priv, 0x0004c7, 0x00000000); + nv_icmd(priv, 0x0004c8, 0x00000000); + nv_icmd(priv, 0x0004c9, 0x00000000); + nv_icmd(priv, 0x0004ca, 0x00000000); + nv_icmd(priv, 0x0004cb, 0x00000000); + nv_icmd(priv, 0x0004cc, 0x00000000); + nv_icmd(priv, 0x0004cd, 0x00000000); + nv_icmd(priv, 0x0004ce, 0x00000000); + nv_icmd(priv, 0x0004cf, 0x00000000); + nv_icmd(priv, 0x000510, 0x3f800000); + nv_icmd(priv, 0x000511, 0x3f800000); + nv_icmd(priv, 0x000512, 0x3f800000); + nv_icmd(priv, 0x000513, 0x3f800000); + nv_icmd(priv, 0x000514, 0x3f800000); + nv_icmd(priv, 0x000515, 0x3f800000); + nv_icmd(priv, 0x000516, 0x3f800000); + nv_icmd(priv, 0x000517, 0x3f800000); + nv_icmd(priv, 0x000518, 0x3f800000); + nv_icmd(priv, 0x000519, 0x3f800000); + nv_icmd(priv, 0x00051a, 0x3f800000); + nv_icmd(priv, 0x00051b, 0x3f800000); + nv_icmd(priv, 0x00051c, 0x3f800000); + nv_icmd(priv, 0x00051d, 0x3f800000); + nv_icmd(priv, 0x00051e, 0x3f800000); + nv_icmd(priv, 0x00051f, 0x3f800000); + nv_icmd(priv, 0x000520, 0x000002b6); + nv_icmd(priv, 0x000529, 0x00000001); + nv_icmd(priv, 0x000530, 0xffff0000); + nv_icmd(priv, 0x000531, 0xffff0000); + nv_icmd(priv, 0x000532, 0xffff0000); + nv_icmd(priv, 0x000533, 0xffff0000); + nv_icmd(priv, 0x000534, 0xffff0000); + nv_icmd(priv, 0x000535, 0xffff0000); + nv_icmd(priv, 0x000536, 0xffff0000); + nv_icmd(priv, 0x000537, 0xffff0000); + nv_icmd(priv, 0x000538, 0xffff0000); + nv_icmd(priv, 0x000539, 0xffff0000); + nv_icmd(priv, 0x00053a, 0xffff0000); + nv_icmd(priv, 0x00053b, 0xffff0000); + nv_icmd(priv, 0x00053c, 0xffff0000); + nv_icmd(priv, 0x00053d, 0xffff0000); + nv_icmd(priv, 0x00053e, 0xffff0000); + nv_icmd(priv, 0x00053f, 0xffff0000); + nv_icmd(priv, 0x000585, 0x0000003f); + nv_icmd(priv, 0x000576, 0x00000003); + nv_icmd(priv, 0x00057b, 0x00000059); + nv_icmd(priv, 0x000586, 0x00000040); + nv_icmd(priv, 0x000582, 0x00000080); + nv_icmd(priv, 0x000583, 0x00000080); + nv_icmd(priv, 0x0005c2, 0x00000001); + nv_icmd(priv, 0x000638, 0x00000001); + nv_icmd(priv, 0x000639, 0x00000001); + nv_icmd(priv, 0x00063a, 0x00000002); + nv_icmd(priv, 0x00063b, 0x00000001); + nv_icmd(priv, 0x00063c, 0x00000001); + nv_icmd(priv, 0x00063d, 0x00000002); + nv_icmd(priv, 0x00063e, 0x00000001); + nv_icmd(priv, 0x0008b8, 0x00000001); + nv_icmd(priv, 0x0008b9, 0x00000001); + nv_icmd(priv, 0x0008ba, 0x00000001); + nv_icmd(priv, 0x0008bb, 0x00000001); + nv_icmd(priv, 0x0008bc, 0x00000001); + nv_icmd(priv, 0x0008bd, 0x00000001); + nv_icmd(priv, 0x0008be, 0x00000001); + nv_icmd(priv, 0x0008bf, 0x00000001); + nv_icmd(priv, 0x000900, 0x00000001); + nv_icmd(priv, 0x000901, 0x00000001); + nv_icmd(priv, 0x000902, 0x00000001); + nv_icmd(priv, 0x000903, 0x00000001); + nv_icmd(priv, 0x000904, 0x00000001); + nv_icmd(priv, 0x000905, 0x00000001); + nv_icmd(priv, 0x000906, 0x00000001); + nv_icmd(priv, 0x000907, 0x00000001); + nv_icmd(priv, 0x000908, 0x00000002); + nv_icmd(priv, 0x000909, 0x00000002); + nv_icmd(priv, 0x00090a, 0x00000002); + nv_icmd(priv, 0x00090b, 0x00000002); + nv_icmd(priv, 0x00090c, 0x00000002); + nv_icmd(priv, 0x00090d, 0x00000002); + nv_icmd(priv, 0x00090e, 0x00000002); + nv_icmd(priv, 0x00090f, 0x00000002); + nv_icmd(priv, 0x000910, 0x00000001); + nv_icmd(priv, 0x000911, 0x00000001); + nv_icmd(priv, 0x000912, 0x00000001); + nv_icmd(priv, 0x000913, 0x00000001); + nv_icmd(priv, 0x000914, 0x00000001); + nv_icmd(priv, 0x000915, 0x00000001); + nv_icmd(priv, 0x000916, 0x00000001); + nv_icmd(priv, 0x000917, 0x00000001); + nv_icmd(priv, 0x000918, 0x00000001); + nv_icmd(priv, 0x000919, 0x00000001); + nv_icmd(priv, 0x00091a, 0x00000001); + nv_icmd(priv, 0x00091b, 0x00000001); + nv_icmd(priv, 0x00091c, 0x00000001); + nv_icmd(priv, 0x00091d, 0x00000001); + nv_icmd(priv, 0x00091e, 0x00000001); + nv_icmd(priv, 0x00091f, 0x00000001); + nv_icmd(priv, 0x000920, 0x00000002); + nv_icmd(priv, 0x000921, 0x00000002); + nv_icmd(priv, 0x000922, 0x00000002); + nv_icmd(priv, 0x000923, 0x00000002); + nv_icmd(priv, 0x000924, 0x00000002); + nv_icmd(priv, 0x000925, 0x00000002); + nv_icmd(priv, 0x000926, 0x00000002); + nv_icmd(priv, 0x000927, 0x00000002); + nv_icmd(priv, 0x000928, 0x00000001); + nv_icmd(priv, 0x000929, 0x00000001); + nv_icmd(priv, 0x00092a, 0x00000001); + nv_icmd(priv, 0x00092b, 0x00000001); + nv_icmd(priv, 0x00092c, 0x00000001); + nv_icmd(priv, 0x00092d, 0x00000001); + nv_icmd(priv, 0x00092e, 0x00000001); + nv_icmd(priv, 0x00092f, 0x00000001); + nv_icmd(priv, 0x000648, 0x00000001); + nv_icmd(priv, 0x000649, 0x00000001); + nv_icmd(priv, 0x00064a, 0x00000001); + nv_icmd(priv, 0x00064b, 0x00000001); + nv_icmd(priv, 0x00064c, 0x00000001); + nv_icmd(priv, 0x00064d, 0x00000001); + nv_icmd(priv, 0x00064e, 0x00000001); + nv_icmd(priv, 0x00064f, 0x00000001); + nv_icmd(priv, 0x000650, 0x00000001); + nv_icmd(priv, 0x000658, 0x0000000f); + nv_icmd(priv, 0x0007ff, 0x0000000a); + nv_icmd(priv, 0x00066a, 0x40000000); + nv_icmd(priv, 0x00066b, 0x10000000); + nv_icmd(priv, 0x00066c, 0xffff0000); + nv_icmd(priv, 0x00066d, 0xffff0000); + nv_icmd(priv, 0x0007af, 0x00000008); + nv_icmd(priv, 0x0007b0, 0x00000008); + nv_icmd(priv, 0x0007f6, 0x00000001); + nv_icmd(priv, 0x0006b2, 0x00000055); + nv_icmd(priv, 0x0007ad, 0x00000003); + nv_icmd(priv, 0x000937, 0x00000001); + nv_icmd(priv, 0x000971, 0x00000008); + nv_icmd(priv, 0x000972, 0x00000040); + nv_icmd(priv, 0x000973, 0x0000012c); + nv_icmd(priv, 0x00097c, 0x00000040); + nv_icmd(priv, 0x000979, 0x00000003); + nv_icmd(priv, 0x000975, 0x00000020); + nv_icmd(priv, 0x000976, 0x00000001); + nv_icmd(priv, 0x000977, 0x00000020); + nv_icmd(priv, 0x000978, 0x00000001); + nv_icmd(priv, 0x000957, 0x00000003); + nv_icmd(priv, 0x00095e, 0x20164010); + nv_icmd(priv, 0x00095f, 0x00000020); + nv_icmd(priv, 0x00097d, 0x00000020); + nv_icmd(priv, 0x000683, 0x00000006); + nv_icmd(priv, 0x000685, 0x003fffff); + nv_icmd(priv, 0x000687, 0x003fffff); + nv_icmd(priv, 0x0006a0, 0x00000005); + nv_icmd(priv, 0x000840, 0x00400008); + nv_icmd(priv, 0x000841, 0x08000080); + nv_icmd(priv, 0x000842, 0x00400008); + nv_icmd(priv, 0x000843, 0x08000080); + nv_icmd(priv, 0x000818, 0x00000000); + nv_icmd(priv, 0x000819, 0x00000000); + nv_icmd(priv, 0x00081a, 0x00000000); + nv_icmd(priv, 0x00081b, 0x00000000); + nv_icmd(priv, 0x00081c, 0x00000000); + nv_icmd(priv, 0x00081d, 0x00000000); + nv_icmd(priv, 0x00081e, 0x00000000); + nv_icmd(priv, 0x00081f, 0x00000000); + nv_icmd(priv, 0x000848, 0x00000000); + nv_icmd(priv, 0x000849, 0x00000000); + nv_icmd(priv, 0x00084a, 0x00000000); + nv_icmd(priv, 0x00084b, 0x00000000); + nv_icmd(priv, 0x00084c, 0x00000000); + nv_icmd(priv, 0x00084d, 0x00000000); + nv_icmd(priv, 0x00084e, 0x00000000); + nv_icmd(priv, 0x00084f, 0x00000000); + nv_icmd(priv, 0x000850, 0x00000000); + nv_icmd(priv, 0x000851, 0x00000000); + nv_icmd(priv, 0x000852, 0x00000000); + nv_icmd(priv, 0x000853, 0x00000000); + nv_icmd(priv, 0x000854, 0x00000000); + nv_icmd(priv, 0x000855, 0x00000000); + nv_icmd(priv, 0x000856, 0x00000000); + nv_icmd(priv, 0x000857, 0x00000000); + nv_icmd(priv, 0x000738, 0x00000000); + nv_icmd(priv, 0x0006aa, 0x00000001); + nv_icmd(priv, 0x0006ab, 0x00000002); + nv_icmd(priv, 0x0006ac, 0x00000080); + nv_icmd(priv, 0x0006ad, 0x00000100); + nv_icmd(priv, 0x0006ae, 0x00000100); + nv_icmd(priv, 0x0006b1, 0x00000011); + nv_icmd(priv, 0x0006bb, 0x000000cf); + nv_icmd(priv, 0x0006ce, 0x2a712488); + nv_icmd(priv, 0x000739, 0x4085c000); + nv_icmd(priv, 0x00073a, 0x00000080); + nv_icmd(priv, 0x000786, 0x80000100); + nv_icmd(priv, 0x00073c, 0x00010100); + nv_icmd(priv, 0x00073d, 0x02800000); + nv_icmd(priv, 0x000787, 0x000000cf); + nv_icmd(priv, 0x00078c, 0x00000008); + nv_icmd(priv, 0x000792, 0x00000001); + nv_icmd(priv, 0x000794, 0x00000001); + nv_icmd(priv, 0x000795, 0x00000001); + nv_icmd(priv, 0x000796, 0x00000001); + nv_icmd(priv, 0x000797, 0x000000cf); + nv_icmd(priv, 0x000836, 0x00000001); + nv_icmd(priv, 0x00079a, 0x00000002); + nv_icmd(priv, 0x000833, 0x04444480); + nv_icmd(priv, 0x0007a1, 0x00000001); + nv_icmd(priv, 0x0007a3, 0x00000001); + nv_icmd(priv, 0x0007a4, 0x00000001); + nv_icmd(priv, 0x0007a5, 0x00000001); + nv_icmd(priv, 0x000831, 0x00000004); + nv_icmd(priv, 0x000b07, 0x00000002); + nv_icmd(priv, 0x000b08, 0x00000100); + nv_icmd(priv, 0x000b09, 0x00000100); + nv_icmd(priv, 0x000b0a, 0x00000001); + nv_icmd(priv, 0x000a04, 0x000000ff); + nv_icmd(priv, 0x000a0b, 0x00000040); + nv_icmd(priv, 0x00097f, 0x00000100); + nv_icmd(priv, 0x000a02, 0x00000001); + nv_icmd(priv, 0x000809, 0x00000007); + nv_icmd(priv, 0x00c221, 0x00000040); + nv_icmd(priv, 0x00c1b0, 0x0000000f); + nv_icmd(priv, 0x00c1b1, 0x0000000f); + nv_icmd(priv, 0x00c1b2, 0x0000000f); + nv_icmd(priv, 0x00c1b3, 0x0000000f); + nv_icmd(priv, 0x00c1b4, 0x0000000f); + nv_icmd(priv, 0x00c1b5, 0x0000000f); + nv_icmd(priv, 0x00c1b6, 0x0000000f); + nv_icmd(priv, 0x00c1b7, 0x0000000f); + nv_icmd(priv, 0x00c1b8, 0x0fac6881); + nv_icmd(priv, 0x00c1b9, 0x00fac688); + nv_icmd(priv, 0x00c401, 0x00000001); + nv_icmd(priv, 0x00c402, 0x00010001); + nv_icmd(priv, 0x00c403, 0x00000001); + nv_icmd(priv, 0x00c404, 0x00000001); + nv_icmd(priv, 0x00c40e, 0x00000020); + nv_icmd(priv, 0x00c500, 0x00000003); + nv_icmd(priv, 0x01e100, 0x00000001); + nv_icmd(priv, 0x001000, 0x00000002); + nv_icmd(priv, 0x0006aa, 0x00000001); + nv_icmd(priv, 0x0006ad, 0x00000100); + nv_icmd(priv, 0x0006ae, 0x00000100); + nv_icmd(priv, 0x0006b1, 0x00000011); + nv_icmd(priv, 0x00078c, 0x00000008); + nv_icmd(priv, 0x000792, 0x00000001); + nv_icmd(priv, 0x000794, 0x00000001); + nv_icmd(priv, 0x000795, 0x00000001); + nv_icmd(priv, 0x000796, 0x00000001); + nv_icmd(priv, 0x000797, 0x000000cf); + nv_icmd(priv, 0x00079a, 0x00000002); + nv_icmd(priv, 0x000833, 0x04444480); + nv_icmd(priv, 0x0007a1, 0x00000001); + nv_icmd(priv, 0x0007a3, 0x00000001); + nv_icmd(priv, 0x0007a4, 0x00000001); + nv_icmd(priv, 0x0007a5, 0x00000001); + nv_icmd(priv, 0x000831, 0x00000004); + nv_icmd(priv, 0x01e100, 0x00000001); + nv_icmd(priv, 0x001000, 0x00000008); + nv_icmd(priv, 0x000039, 0x00000000); + nv_icmd(priv, 0x00003a, 0x00000000); + nv_icmd(priv, 0x00003b, 0x00000000); + nv_icmd(priv, 0x000380, 0x00000001); + nv_icmd(priv, 0x000366, 0x00000000); + nv_icmd(priv, 0x000367, 0x00000000); + nv_icmd(priv, 0x000368, 0x00000fff); + nv_icmd(priv, 0x000370, 0x00000000); + nv_icmd(priv, 0x000371, 0x00000000); + nv_icmd(priv, 0x000372, 0x000fffff); + nv_icmd(priv, 0x000813, 0x00000006); + nv_icmd(priv, 0x000814, 0x00000008); + nv_icmd(priv, 0x000957, 0x00000003); + nv_icmd(priv, 0x000818, 0x00000000); + nv_icmd(priv, 0x000819, 0x00000000); + nv_icmd(priv, 0x00081a, 0x00000000); + nv_icmd(priv, 0x00081b, 0x00000000); + nv_icmd(priv, 0x00081c, 0x00000000); + nv_icmd(priv, 0x00081d, 0x00000000); + nv_icmd(priv, 0x00081e, 0x00000000); + nv_icmd(priv, 0x00081f, 0x00000000); + nv_icmd(priv, 0x000848, 0x00000000); + nv_icmd(priv, 0x000849, 0x00000000); + nv_icmd(priv, 0x00084a, 0x00000000); + nv_icmd(priv, 0x00084b, 0x00000000); + nv_icmd(priv, 0x00084c, 0x00000000); + nv_icmd(priv, 0x00084d, 0x00000000); + nv_icmd(priv, 0x00084e, 0x00000000); + nv_icmd(priv, 0x00084f, 0x00000000); + nv_icmd(priv, 0x000850, 0x00000000); + nv_icmd(priv, 0x000851, 0x00000000); + nv_icmd(priv, 0x000852, 0x00000000); + nv_icmd(priv, 0x000853, 0x00000000); + nv_icmd(priv, 0x000854, 0x00000000); + nv_icmd(priv, 0x000855, 0x00000000); + nv_icmd(priv, 0x000856, 0x00000000); + nv_icmd(priv, 0x000857, 0x00000000); + nv_icmd(priv, 0x000738, 0x00000000); + nv_icmd(priv, 0x000b07, 0x00000002); + nv_icmd(priv, 0x000b08, 0x00000100); + nv_icmd(priv, 0x000b09, 0x00000100); + nv_icmd(priv, 0x000b0a, 0x00000001); + nv_icmd(priv, 0x000a04, 0x000000ff); + nv_icmd(priv, 0x00097f, 0x00000100); + nv_icmd(priv, 0x000a02, 0x00000001); + nv_icmd(priv, 0x000809, 0x00000007); + nv_icmd(priv, 0x00c221, 0x00000040); + nv_icmd(priv, 0x00c401, 0x00000001); + nv_icmd(priv, 0x00c402, 0x00010001); + nv_icmd(priv, 0x00c403, 0x00000001); + nv_icmd(priv, 0x00c404, 0x00000001); + nv_icmd(priv, 0x00c40e, 0x00000020); + nv_icmd(priv, 0x00c500, 0x00000003); + nv_icmd(priv, 0x01e100, 0x00000001); + nv_icmd(priv, 0x001000, 0x00000001); + nv_icmd(priv, 0x000b07, 0x00000002); + nv_icmd(priv, 0x000b08, 0x00000100); + nv_icmd(priv, 0x000b09, 0x00000100); + nv_icmd(priv, 0x000b0a, 0x00000001); + nv_icmd(priv, 0x01e100, 0x00000001); + nv_wr32(priv, 0x400208, 0x00000000); +} + +static void +nve0_grctx_generate_a097(struct nvc0_graph_priv *priv) +{ + nv_mthd(priv, 0xa097, 0x0800, 0x00000000); + nv_mthd(priv, 0xa097, 0x0840, 0x00000000); + nv_mthd(priv, 0xa097, 0x0880, 0x00000000); + nv_mthd(priv, 0xa097, 0x08c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0900, 0x00000000); + nv_mthd(priv, 0xa097, 0x0940, 0x00000000); + nv_mthd(priv, 0xa097, 0x0980, 0x00000000); + nv_mthd(priv, 0xa097, 0x09c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0804, 0x00000000); + nv_mthd(priv, 0xa097, 0x0844, 0x00000000); + nv_mthd(priv, 0xa097, 0x0884, 0x00000000); + nv_mthd(priv, 0xa097, 0x08c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0904, 0x00000000); + nv_mthd(priv, 0xa097, 0x0944, 0x00000000); + nv_mthd(priv, 0xa097, 0x0984, 0x00000000); + nv_mthd(priv, 0xa097, 0x09c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0808, 0x00000400); + nv_mthd(priv, 0xa097, 0x0848, 0x00000400); + nv_mthd(priv, 0xa097, 0x0888, 0x00000400); + nv_mthd(priv, 0xa097, 0x08c8, 0x00000400); + nv_mthd(priv, 0xa097, 0x0908, 0x00000400); + nv_mthd(priv, 0xa097, 0x0948, 0x00000400); + nv_mthd(priv, 0xa097, 0x0988, 0x00000400); + nv_mthd(priv, 0xa097, 0x09c8, 0x00000400); + nv_mthd(priv, 0xa097, 0x080c, 0x00000300); + nv_mthd(priv, 0xa097, 0x084c, 0x00000300); + nv_mthd(priv, 0xa097, 0x088c, 0x00000300); + nv_mthd(priv, 0xa097, 0x08cc, 0x00000300); + nv_mthd(priv, 0xa097, 0x090c, 0x00000300); + nv_mthd(priv, 0xa097, 0x094c, 0x00000300); + nv_mthd(priv, 0xa097, 0x098c, 0x00000300); + nv_mthd(priv, 0xa097, 0x09cc, 0x00000300); + nv_mthd(priv, 0xa097, 0x0810, 0x000000cf); + nv_mthd(priv, 0xa097, 0x0850, 0x00000000); + nv_mthd(priv, 0xa097, 0x0890, 0x00000000); + nv_mthd(priv, 0xa097, 0x08d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0910, 0x00000000); + nv_mthd(priv, 0xa097, 0x0950, 0x00000000); + nv_mthd(priv, 0xa097, 0x0990, 0x00000000); + nv_mthd(priv, 0xa097, 0x09d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0814, 0x00000040); + nv_mthd(priv, 0xa097, 0x0854, 0x00000040); + nv_mthd(priv, 0xa097, 0x0894, 0x00000040); + nv_mthd(priv, 0xa097, 0x08d4, 0x00000040); + nv_mthd(priv, 0xa097, 0x0914, 0x00000040); + nv_mthd(priv, 0xa097, 0x0954, 0x00000040); + nv_mthd(priv, 0xa097, 0x0994, 0x00000040); + nv_mthd(priv, 0xa097, 0x09d4, 0x00000040); + nv_mthd(priv, 0xa097, 0x0818, 0x00000001); + nv_mthd(priv, 0xa097, 0x0858, 0x00000001); + nv_mthd(priv, 0xa097, 0x0898, 0x00000001); + nv_mthd(priv, 0xa097, 0x08d8, 0x00000001); + nv_mthd(priv, 0xa097, 0x0918, 0x00000001); + nv_mthd(priv, 0xa097, 0x0958, 0x00000001); + nv_mthd(priv, 0xa097, 0x0998, 0x00000001); + nv_mthd(priv, 0xa097, 0x09d8, 0x00000001); + nv_mthd(priv, 0xa097, 0x081c, 0x00000000); + nv_mthd(priv, 0xa097, 0x085c, 0x00000000); + nv_mthd(priv, 0xa097, 0x089c, 0x00000000); + nv_mthd(priv, 0xa097, 0x08dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x091c, 0x00000000); + nv_mthd(priv, 0xa097, 0x095c, 0x00000000); + nv_mthd(priv, 0xa097, 0x099c, 0x00000000); + nv_mthd(priv, 0xa097, 0x09dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0820, 0x00000000); + nv_mthd(priv, 0xa097, 0x0860, 0x00000000); + nv_mthd(priv, 0xa097, 0x08a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x08e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0920, 0x00000000); + nv_mthd(priv, 0xa097, 0x0960, 0x00000000); + nv_mthd(priv, 0xa097, 0x09a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x09e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c00, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c10, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c20, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c30, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c40, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c50, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c60, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c70, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c80, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c90, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ca0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cb0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cc0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cd0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ce0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cf0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c04, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c14, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c24, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c34, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c44, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c54, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c64, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c74, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c84, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c94, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ca4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cb4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cc4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cd4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ce4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cf4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c08, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c18, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c28, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c38, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c48, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c58, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c68, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c78, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c88, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c98, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ca8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cb8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cc8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cd8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ce8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cf8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c0c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c1c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c2c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c3c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c4c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c5c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c6c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c7c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c8c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1c9c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cac, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cbc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ccc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cdc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cec, 0x00000000); + nv_mthd(priv, 0xa097, 0x1cfc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d00, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d10, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d20, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d30, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d40, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d50, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d60, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d70, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d80, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d90, 0x00000000); + nv_mthd(priv, 0xa097, 0x1da0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1db0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dc0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dd0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1de0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1df0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d04, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d14, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d24, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d34, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d44, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d54, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d64, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d74, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d84, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d94, 0x00000000); + nv_mthd(priv, 0xa097, 0x1da4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1db4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dc4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dd4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1de4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1df4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d08, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d18, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d28, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d38, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d48, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d58, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d68, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d78, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d88, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d98, 0x00000000); + nv_mthd(priv, 0xa097, 0x1da8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1db8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dc8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dd8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1de8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1df8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d0c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d1c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d2c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d3c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d4c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d5c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d6c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d7c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d8c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1d9c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dac, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dbc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dcc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ddc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dec, 0x00000000); + nv_mthd(priv, 0xa097, 0x1dfc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f00, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f08, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f10, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f18, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f20, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f28, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f30, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f38, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f40, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f48, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f50, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f58, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f60, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f68, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f70, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f78, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f04, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f0c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f14, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f1c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f24, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f2c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f34, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f3c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f44, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f4c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f54, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f5c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f64, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f6c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f74, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f7c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f80, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f88, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f90, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f98, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fa0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fa8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fb0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fb8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fc0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fc8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fd0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fd8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fe0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fe8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ff0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ff8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f84, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f8c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f94, 0x00000000); + nv_mthd(priv, 0xa097, 0x1f9c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fa4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fac, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fb4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fbc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fc4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fcc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fd4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fdc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fe4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1fec, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ff4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1ffc, 0x00000000); + nv_mthd(priv, 0xa097, 0x2000, 0x00000000); + nv_mthd(priv, 0xa097, 0x2040, 0x00000011); + nv_mthd(priv, 0xa097, 0x2080, 0x00000020); + nv_mthd(priv, 0xa097, 0x20c0, 0x00000030); + nv_mthd(priv, 0xa097, 0x2100, 0x00000040); + nv_mthd(priv, 0xa097, 0x2140, 0x00000051); + nv_mthd(priv, 0xa097, 0x200c, 0x00000001); + nv_mthd(priv, 0xa097, 0x204c, 0x00000001); + nv_mthd(priv, 0xa097, 0x208c, 0x00000001); + nv_mthd(priv, 0xa097, 0x20cc, 0x00000001); + nv_mthd(priv, 0xa097, 0x210c, 0x00000001); + nv_mthd(priv, 0xa097, 0x214c, 0x00000001); + nv_mthd(priv, 0xa097, 0x2010, 0x00000000); + nv_mthd(priv, 0xa097, 0x2050, 0x00000000); + nv_mthd(priv, 0xa097, 0x2090, 0x00000001); + nv_mthd(priv, 0xa097, 0x20d0, 0x00000002); + nv_mthd(priv, 0xa097, 0x2110, 0x00000003); + nv_mthd(priv, 0xa097, 0x2150, 0x00000004); + nv_mthd(priv, 0xa097, 0x0380, 0x00000000); + nv_mthd(priv, 0xa097, 0x03a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x03c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x03e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0384, 0x00000000); + nv_mthd(priv, 0xa097, 0x03a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x03c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x03e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0388, 0x00000000); + nv_mthd(priv, 0xa097, 0x03a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x03c8, 0x00000000); + nv_mthd(priv, 0xa097, 0x03e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x038c, 0x00000000); + nv_mthd(priv, 0xa097, 0x03ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x03cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x03ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x0700, 0x00000000); + nv_mthd(priv, 0xa097, 0x0710, 0x00000000); + nv_mthd(priv, 0xa097, 0x0720, 0x00000000); + nv_mthd(priv, 0xa097, 0x0730, 0x00000000); + nv_mthd(priv, 0xa097, 0x0704, 0x00000000); + nv_mthd(priv, 0xa097, 0x0714, 0x00000000); + nv_mthd(priv, 0xa097, 0x0724, 0x00000000); + nv_mthd(priv, 0xa097, 0x0734, 0x00000000); + nv_mthd(priv, 0xa097, 0x0708, 0x00000000); + nv_mthd(priv, 0xa097, 0x0718, 0x00000000); + nv_mthd(priv, 0xa097, 0x0728, 0x00000000); + nv_mthd(priv, 0xa097, 0x0738, 0x00000000); + nv_mthd(priv, 0xa097, 0x2800, 0x00000000); + nv_mthd(priv, 0xa097, 0x2804, 0x00000000); + nv_mthd(priv, 0xa097, 0x2808, 0x00000000); + nv_mthd(priv, 0xa097, 0x280c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2810, 0x00000000); + nv_mthd(priv, 0xa097, 0x2814, 0x00000000); + nv_mthd(priv, 0xa097, 0x2818, 0x00000000); + nv_mthd(priv, 0xa097, 0x281c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2820, 0x00000000); + nv_mthd(priv, 0xa097, 0x2824, 0x00000000); + nv_mthd(priv, 0xa097, 0x2828, 0x00000000); + nv_mthd(priv, 0xa097, 0x282c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2830, 0x00000000); + nv_mthd(priv, 0xa097, 0x2834, 0x00000000); + nv_mthd(priv, 0xa097, 0x2838, 0x00000000); + nv_mthd(priv, 0xa097, 0x283c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2840, 0x00000000); + nv_mthd(priv, 0xa097, 0x2844, 0x00000000); + nv_mthd(priv, 0xa097, 0x2848, 0x00000000); + nv_mthd(priv, 0xa097, 0x284c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2850, 0x00000000); + nv_mthd(priv, 0xa097, 0x2854, 0x00000000); + nv_mthd(priv, 0xa097, 0x2858, 0x00000000); + nv_mthd(priv, 0xa097, 0x285c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2860, 0x00000000); + nv_mthd(priv, 0xa097, 0x2864, 0x00000000); + nv_mthd(priv, 0xa097, 0x2868, 0x00000000); + nv_mthd(priv, 0xa097, 0x286c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2870, 0x00000000); + nv_mthd(priv, 0xa097, 0x2874, 0x00000000); + nv_mthd(priv, 0xa097, 0x2878, 0x00000000); + nv_mthd(priv, 0xa097, 0x287c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2880, 0x00000000); + nv_mthd(priv, 0xa097, 0x2884, 0x00000000); + nv_mthd(priv, 0xa097, 0x2888, 0x00000000); + nv_mthd(priv, 0xa097, 0x288c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2890, 0x00000000); + nv_mthd(priv, 0xa097, 0x2894, 0x00000000); + nv_mthd(priv, 0xa097, 0x2898, 0x00000000); + nv_mthd(priv, 0xa097, 0x289c, 0x00000000); + nv_mthd(priv, 0xa097, 0x28a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x28a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x28a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x28ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x28b0, 0x00000000); + nv_mthd(priv, 0xa097, 0x28b4, 0x00000000); + nv_mthd(priv, 0xa097, 0x28b8, 0x00000000); + nv_mthd(priv, 0xa097, 0x28bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x28c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x28c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x28c8, 0x00000000); + nv_mthd(priv, 0xa097, 0x28cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x28d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x28d4, 0x00000000); + nv_mthd(priv, 0xa097, 0x28d8, 0x00000000); + nv_mthd(priv, 0xa097, 0x28dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x28e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x28e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x28e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x28ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x28f0, 0x00000000); + nv_mthd(priv, 0xa097, 0x28f4, 0x00000000); + nv_mthd(priv, 0xa097, 0x28f8, 0x00000000); + nv_mthd(priv, 0xa097, 0x28fc, 0x00000000); + nv_mthd(priv, 0xa097, 0x2900, 0x00000000); + nv_mthd(priv, 0xa097, 0x2904, 0x00000000); + nv_mthd(priv, 0xa097, 0x2908, 0x00000000); + nv_mthd(priv, 0xa097, 0x290c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2910, 0x00000000); + nv_mthd(priv, 0xa097, 0x2914, 0x00000000); + nv_mthd(priv, 0xa097, 0x2918, 0x00000000); + nv_mthd(priv, 0xa097, 0x291c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2920, 0x00000000); + nv_mthd(priv, 0xa097, 0x2924, 0x00000000); + nv_mthd(priv, 0xa097, 0x2928, 0x00000000); + nv_mthd(priv, 0xa097, 0x292c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2930, 0x00000000); + nv_mthd(priv, 0xa097, 0x2934, 0x00000000); + nv_mthd(priv, 0xa097, 0x2938, 0x00000000); + nv_mthd(priv, 0xa097, 0x293c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2940, 0x00000000); + nv_mthd(priv, 0xa097, 0x2944, 0x00000000); + nv_mthd(priv, 0xa097, 0x2948, 0x00000000); + nv_mthd(priv, 0xa097, 0x294c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2950, 0x00000000); + nv_mthd(priv, 0xa097, 0x2954, 0x00000000); + nv_mthd(priv, 0xa097, 0x2958, 0x00000000); + nv_mthd(priv, 0xa097, 0x295c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2960, 0x00000000); + nv_mthd(priv, 0xa097, 0x2964, 0x00000000); + nv_mthd(priv, 0xa097, 0x2968, 0x00000000); + nv_mthd(priv, 0xa097, 0x296c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2970, 0x00000000); + nv_mthd(priv, 0xa097, 0x2974, 0x00000000); + nv_mthd(priv, 0xa097, 0x2978, 0x00000000); + nv_mthd(priv, 0xa097, 0x297c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2980, 0x00000000); + nv_mthd(priv, 0xa097, 0x2984, 0x00000000); + nv_mthd(priv, 0xa097, 0x2988, 0x00000000); + nv_mthd(priv, 0xa097, 0x298c, 0x00000000); + nv_mthd(priv, 0xa097, 0x2990, 0x00000000); + nv_mthd(priv, 0xa097, 0x2994, 0x00000000); + nv_mthd(priv, 0xa097, 0x2998, 0x00000000); + nv_mthd(priv, 0xa097, 0x299c, 0x00000000); + nv_mthd(priv, 0xa097, 0x29a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x29a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x29a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x29ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x29b0, 0x00000000); + nv_mthd(priv, 0xa097, 0x29b4, 0x00000000); + nv_mthd(priv, 0xa097, 0x29b8, 0x00000000); + nv_mthd(priv, 0xa097, 0x29bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x29c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x29c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x29c8, 0x00000000); + nv_mthd(priv, 0xa097, 0x29cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x29d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x29d4, 0x00000000); + nv_mthd(priv, 0xa097, 0x29d8, 0x00000000); + nv_mthd(priv, 0xa097, 0x29dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x29e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x29e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x29e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x29ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x29f0, 0x00000000); + nv_mthd(priv, 0xa097, 0x29f4, 0x00000000); + nv_mthd(priv, 0xa097, 0x29f8, 0x00000000); + nv_mthd(priv, 0xa097, 0x29fc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a00, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a20, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a40, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a60, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a80, 0x00000000); + nv_mthd(priv, 0xa097, 0x0aa0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ac0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ae0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b00, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b20, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b40, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b60, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b80, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ba0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bc0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0be0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a04, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a24, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a44, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a64, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a84, 0x00000000); + nv_mthd(priv, 0xa097, 0x0aa4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ac4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ae4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b04, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b24, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b44, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b64, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b84, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ba4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bc4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0be4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a08, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a28, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a48, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a68, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a88, 0x00000000); + nv_mthd(priv, 0xa097, 0x0aa8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ac8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ae8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b08, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b28, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b48, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b68, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b88, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ba8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bc8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0be8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a0c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a2c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a4c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a6c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a8c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0aac, 0x00000000); + nv_mthd(priv, 0xa097, 0x0acc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0aec, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b0c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b2c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b4c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b6c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b8c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bac, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bcc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bec, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a10, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a30, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a50, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a70, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a90, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ab0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ad0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0af0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b10, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b30, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b50, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b70, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b90, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bb0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bd0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bf0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a14, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a34, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a54, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a74, 0x00000000); + nv_mthd(priv, 0xa097, 0x0a94, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ab4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ad4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0af4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b14, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b34, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b54, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b74, 0x00000000); + nv_mthd(priv, 0xa097, 0x0b94, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bb4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bd4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0bf4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c00, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c10, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c20, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c30, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c40, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c50, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c60, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c70, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c80, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c90, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ca0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cb0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cc0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cd0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ce0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cf0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c04, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c14, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c24, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c34, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c44, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c54, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c64, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c74, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c84, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c94, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ca4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cb4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cc4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cd4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ce4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cf4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c08, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c18, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c28, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c38, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c48, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c58, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c68, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c78, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c88, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c98, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ca8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cb8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cc8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cd8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ce8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0cf8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0c0c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c1c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c2c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c3c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c4c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c5c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c6c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c7c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c8c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0c9c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0cac, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0cbc, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0ccc, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0cdc, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0cec, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0cfc, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0d00, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d08, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d10, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d18, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d20, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d28, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d30, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d38, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d04, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d0c, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d14, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d1c, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d24, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d2c, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d34, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d3c, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e00, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e10, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e20, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e30, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e40, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e50, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e60, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e70, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e80, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e90, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ea0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0eb0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ec0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ed0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ee0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ef0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0e04, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e14, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e24, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e34, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e44, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e54, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e64, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e74, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e84, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e94, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ea4, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0eb4, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ec4, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ed4, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ee4, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ef4, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e08, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e18, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e28, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e38, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e48, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e58, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e68, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e78, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e88, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0e98, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ea8, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0eb8, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ec8, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ed8, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ee8, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0ef8, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d40, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d48, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d50, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d58, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d44, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d4c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d54, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d5c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1e00, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e20, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e40, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e60, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e80, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ea0, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ec0, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ee0, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e04, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e24, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e44, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e64, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e84, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ea4, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ec4, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ee4, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e08, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e28, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e48, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e68, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e88, 0x00000002); + nv_mthd(priv, 0xa097, 0x1ea8, 0x00000002); + nv_mthd(priv, 0xa097, 0x1ec8, 0x00000002); + nv_mthd(priv, 0xa097, 0x1ee8, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e0c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e2c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e4c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e6c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e8c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1eac, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ecc, 0x00000001); + nv_mthd(priv, 0xa097, 0x1eec, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e10, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e30, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e50, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e70, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e90, 0x00000001); + nv_mthd(priv, 0xa097, 0x1eb0, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ed0, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ef0, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e14, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e34, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e54, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e74, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e94, 0x00000002); + nv_mthd(priv, 0xa097, 0x1eb4, 0x00000002); + nv_mthd(priv, 0xa097, 0x1ed4, 0x00000002); + nv_mthd(priv, 0xa097, 0x1ef4, 0x00000002); + nv_mthd(priv, 0xa097, 0x1e18, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e38, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e58, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e78, 0x00000001); + nv_mthd(priv, 0xa097, 0x1e98, 0x00000001); + nv_mthd(priv, 0xa097, 0x1eb8, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ed8, 0x00000001); + nv_mthd(priv, 0xa097, 0x1ef8, 0x00000001); + nv_mthd(priv, 0xa097, 0x3400, 0x00000000); + nv_mthd(priv, 0xa097, 0x3404, 0x00000000); + nv_mthd(priv, 0xa097, 0x3408, 0x00000000); + nv_mthd(priv, 0xa097, 0x340c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3410, 0x00000000); + nv_mthd(priv, 0xa097, 0x3414, 0x00000000); + nv_mthd(priv, 0xa097, 0x3418, 0x00000000); + nv_mthd(priv, 0xa097, 0x341c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3420, 0x00000000); + nv_mthd(priv, 0xa097, 0x3424, 0x00000000); + nv_mthd(priv, 0xa097, 0x3428, 0x00000000); + nv_mthd(priv, 0xa097, 0x342c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3430, 0x00000000); + nv_mthd(priv, 0xa097, 0x3434, 0x00000000); + nv_mthd(priv, 0xa097, 0x3438, 0x00000000); + nv_mthd(priv, 0xa097, 0x343c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3440, 0x00000000); + nv_mthd(priv, 0xa097, 0x3444, 0x00000000); + nv_mthd(priv, 0xa097, 0x3448, 0x00000000); + nv_mthd(priv, 0xa097, 0x344c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3450, 0x00000000); + nv_mthd(priv, 0xa097, 0x3454, 0x00000000); + nv_mthd(priv, 0xa097, 0x3458, 0x00000000); + nv_mthd(priv, 0xa097, 0x345c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3460, 0x00000000); + nv_mthd(priv, 0xa097, 0x3464, 0x00000000); + nv_mthd(priv, 0xa097, 0x3468, 0x00000000); + nv_mthd(priv, 0xa097, 0x346c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3470, 0x00000000); + nv_mthd(priv, 0xa097, 0x3474, 0x00000000); + nv_mthd(priv, 0xa097, 0x3478, 0x00000000); + nv_mthd(priv, 0xa097, 0x347c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3480, 0x00000000); + nv_mthd(priv, 0xa097, 0x3484, 0x00000000); + nv_mthd(priv, 0xa097, 0x3488, 0x00000000); + nv_mthd(priv, 0xa097, 0x348c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3490, 0x00000000); + nv_mthd(priv, 0xa097, 0x3494, 0x00000000); + nv_mthd(priv, 0xa097, 0x3498, 0x00000000); + nv_mthd(priv, 0xa097, 0x349c, 0x00000000); + nv_mthd(priv, 0xa097, 0x34a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x34a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x34a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x34ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x34b0, 0x00000000); + nv_mthd(priv, 0xa097, 0x34b4, 0x00000000); + nv_mthd(priv, 0xa097, 0x34b8, 0x00000000); + nv_mthd(priv, 0xa097, 0x34bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x34c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x34c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x34c8, 0x00000000); + nv_mthd(priv, 0xa097, 0x34cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x34d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x34d4, 0x00000000); + nv_mthd(priv, 0xa097, 0x34d8, 0x00000000); + nv_mthd(priv, 0xa097, 0x34dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x34e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x34e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x34e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x34ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x34f0, 0x00000000); + nv_mthd(priv, 0xa097, 0x34f4, 0x00000000); + nv_mthd(priv, 0xa097, 0x34f8, 0x00000000); + nv_mthd(priv, 0xa097, 0x34fc, 0x00000000); + nv_mthd(priv, 0xa097, 0x3500, 0x00000000); + nv_mthd(priv, 0xa097, 0x3504, 0x00000000); + nv_mthd(priv, 0xa097, 0x3508, 0x00000000); + nv_mthd(priv, 0xa097, 0x350c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3510, 0x00000000); + nv_mthd(priv, 0xa097, 0x3514, 0x00000000); + nv_mthd(priv, 0xa097, 0x3518, 0x00000000); + nv_mthd(priv, 0xa097, 0x351c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3520, 0x00000000); + nv_mthd(priv, 0xa097, 0x3524, 0x00000000); + nv_mthd(priv, 0xa097, 0x3528, 0x00000000); + nv_mthd(priv, 0xa097, 0x352c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3530, 0x00000000); + nv_mthd(priv, 0xa097, 0x3534, 0x00000000); + nv_mthd(priv, 0xa097, 0x3538, 0x00000000); + nv_mthd(priv, 0xa097, 0x353c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3540, 0x00000000); + nv_mthd(priv, 0xa097, 0x3544, 0x00000000); + nv_mthd(priv, 0xa097, 0x3548, 0x00000000); + nv_mthd(priv, 0xa097, 0x354c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3550, 0x00000000); + nv_mthd(priv, 0xa097, 0x3554, 0x00000000); + nv_mthd(priv, 0xa097, 0x3558, 0x00000000); + nv_mthd(priv, 0xa097, 0x355c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3560, 0x00000000); + nv_mthd(priv, 0xa097, 0x3564, 0x00000000); + nv_mthd(priv, 0xa097, 0x3568, 0x00000000); + nv_mthd(priv, 0xa097, 0x356c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3570, 0x00000000); + nv_mthd(priv, 0xa097, 0x3574, 0x00000000); + nv_mthd(priv, 0xa097, 0x3578, 0x00000000); + nv_mthd(priv, 0xa097, 0x357c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3580, 0x00000000); + nv_mthd(priv, 0xa097, 0x3584, 0x00000000); + nv_mthd(priv, 0xa097, 0x3588, 0x00000000); + nv_mthd(priv, 0xa097, 0x358c, 0x00000000); + nv_mthd(priv, 0xa097, 0x3590, 0x00000000); + nv_mthd(priv, 0xa097, 0x3594, 0x00000000); + nv_mthd(priv, 0xa097, 0x3598, 0x00000000); + nv_mthd(priv, 0xa097, 0x359c, 0x00000000); + nv_mthd(priv, 0xa097, 0x35a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x35a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x35a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x35ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x35b0, 0x00000000); + nv_mthd(priv, 0xa097, 0x35b4, 0x00000000); + nv_mthd(priv, 0xa097, 0x35b8, 0x00000000); + nv_mthd(priv, 0xa097, 0x35bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x35c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x35c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x35c8, 0x00000000); + nv_mthd(priv, 0xa097, 0x35cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x35d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x35d4, 0x00000000); + nv_mthd(priv, 0xa097, 0x35d8, 0x00000000); + nv_mthd(priv, 0xa097, 0x35dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x35e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x35e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x35e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x35ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x35f0, 0x00000000); + nv_mthd(priv, 0xa097, 0x35f4, 0x00000000); + nv_mthd(priv, 0xa097, 0x35f8, 0x00000000); + nv_mthd(priv, 0xa097, 0x35fc, 0x00000000); + nv_mthd(priv, 0xa097, 0x030c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1944, 0x00000000); + nv_mthd(priv, 0xa097, 0x1514, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d68, 0x0000ffff); + nv_mthd(priv, 0xa097, 0x121c, 0x0fac6881); + nv_mthd(priv, 0xa097, 0x0fac, 0x00000001); + nv_mthd(priv, 0xa097, 0x1538, 0x00000001); + nv_mthd(priv, 0xa097, 0x0fe0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0fe4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0fe8, 0x00000014); + nv_mthd(priv, 0xa097, 0x0fec, 0x00000040); + nv_mthd(priv, 0xa097, 0x0ff0, 0x00000000); + nv_mthd(priv, 0xa097, 0x179c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1228, 0x00000400); + nv_mthd(priv, 0xa097, 0x122c, 0x00000300); + nv_mthd(priv, 0xa097, 0x1230, 0x00010001); + nv_mthd(priv, 0xa097, 0x07f8, 0x00000000); + nv_mthd(priv, 0xa097, 0x15b4, 0x00000001); + nv_mthd(priv, 0xa097, 0x15cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1534, 0x00000000); + nv_mthd(priv, 0xa097, 0x0fb0, 0x00000000); + nv_mthd(priv, 0xa097, 0x15d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x153c, 0x00000000); + nv_mthd(priv, 0xa097, 0x16b4, 0x00000003); + nv_mthd(priv, 0xa097, 0x0fbc, 0x0000ffff); + nv_mthd(priv, 0xa097, 0x0fc0, 0x0000ffff); + nv_mthd(priv, 0xa097, 0x0fc4, 0x0000ffff); + nv_mthd(priv, 0xa097, 0x0fc8, 0x0000ffff); + nv_mthd(priv, 0xa097, 0x0df8, 0x00000000); + nv_mthd(priv, 0xa097, 0x0dfc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1948, 0x00000000); + nv_mthd(priv, 0xa097, 0x1970, 0x00000001); + nv_mthd(priv, 0xa097, 0x161c, 0x000009f0); + nv_mthd(priv, 0xa097, 0x0dcc, 0x00000010); + nv_mthd(priv, 0xa097, 0x163c, 0x00000000); + nv_mthd(priv, 0xa097, 0x15e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1160, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1164, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1168, 0x25e00040); + nv_mthd(priv, 0xa097, 0x116c, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1170, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1174, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1178, 0x25e00040); + nv_mthd(priv, 0xa097, 0x117c, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1180, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1184, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1188, 0x25e00040); + nv_mthd(priv, 0xa097, 0x118c, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1190, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1194, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1198, 0x25e00040); + nv_mthd(priv, 0xa097, 0x119c, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11a0, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11a4, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11a8, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11ac, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11b0, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11b4, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11b8, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11bc, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11c0, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11c4, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11c8, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11cc, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11d0, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11d4, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11d8, 0x25e00040); + nv_mthd(priv, 0xa097, 0x11dc, 0x25e00040); + nv_mthd(priv, 0xa097, 0x1880, 0x00000000); + nv_mthd(priv, 0xa097, 0x1884, 0x00000000); + nv_mthd(priv, 0xa097, 0x1888, 0x00000000); + nv_mthd(priv, 0xa097, 0x188c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1890, 0x00000000); + nv_mthd(priv, 0xa097, 0x1894, 0x00000000); + nv_mthd(priv, 0xa097, 0x1898, 0x00000000); + nv_mthd(priv, 0xa097, 0x189c, 0x00000000); + nv_mthd(priv, 0xa097, 0x18a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x18a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x18a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x18ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x18b0, 0x00000000); + nv_mthd(priv, 0xa097, 0x18b4, 0x00000000); + nv_mthd(priv, 0xa097, 0x18b8, 0x00000000); + nv_mthd(priv, 0xa097, 0x18bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x18c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x18c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x18c8, 0x00000000); + nv_mthd(priv, 0xa097, 0x18cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x18d0, 0x00000000); + nv_mthd(priv, 0xa097, 0x18d4, 0x00000000); + nv_mthd(priv, 0xa097, 0x18d8, 0x00000000); + nv_mthd(priv, 0xa097, 0x18dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x18e0, 0x00000000); + nv_mthd(priv, 0xa097, 0x18e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x18e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x18ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x18f0, 0x00000000); + nv_mthd(priv, 0xa097, 0x18f4, 0x00000000); + nv_mthd(priv, 0xa097, 0x18f8, 0x00000000); + nv_mthd(priv, 0xa097, 0x18fc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f84, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f88, 0x00000000); + nv_mthd(priv, 0xa097, 0x17c8, 0x00000000); + nv_mthd(priv, 0xa097, 0x17cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x17d0, 0x000000ff); + nv_mthd(priv, 0xa097, 0x17d4, 0xffffffff); + nv_mthd(priv, 0xa097, 0x17d8, 0x00000002); + nv_mthd(priv, 0xa097, 0x17dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x15f4, 0x00000000); + nv_mthd(priv, 0xa097, 0x15f8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1434, 0x00000000); + nv_mthd(priv, 0xa097, 0x1438, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d74, 0x00000000); + nv_mthd(priv, 0xa097, 0x0dec, 0x00000001); + nv_mthd(priv, 0xa097, 0x13a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1318, 0x00000001); + nv_mthd(priv, 0xa097, 0x1644, 0x00000000); + nv_mthd(priv, 0xa097, 0x0748, 0x00000000); + nv_mthd(priv, 0xa097, 0x0de8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1648, 0x00000000); + nv_mthd(priv, 0xa097, 0x12a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x1120, 0x00000000); + nv_mthd(priv, 0xa097, 0x1124, 0x00000000); + nv_mthd(priv, 0xa097, 0x1128, 0x00000000); + nv_mthd(priv, 0xa097, 0x112c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1118, 0x00000000); + nv_mthd(priv, 0xa097, 0x164c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1658, 0x00000000); + nv_mthd(priv, 0xa097, 0x1910, 0x00000290); + nv_mthd(priv, 0xa097, 0x1518, 0x00000000); + nv_mthd(priv, 0xa097, 0x165c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1520, 0x00000000); + nv_mthd(priv, 0xa097, 0x1604, 0x00000000); + nv_mthd(priv, 0xa097, 0x1570, 0x00000000); + nv_mthd(priv, 0xa097, 0x13b0, 0x3f800000); + nv_mthd(priv, 0xa097, 0x13b4, 0x3f800000); + nv_mthd(priv, 0xa097, 0x020c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1670, 0x30201000); + nv_mthd(priv, 0xa097, 0x1674, 0x70605040); + nv_mthd(priv, 0xa097, 0x1678, 0xb8a89888); + nv_mthd(priv, 0xa097, 0x167c, 0xf8e8d8c8); + nv_mthd(priv, 0xa097, 0x166c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1680, 0x00ffff00); + nv_mthd(priv, 0xa097, 0x12d0, 0x00000003); + nv_mthd(priv, 0xa097, 0x12d4, 0x00000002); + nv_mthd(priv, 0xa097, 0x1684, 0x00000000); + nv_mthd(priv, 0xa097, 0x1688, 0x00000000); + nv_mthd(priv, 0xa097, 0x0dac, 0x00001b02); + nv_mthd(priv, 0xa097, 0x0db0, 0x00001b02); + nv_mthd(priv, 0xa097, 0x0db4, 0x00000000); + nv_mthd(priv, 0xa097, 0x168c, 0x00000000); + nv_mthd(priv, 0xa097, 0x15bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x156c, 0x00000000); + nv_mthd(priv, 0xa097, 0x187c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1110, 0x00000001); + nv_mthd(priv, 0xa097, 0x0dc0, 0x00000000); + nv_mthd(priv, 0xa097, 0x0dc4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0dc8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1234, 0x00000000); + nv_mthd(priv, 0xa097, 0x1690, 0x00000000); + nv_mthd(priv, 0xa097, 0x12ac, 0x00000001); + nv_mthd(priv, 0xa097, 0x0790, 0x00000000); + nv_mthd(priv, 0xa097, 0x0794, 0x00000000); + nv_mthd(priv, 0xa097, 0x0798, 0x00000000); + nv_mthd(priv, 0xa097, 0x079c, 0x00000000); + nv_mthd(priv, 0xa097, 0x07a0, 0x00000000); + nv_mthd(priv, 0xa097, 0x077c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1000, 0x00000010); + nv_mthd(priv, 0xa097, 0x10fc, 0x00000000); + nv_mthd(priv, 0xa097, 0x1290, 0x00000000); + nv_mthd(priv, 0xa097, 0x0218, 0x00000010); + nv_mthd(priv, 0xa097, 0x12d8, 0x00000000); + nv_mthd(priv, 0xa097, 0x12dc, 0x00000010); + nv_mthd(priv, 0xa097, 0x0d94, 0x00000001); + nv_mthd(priv, 0xa097, 0x155c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1560, 0x00000000); + nv_mthd(priv, 0xa097, 0x1564, 0x00000fff); + nv_mthd(priv, 0xa097, 0x1574, 0x00000000); + nv_mthd(priv, 0xa097, 0x1578, 0x00000000); + nv_mthd(priv, 0xa097, 0x157c, 0x000fffff); + nv_mthd(priv, 0xa097, 0x1354, 0x00000000); + nv_mthd(priv, 0xa097, 0x1610, 0x00000012); + nv_mthd(priv, 0xa097, 0x1608, 0x00000000); + nv_mthd(priv, 0xa097, 0x160c, 0x00000000); + nv_mthd(priv, 0xa097, 0x260c, 0x00000000); + nv_mthd(priv, 0xa097, 0x07ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x162c, 0x00000003); + nv_mthd(priv, 0xa097, 0x0210, 0x00000000); + nv_mthd(priv, 0xa097, 0x0320, 0x00000000); + nv_mthd(priv, 0xa097, 0x0324, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0328, 0x3f800000); + nv_mthd(priv, 0xa097, 0x032c, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0330, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0334, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0338, 0x3f800000); + nv_mthd(priv, 0xa097, 0x0750, 0x00000000); + nv_mthd(priv, 0xa097, 0x0760, 0x39291909); + nv_mthd(priv, 0xa097, 0x0764, 0x79695949); + nv_mthd(priv, 0xa097, 0x0768, 0xb9a99989); + nv_mthd(priv, 0xa097, 0x076c, 0xf9e9d9c9); + nv_mthd(priv, 0xa097, 0x0770, 0x30201000); + nv_mthd(priv, 0xa097, 0x0774, 0x70605040); + nv_mthd(priv, 0xa097, 0x0778, 0x00009080); + nv_mthd(priv, 0xa097, 0x0780, 0x39291909); + nv_mthd(priv, 0xa097, 0x0784, 0x79695949); + nv_mthd(priv, 0xa097, 0x0788, 0xb9a99989); + nv_mthd(priv, 0xa097, 0x078c, 0xf9e9d9c9); + nv_mthd(priv, 0xa097, 0x07d0, 0x30201000); + nv_mthd(priv, 0xa097, 0x07d4, 0x70605040); + nv_mthd(priv, 0xa097, 0x07d8, 0x00009080); + nv_mthd(priv, 0xa097, 0x037c, 0x00000001); + nv_mthd(priv, 0xa097, 0x0740, 0x00000000); + nv_mthd(priv, 0xa097, 0x0744, 0x00000000); + nv_mthd(priv, 0xa097, 0x2600, 0x00000000); + nv_mthd(priv, 0xa097, 0x1918, 0x00000000); + nv_mthd(priv, 0xa097, 0x191c, 0x00000900); + nv_mthd(priv, 0xa097, 0x1920, 0x00000405); + nv_mthd(priv, 0xa097, 0x1308, 0x00000001); + nv_mthd(priv, 0xa097, 0x1924, 0x00000000); + nv_mthd(priv, 0xa097, 0x13ac, 0x00000000); + nv_mthd(priv, 0xa097, 0x192c, 0x00000001); + nv_mthd(priv, 0xa097, 0x193c, 0x00002c1c); + nv_mthd(priv, 0xa097, 0x0d7c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f8c, 0x00000000); + nv_mthd(priv, 0xa097, 0x02c0, 0x00000001); + nv_mthd(priv, 0xa097, 0x1510, 0x00000000); + nv_mthd(priv, 0xa097, 0x1940, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ff4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0ff8, 0x00000000); + nv_mthd(priv, 0xa097, 0x194c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1950, 0x00000000); + nv_mthd(priv, 0xa097, 0x1968, 0x00000000); + nv_mthd(priv, 0xa097, 0x1590, 0x0000003f); + nv_mthd(priv, 0xa097, 0x07e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x07ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x07f0, 0x00000000); + nv_mthd(priv, 0xa097, 0x07f4, 0x00000000); + nv_mthd(priv, 0xa097, 0x196c, 0x00000011); + nv_mthd(priv, 0xa097, 0x02e4, 0x0000b001); + nv_mthd(priv, 0xa097, 0x036c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0370, 0x00000000); + nv_mthd(priv, 0xa097, 0x197c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0fcc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0fd0, 0x00000000); + nv_mthd(priv, 0xa097, 0x02d8, 0x00000040); + nv_mthd(priv, 0xa097, 0x1980, 0x00000080); + nv_mthd(priv, 0xa097, 0x1504, 0x00000080); + nv_mthd(priv, 0xa097, 0x1984, 0x00000000); + nv_mthd(priv, 0xa097, 0x0300, 0x00000001); + nv_mthd(priv, 0xa097, 0x13a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x12ec, 0x00000000); + nv_mthd(priv, 0xa097, 0x1310, 0x00000000); + nv_mthd(priv, 0xa097, 0x1314, 0x00000001); + nv_mthd(priv, 0xa097, 0x1380, 0x00000000); + nv_mthd(priv, 0xa097, 0x1384, 0x00000001); + nv_mthd(priv, 0xa097, 0x1388, 0x00000001); + nv_mthd(priv, 0xa097, 0x138c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1390, 0x00000001); + nv_mthd(priv, 0xa097, 0x1394, 0x00000000); + nv_mthd(priv, 0xa097, 0x139c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1398, 0x00000000); + nv_mthd(priv, 0xa097, 0x1594, 0x00000000); + nv_mthd(priv, 0xa097, 0x1598, 0x00000001); + nv_mthd(priv, 0xa097, 0x159c, 0x00000001); + nv_mthd(priv, 0xa097, 0x15a0, 0x00000001); + nv_mthd(priv, 0xa097, 0x15a4, 0x00000001); + nv_mthd(priv, 0xa097, 0x0f54, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f58, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f5c, 0x00000000); + nv_mthd(priv, 0xa097, 0x19bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f9c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0fa0, 0x00000000); + nv_mthd(priv, 0xa097, 0x12cc, 0x00000000); + nv_mthd(priv, 0xa097, 0x12e8, 0x00000000); + nv_mthd(priv, 0xa097, 0x130c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1360, 0x00000000); + nv_mthd(priv, 0xa097, 0x1364, 0x00000000); + nv_mthd(priv, 0xa097, 0x1368, 0x00000000); + nv_mthd(priv, 0xa097, 0x136c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1370, 0x00000000); + nv_mthd(priv, 0xa097, 0x1374, 0x00000000); + nv_mthd(priv, 0xa097, 0x1378, 0x00000000); + nv_mthd(priv, 0xa097, 0x137c, 0x00000000); + nv_mthd(priv, 0xa097, 0x133c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1340, 0x00000001); + nv_mthd(priv, 0xa097, 0x1344, 0x00000002); + nv_mthd(priv, 0xa097, 0x1348, 0x00000001); + nv_mthd(priv, 0xa097, 0x134c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1350, 0x00000002); + nv_mthd(priv, 0xa097, 0x1358, 0x00000001); + nv_mthd(priv, 0xa097, 0x12e4, 0x00000000); + nv_mthd(priv, 0xa097, 0x131c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1320, 0x00000000); + nv_mthd(priv, 0xa097, 0x1324, 0x00000000); + nv_mthd(priv, 0xa097, 0x1328, 0x00000000); + nv_mthd(priv, 0xa097, 0x19c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x1140, 0x00000000); + nv_mthd(priv, 0xa097, 0x19c4, 0x00000000); + nv_mthd(priv, 0xa097, 0x19c8, 0x00001500); + nv_mthd(priv, 0xa097, 0x135c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f90, 0x00000000); + nv_mthd(priv, 0xa097, 0x19e0, 0x00000001); + nv_mthd(priv, 0xa097, 0x19e4, 0x00000001); + nv_mthd(priv, 0xa097, 0x19e8, 0x00000001); + nv_mthd(priv, 0xa097, 0x19ec, 0x00000001); + nv_mthd(priv, 0xa097, 0x19f0, 0x00000001); + nv_mthd(priv, 0xa097, 0x19f4, 0x00000001); + nv_mthd(priv, 0xa097, 0x19f8, 0x00000001); + nv_mthd(priv, 0xa097, 0x19fc, 0x00000001); + nv_mthd(priv, 0xa097, 0x19cc, 0x00000001); + nv_mthd(priv, 0xa097, 0x15b8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1a00, 0x00001111); + nv_mthd(priv, 0xa097, 0x1a04, 0x00000000); + nv_mthd(priv, 0xa097, 0x1a08, 0x00000000); + nv_mthd(priv, 0xa097, 0x1a0c, 0x00000000); + nv_mthd(priv, 0xa097, 0x1a10, 0x00000000); + nv_mthd(priv, 0xa097, 0x1a14, 0x00000000); + nv_mthd(priv, 0xa097, 0x1a18, 0x00000000); + nv_mthd(priv, 0xa097, 0x1a1c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d6c, 0xffff0000); + nv_mthd(priv, 0xa097, 0x0d70, 0xffff0000); + nv_mthd(priv, 0xa097, 0x10f8, 0x00001010); + nv_mthd(priv, 0xa097, 0x0d80, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d84, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d88, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d8c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0d90, 0x00000000); + nv_mthd(priv, 0xa097, 0x0da0, 0x00000000); + nv_mthd(priv, 0xa097, 0x07a4, 0x00000000); + nv_mthd(priv, 0xa097, 0x07a8, 0x00000000); + nv_mthd(priv, 0xa097, 0x1508, 0x80000000); + nv_mthd(priv, 0xa097, 0x150c, 0x40000000); + nv_mthd(priv, 0xa097, 0x1668, 0x00000000); + nv_mthd(priv, 0xa097, 0x0318, 0x00000008); + nv_mthd(priv, 0xa097, 0x031c, 0x00000008); + nv_mthd(priv, 0xa097, 0x0d9c, 0x00000001); + nv_mthd(priv, 0xa097, 0x0374, 0x00000000); + nv_mthd(priv, 0xa097, 0x0378, 0x00000020); + nv_mthd(priv, 0xa097, 0x07dc, 0x00000000); + nv_mthd(priv, 0xa097, 0x074c, 0x00000055); + nv_mthd(priv, 0xa097, 0x1420, 0x00000003); + nv_mthd(priv, 0xa097, 0x17bc, 0x00000000); + nv_mthd(priv, 0xa097, 0x17c0, 0x00000000); + nv_mthd(priv, 0xa097, 0x17c4, 0x00000001); + nv_mthd(priv, 0xa097, 0x1008, 0x00000008); + nv_mthd(priv, 0xa097, 0x100c, 0x00000040); + nv_mthd(priv, 0xa097, 0x1010, 0x0000012c); + nv_mthd(priv, 0xa097, 0x0d60, 0x00000040); + nv_mthd(priv, 0xa097, 0x075c, 0x00000003); + nv_mthd(priv, 0xa097, 0x1018, 0x00000020); + nv_mthd(priv, 0xa097, 0x101c, 0x00000001); + nv_mthd(priv, 0xa097, 0x1020, 0x00000020); + nv_mthd(priv, 0xa097, 0x1024, 0x00000001); + nv_mthd(priv, 0xa097, 0x1444, 0x00000000); + nv_mthd(priv, 0xa097, 0x1448, 0x00000000); + nv_mthd(priv, 0xa097, 0x144c, 0x00000000); + nv_mthd(priv, 0xa097, 0x0360, 0x20164010); + nv_mthd(priv, 0xa097, 0x0364, 0x00000020); + nv_mthd(priv, 0xa097, 0x0368, 0x00000000); + nv_mthd(priv, 0xa097, 0x0de4, 0x00000000); + nv_mthd(priv, 0xa097, 0x0204, 0x00000006); + nv_mthd(priv, 0xa097, 0x0208, 0x00000000); + nv_mthd(priv, 0xa097, 0x02cc, 0x003fffff); + nv_mthd(priv, 0xa097, 0x02d0, 0x003fffff); + nv_mthd(priv, 0xa097, 0x1220, 0x00000005); + nv_mthd(priv, 0xa097, 0x0fdc, 0x00000000); + nv_mthd(priv, 0xa097, 0x0f98, 0x00400008); + nv_mthd(priv, 0xa097, 0x1284, 0x08000080); + nv_mthd(priv, 0xa097, 0x1450, 0x00400008); + nv_mthd(priv, 0xa097, 0x1454, 0x08000080); + nv_mthd(priv, 0xa097, 0x0214, 0x00000000); +} + +static void +nve0_grctx_generate_902d(struct nvc0_graph_priv *priv) +{ + nv_mthd(priv, 0x902d, 0x0200, 0x000000cf); + nv_mthd(priv, 0x902d, 0x0204, 0x00000001); + nv_mthd(priv, 0x902d, 0x0208, 0x00000020); + nv_mthd(priv, 0x902d, 0x020c, 0x00000001); + nv_mthd(priv, 0x902d, 0x0210, 0x00000000); + nv_mthd(priv, 0x902d, 0x0214, 0x00000080); + nv_mthd(priv, 0x902d, 0x0218, 0x00000100); + nv_mthd(priv, 0x902d, 0x021c, 0x00000100); + nv_mthd(priv, 0x902d, 0x0220, 0x00000000); + nv_mthd(priv, 0x902d, 0x0224, 0x00000000); + nv_mthd(priv, 0x902d, 0x0230, 0x000000cf); + nv_mthd(priv, 0x902d, 0x0234, 0x00000001); + nv_mthd(priv, 0x902d, 0x0238, 0x00000020); + nv_mthd(priv, 0x902d, 0x023c, 0x00000001); + nv_mthd(priv, 0x902d, 0x0244, 0x00000080); + nv_mthd(priv, 0x902d, 0x0248, 0x00000100); + nv_mthd(priv, 0x902d, 0x024c, 0x00000100); + nv_mthd(priv, 0x902d, 0x3410, 0x00000000); +} + +static void +nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x404010, 0x0); + nv_wr32(priv, 0x404014, 0x0); + nv_wr32(priv, 0x404018, 0x0); + nv_wr32(priv, 0x40401c, 0x0); + nv_wr32(priv, 0x404020, 0x0); + nv_wr32(priv, 0x404024, 0xe000); + nv_wr32(priv, 0x404028, 0x0); + nv_wr32(priv, 0x4040a8, 0x0); + nv_wr32(priv, 0x4040ac, 0x0); + nv_wr32(priv, 0x4040b0, 0x0); + nv_wr32(priv, 0x4040b4, 0x0); + nv_wr32(priv, 0x4040b8, 0x0); + nv_wr32(priv, 0x4040bc, 0x0); + nv_wr32(priv, 0x4040c0, 0x0); + nv_wr32(priv, 0x4040c4, 0x0); + nv_wr32(priv, 0x4040c8, 0xf800008f); + nv_wr32(priv, 0x4040d0, 0x0); + nv_wr32(priv, 0x4040d4, 0x0); + nv_wr32(priv, 0x4040d8, 0x0); + nv_wr32(priv, 0x4040dc, 0x0); + nv_wr32(priv, 0x4040e0, 0x0); + nv_wr32(priv, 0x4040e4, 0x0); + nv_wr32(priv, 0x4040e8, 0x1000); + nv_wr32(priv, 0x4040f8, 0x0); + nv_wr32(priv, 0x404130, 0x0); + nv_wr32(priv, 0x404134, 0x0); + nv_wr32(priv, 0x404138, 0x20000040); + nv_wr32(priv, 0x404150, 0x2e); + nv_wr32(priv, 0x404154, 0x400); + nv_wr32(priv, 0x404158, 0x200); + nv_wr32(priv, 0x404164, 0x55); + nv_wr32(priv, 0x4041a0, 0x0); + nv_wr32(priv, 0x4041a4, 0x0); + nv_wr32(priv, 0x4041a8, 0x0); + nv_wr32(priv, 0x4041ac, 0x0); + nv_wr32(priv, 0x404200, 0x0); + nv_wr32(priv, 0x404204, 0x0); + nv_wr32(priv, 0x404208, 0x0); + nv_wr32(priv, 0x40420c, 0x0); +} + +static void +nve0_graph_generate_unk44xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x404404, 0x0); + nv_wr32(priv, 0x404408, 0x0); + nv_wr32(priv, 0x40440c, 0x0); + nv_wr32(priv, 0x404410, 0x0); + nv_wr32(priv, 0x404414, 0x0); + nv_wr32(priv, 0x404418, 0x0); + nv_wr32(priv, 0x40441c, 0x0); + nv_wr32(priv, 0x404420, 0x0); + nv_wr32(priv, 0x404424, 0x0); + nv_wr32(priv, 0x404428, 0x0); + nv_wr32(priv, 0x40442c, 0x0); + nv_wr32(priv, 0x404430, 0x0); + nv_wr32(priv, 0x404434, 0x0); + nv_wr32(priv, 0x404438, 0x0); + nv_wr32(priv, 0x404460, 0x0); + nv_wr32(priv, 0x404464, 0x0); + nv_wr32(priv, 0x404468, 0xffffff); + nv_wr32(priv, 0x40446c, 0x0); + nv_wr32(priv, 0x404480, 0x1); + nv_wr32(priv, 0x404498, 0x1); +} + +static void +nve0_graph_generate_unk46xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x404604, 0x14); + nv_wr32(priv, 0x404608, 0x0); + nv_wr32(priv, 0x40460c, 0x3fff); + nv_wr32(priv, 0x404610, 0x100); + nv_wr32(priv, 0x404618, 0x0); + nv_wr32(priv, 0x40461c, 0x0); + nv_wr32(priv, 0x404620, 0x0); + nv_wr32(priv, 0x404624, 0x0); + nv_wr32(priv, 0x40462c, 0x0); + nv_wr32(priv, 0x404630, 0x0); + nv_wr32(priv, 0x404640, 0x0); + nv_wr32(priv, 0x404654, 0x0); + nv_wr32(priv, 0x404660, 0x0); + nv_wr32(priv, 0x404678, 0x0); + nv_wr32(priv, 0x40467c, 0x2); + nv_wr32(priv, 0x404680, 0x0); + nv_wr32(priv, 0x404684, 0x0); + nv_wr32(priv, 0x404688, 0x0); + nv_wr32(priv, 0x40468c, 0x0); + nv_wr32(priv, 0x404690, 0x0); + nv_wr32(priv, 0x404694, 0x0); + nv_wr32(priv, 0x404698, 0x0); + nv_wr32(priv, 0x40469c, 0x0); + nv_wr32(priv, 0x4046a0, 0x7f0080); + nv_wr32(priv, 0x4046a4, 0x0); + nv_wr32(priv, 0x4046a8, 0x0); + nv_wr32(priv, 0x4046ac, 0x0); + nv_wr32(priv, 0x4046b0, 0x0); + nv_wr32(priv, 0x4046b4, 0x0); + nv_wr32(priv, 0x4046b8, 0x0); + nv_wr32(priv, 0x4046bc, 0x0); + nv_wr32(priv, 0x4046c0, 0x0); + nv_wr32(priv, 0x4046c8, 0x0); + nv_wr32(priv, 0x4046cc, 0x0); + nv_wr32(priv, 0x4046d0, 0x0); +} + +static void +nve0_graph_generate_unk47xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x404700, 0x0); + nv_wr32(priv, 0x404704, 0x0); + nv_wr32(priv, 0x404708, 0x0); + nv_wr32(priv, 0x404718, 0x0); + nv_wr32(priv, 0x40471c, 0x0); + nv_wr32(priv, 0x404720, 0x0); + nv_wr32(priv, 0x404724, 0x0); + nv_wr32(priv, 0x404728, 0x0); + nv_wr32(priv, 0x40472c, 0x0); + nv_wr32(priv, 0x404730, 0x0); + nv_wr32(priv, 0x404734, 0x100); + nv_wr32(priv, 0x404738, 0x0); + nv_wr32(priv, 0x40473c, 0x0); + nv_wr32(priv, 0x404744, 0x0); + nv_wr32(priv, 0x404748, 0x0); + nv_wr32(priv, 0x404754, 0x0); +} + +static void +nve0_graph_generate_unk58xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x405800, 0xf8000bf); + nv_wr32(priv, 0x405830, 0x2180648); + nv_wr32(priv, 0x405834, 0x8000000); + nv_wr32(priv, 0x405838, 0x0); + nv_wr32(priv, 0x405854, 0x0); + nv_wr32(priv, 0x405870, 0x1); + nv_wr32(priv, 0x405874, 0x1); + nv_wr32(priv, 0x405878, 0x1); + nv_wr32(priv, 0x40587c, 0x1); + nv_wr32(priv, 0x405a00, 0x0); + nv_wr32(priv, 0x405a04, 0x0); + nv_wr32(priv, 0x405a18, 0x0); + nv_wr32(priv, 0x405b00, 0x0); + nv_wr32(priv, 0x405b10, 0x1000); +} + +static void +nve0_graph_generate_unk60xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x406020, 0x4103c1); + nv_wr32(priv, 0x406028, 0x1); + nv_wr32(priv, 0x40602c, 0x1); + nv_wr32(priv, 0x406030, 0x1); + nv_wr32(priv, 0x406034, 0x1); +} + +static void +nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x4064a8, 0x0); + nv_wr32(priv, 0x4064ac, 0x3fff); + nv_wr32(priv, 0x4064b4, 0x0); + nv_wr32(priv, 0x4064b8, 0x0); + nv_wr32(priv, 0x4064c0, 0x801a00f0); + nv_wr32(priv, 0x4064c4, 0x192ffff); + nv_wr32(priv, 0x4064c8, 0x1800600); + nv_wr32(priv, 0x4064cc, 0x0); + nv_wr32(priv, 0x4064d0, 0x0); + nv_wr32(priv, 0x4064d4, 0x0); + nv_wr32(priv, 0x4064d8, 0x0); + nv_wr32(priv, 0x4064dc, 0x0); + nv_wr32(priv, 0x4064e0, 0x0); + nv_wr32(priv, 0x4064e4, 0x0); + nv_wr32(priv, 0x4064e8, 0x0); + nv_wr32(priv, 0x4064ec, 0x0); + nv_wr32(priv, 0x4064fc, 0x22a); +} + +static void +nve0_graph_generate_unk70xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x407040, 0x0); +} + +static void +nve0_graph_generate_unk78xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x407804, 0x23); + nv_wr32(priv, 0x40780c, 0xa418820); + nv_wr32(priv, 0x407810, 0x62080e6); + nv_wr32(priv, 0x407814, 0x20398a4); + nv_wr32(priv, 0x407818, 0xe629062); + nv_wr32(priv, 0x40781c, 0xa418820); + nv_wr32(priv, 0x407820, 0xe6); + nv_wr32(priv, 0x4078bc, 0x103); +} + +static void +nve0_graph_generate_unk80xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x408000, 0x0); + nv_wr32(priv, 0x408004, 0x0); + nv_wr32(priv, 0x408008, 0x30); + nv_wr32(priv, 0x40800c, 0x0); + nv_wr32(priv, 0x408010, 0x0); + nv_wr32(priv, 0x408014, 0x69); + nv_wr32(priv, 0x408018, 0xe100e100); + nv_wr32(priv, 0x408064, 0x0); +} + +static void +nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x408800, 0x2802a3c); + nv_wr32(priv, 0x408804, 0x40); + nv_wr32(priv, 0x408808, 0x1043e005); + nv_wr32(priv, 0x408840, 0xb); + nv_wr32(priv, 0x408900, 0x3080b801); + nv_wr32(priv, 0x408904, 0x62000001); + nv_wr32(priv, 0x408908, 0xc8102f); + nv_wr32(priv, 0x408980, 0x11d); +} + +static void +nve0_graph_generate_gpc(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x418380, 0x16); + nv_wr32(priv, 0x418400, 0x38004e00); + nv_wr32(priv, 0x418404, 0x71e0ffff); + nv_wr32(priv, 0x41840c, 0x1008); + nv_wr32(priv, 0x418410, 0xfff0fff); + nv_wr32(priv, 0x418414, 0x2200fff); + nv_wr32(priv, 0x418450, 0x0); + nv_wr32(priv, 0x418454, 0x0); + nv_wr32(priv, 0x418458, 0x0); + nv_wr32(priv, 0x41845c, 0x0); + nv_wr32(priv, 0x418460, 0x0); + nv_wr32(priv, 0x418464, 0x0); + nv_wr32(priv, 0x418468, 0x1); + nv_wr32(priv, 0x41846c, 0x0); + nv_wr32(priv, 0x418470, 0x0); + nv_wr32(priv, 0x418600, 0x1f); + nv_wr32(priv, 0x418684, 0xf); + nv_wr32(priv, 0x418700, 0x2); + nv_wr32(priv, 0x418704, 0x80); + nv_wr32(priv, 0x418708, 0x0); + nv_wr32(priv, 0x41870c, 0x0); + nv_wr32(priv, 0x418710, 0x0); + nv_wr32(priv, 0x418800, 0x7006860a); + nv_wr32(priv, 0x418808, 0x0); + nv_wr32(priv, 0x41880c, 0x0); + nv_wr32(priv, 0x418810, 0x0); + nv_wr32(priv, 0x418828, 0x44); + nv_wr32(priv, 0x418830, 0x10000001); + nv_wr32(priv, 0x4188d8, 0x8); + nv_wr32(priv, 0x4188e0, 0x1000000); + nv_wr32(priv, 0x4188e8, 0x0); + nv_wr32(priv, 0x4188ec, 0x0); + nv_wr32(priv, 0x4188f0, 0x0); + nv_wr32(priv, 0x4188f4, 0x0); + nv_wr32(priv, 0x4188f8, 0x0); + nv_wr32(priv, 0x4188fc, 0x20100018); + nv_wr32(priv, 0x41891c, 0xff00ff); + nv_wr32(priv, 0x418924, 0x0); + nv_wr32(priv, 0x418928, 0xffff00); + nv_wr32(priv, 0x41892c, 0xff00); + nv_wr32(priv, 0x418a00, 0x0); + nv_wr32(priv, 0x418a04, 0x0); + nv_wr32(priv, 0x418a08, 0x0); + nv_wr32(priv, 0x418a0c, 0x10000); + nv_wr32(priv, 0x418a10, 0x0); + nv_wr32(priv, 0x418a14, 0x0); + nv_wr32(priv, 0x418a18, 0x0); + nv_wr32(priv, 0x418a20, 0x0); + nv_wr32(priv, 0x418a24, 0x0); + nv_wr32(priv, 0x418a28, 0x0); + nv_wr32(priv, 0x418a2c, 0x10000); + nv_wr32(priv, 0x418a30, 0x0); + nv_wr32(priv, 0x418a34, 0x0); + nv_wr32(priv, 0x418a38, 0x0); + nv_wr32(priv, 0x418a40, 0x0); + nv_wr32(priv, 0x418a44, 0x0); + nv_wr32(priv, 0x418a48, 0x0); + nv_wr32(priv, 0x418a4c, 0x10000); + nv_wr32(priv, 0x418a50, 0x0); + nv_wr32(priv, 0x418a54, 0x0); + nv_wr32(priv, 0x418a58, 0x0); + nv_wr32(priv, 0x418a60, 0x0); + nv_wr32(priv, 0x418a64, 0x0); + nv_wr32(priv, 0x418a68, 0x0); + nv_wr32(priv, 0x418a6c, 0x10000); + nv_wr32(priv, 0x418a70, 0x0); + nv_wr32(priv, 0x418a74, 0x0); + nv_wr32(priv, 0x418a78, 0x0); + nv_wr32(priv, 0x418a80, 0x0); + nv_wr32(priv, 0x418a84, 0x0); + nv_wr32(priv, 0x418a88, 0x0); + nv_wr32(priv, 0x418a8c, 0x10000); + nv_wr32(priv, 0x418a90, 0x0); + nv_wr32(priv, 0x418a94, 0x0); + nv_wr32(priv, 0x418a98, 0x0); + nv_wr32(priv, 0x418aa0, 0x0); + nv_wr32(priv, 0x418aa4, 0x0); + nv_wr32(priv, 0x418aa8, 0x0); + nv_wr32(priv, 0x418aac, 0x10000); + nv_wr32(priv, 0x418ab0, 0x0); + nv_wr32(priv, 0x418ab4, 0x0); + nv_wr32(priv, 0x418ab8, 0x0); + nv_wr32(priv, 0x418ac0, 0x0); + nv_wr32(priv, 0x418ac4, 0x0); + nv_wr32(priv, 0x418ac8, 0x0); + nv_wr32(priv, 0x418acc, 0x10000); + nv_wr32(priv, 0x418ad0, 0x0); + nv_wr32(priv, 0x418ad4, 0x0); + nv_wr32(priv, 0x418ad8, 0x0); + nv_wr32(priv, 0x418ae0, 0x0); + nv_wr32(priv, 0x418ae4, 0x0); + nv_wr32(priv, 0x418ae8, 0x0); + nv_wr32(priv, 0x418aec, 0x10000); + nv_wr32(priv, 0x418af0, 0x0); + nv_wr32(priv, 0x418af4, 0x0); + nv_wr32(priv, 0x418af8, 0x0); + nv_wr32(priv, 0x418b00, 0x6); + nv_wr32(priv, 0x418b08, 0xa418820); + nv_wr32(priv, 0x418b0c, 0x62080e6); + nv_wr32(priv, 0x418b10, 0x20398a4); + nv_wr32(priv, 0x418b14, 0xe629062); + nv_wr32(priv, 0x418b18, 0xa418820); + nv_wr32(priv, 0x418b1c, 0xe6); + nv_wr32(priv, 0x418bb8, 0x103); + nv_wr32(priv, 0x418c08, 0x1); + nv_wr32(priv, 0x418c10, 0x0); + nv_wr32(priv, 0x418c14, 0x0); + nv_wr32(priv, 0x418c18, 0x0); + nv_wr32(priv, 0x418c1c, 0x0); + nv_wr32(priv, 0x418c20, 0x0); + nv_wr32(priv, 0x418c24, 0x0); + nv_wr32(priv, 0x418c28, 0x0); + nv_wr32(priv, 0x418c2c, 0x0); + nv_wr32(priv, 0x418c40, 0xffffffff); + nv_wr32(priv, 0x418c6c, 0x1); + nv_wr32(priv, 0x418c80, 0x20200004); + nv_wr32(priv, 0x418c8c, 0x1); + nv_wr32(priv, 0x419000, 0x780); + nv_wr32(priv, 0x419004, 0x0); + nv_wr32(priv, 0x419008, 0x0); + nv_wr32(priv, 0x419014, 0x4); +} + +static void +nve0_graph_generate_tpc(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x419848, 0x0); + nv_wr32(priv, 0x419864, 0x129); + nv_wr32(priv, 0x419888, 0x0); + nv_wr32(priv, 0x419a00, 0xf0); + nv_wr32(priv, 0x419a04, 0x1); + nv_wr32(priv, 0x419a08, 0x21); + nv_wr32(priv, 0x419a0c, 0x20000); + nv_wr32(priv, 0x419a10, 0x0); + nv_wr32(priv, 0x419a14, 0x200); + nv_wr32(priv, 0x419a1c, 0xc000); + nv_wr32(priv, 0x419a20, 0x800); + nv_wr32(priv, 0x419a30, 0x1); + nv_wr32(priv, 0x419ac4, 0x37f440); + nv_wr32(priv, 0x419c00, 0xa); + nv_wr32(priv, 0x419c04, 0x80000006); + nv_wr32(priv, 0x419c08, 0x2); + nv_wr32(priv, 0x419c20, 0x0); + nv_wr32(priv, 0x419c24, 0x84210); + nv_wr32(priv, 0x419c28, 0x3efbefbe); + nv_wr32(priv, 0x419ce8, 0x0); + nv_wr32(priv, 0x419cf4, 0x3203); + nv_wr32(priv, 0x419e04, 0x0); + nv_wr32(priv, 0x419e08, 0x0); + nv_wr32(priv, 0x419e0c, 0x0); + nv_wr32(priv, 0x419e10, 0x402); + nv_wr32(priv, 0x419e44, 0x13eff2); + nv_wr32(priv, 0x419e48, 0x0); + nv_wr32(priv, 0x419e4c, 0x7f); + nv_wr32(priv, 0x419e50, 0x0); + nv_wr32(priv, 0x419e54, 0x0); + nv_wr32(priv, 0x419e58, 0x0); + nv_wr32(priv, 0x419e5c, 0x0); + nv_wr32(priv, 0x419e60, 0x0); + nv_wr32(priv, 0x419e64, 0x0); + nv_wr32(priv, 0x419e68, 0x0); + nv_wr32(priv, 0x419e6c, 0x0); + nv_wr32(priv, 0x419e70, 0x0); + nv_wr32(priv, 0x419e74, 0x0); + nv_wr32(priv, 0x419e78, 0x0); + nv_wr32(priv, 0x419e7c, 0x0); + nv_wr32(priv, 0x419e80, 0x0); + nv_wr32(priv, 0x419e84, 0x0); + nv_wr32(priv, 0x419e88, 0x0); + nv_wr32(priv, 0x419e8c, 0x0); + nv_wr32(priv, 0x419e90, 0x0); + nv_wr32(priv, 0x419e94, 0x0); + nv_wr32(priv, 0x419e98, 0x0); + nv_wr32(priv, 0x419eac, 0x1fcf); + nv_wr32(priv, 0x419eb0, 0xd3f); + nv_wr32(priv, 0x419ec8, 0x1304f); + nv_wr32(priv, 0x419f30, 0x0); + nv_wr32(priv, 0x419f34, 0x0); + nv_wr32(priv, 0x419f38, 0x0); + nv_wr32(priv, 0x419f3c, 0x0); + nv_wr32(priv, 0x419f40, 0x0); + nv_wr32(priv, 0x419f44, 0x0); + nv_wr32(priv, 0x419f48, 0x0); + nv_wr32(priv, 0x419f4c, 0x0); + nv_wr32(priv, 0x419f58, 0x0); + nv_wr32(priv, 0x419f78, 0xb); +} + +static void +nve0_graph_generate_tpcunk(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x41be24, 0x6); + nv_wr32(priv, 0x41bec0, 0x12180000); + nv_wr32(priv, 0x41bec4, 0x37f7f); + nv_wr32(priv, 0x41bee4, 0x6480430); + nv_wr32(priv, 0x41bf00, 0xa418820); + nv_wr32(priv, 0x41bf04, 0x62080e6); + nv_wr32(priv, 0x41bf08, 0x20398a4); + nv_wr32(priv, 0x41bf0c, 0xe629062); + nv_wr32(priv, 0x41bf10, 0xa418820); + nv_wr32(priv, 0x41bf14, 0xe6); + nv_wr32(priv, 0x41bfd0, 0x900103); + nv_wr32(priv, 0x41bfe0, 0x400001); + nv_wr32(priv, 0x41bfe4, 0x0); +} + +int +nve0_grctx_generate(struct nvc0_graph_priv *priv) +{ + struct nvc0_grctx info; + int ret, i, gpc, tpc, id; + u32 data[6] = {}, data2[2] = {}, tmp; + u32 tpc_set = 0, tpc_mask = 0; + u32 magic[GPC_MAX][2], offset; + u8 tpcnr[GPC_MAX], a, b; + u8 shift, ntpcv; + + ret = nvc0_grctx_init(priv, &info); + if (ret) + return ret; + + nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nv_wr32(priv, 0x400204, 0x00000000); + nv_wr32(priv, 0x400208, 0x00000000); + + nve0_graph_generate_unk40xx(priv); + nve0_graph_generate_unk44xx(priv); + nve0_graph_generate_unk46xx(priv); + nve0_graph_generate_unk47xx(priv); + nve0_graph_generate_unk58xx(priv); + nve0_graph_generate_unk60xx(priv); + nve0_graph_generate_unk64xx(priv); + nve0_graph_generate_unk70xx(priv); + nve0_graph_generate_unk78xx(priv); + nve0_graph_generate_unk80xx(priv); + nve0_graph_generate_unk88xx(priv); + nve0_graph_generate_gpc(priv); + nve0_graph_generate_tpc(priv); + nve0_graph_generate_tpcunk(priv); + + nv_wr32(priv, 0x404154, 0x0); + + mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); + mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); + mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); + mmio_list(0x40800c, 0x00000000, 8, 1); + mmio_list(0x408010, 0x80000000, 0, 0); + mmio_list(0x419004, 0x00000000, 8, 1); + mmio_list(0x419008, 0x00000000, 0, 0); + mmio_list(0x4064cc, 0x80000000, 0, 0); + mmio_list(0x408004, 0x00000000, 8, 0); + mmio_list(0x408008, 0x80000030, 0, 0); + mmio_list(0x418808, 0x00000000, 8, 0); + mmio_list(0x41880c, 0x80000030, 0, 0); + mmio_list(0x4064c8, 0x01800600, 0, 0); + mmio_list(0x418810, 0x80000000, 12, 2); + mmio_list(0x419848, 0x10000000, 12, 2); + mmio_list(0x405830, 0x02180648, 0, 0); + mmio_list(0x4064c4, 0x0192ffff, 0, 0); + for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) { + u16 magic0 = 0x0218 * priv->tpc_nr[gpc]; + u16 magic1 = 0x0648 * priv->tpc_nr[gpc]; + magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset; + magic[gpc][1] = 0x00000000 | (magic1 << 16); + offset += 0x0324 * priv->tpc_nr[gpc]; + } + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0); + mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0); + offset += 0x07ff * priv->tpc_nr[gpc]; + } + mmio_list(0x17e91c, 0x06060609, 0, 0); + mmio_list(0x17e920, 0x00090a05, 0, 0); + + nv_wr32(priv, 0x418c6c, 0x1); + nv_wr32(priv, 0x41980c, 0x10); + nv_wr32(priv, 0x41be08, 0x4); + nv_wr32(priv, 0x4064c0, 0x801a00f0); + nv_wr32(priv, 0x405800, 0xf8000bf); + nv_wr32(priv, 0x419c00, 0xa); + + for (tpc = 0, id = 0; tpc < 4; tpc++) { + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + if (tpc < priv->tpc_nr[gpc]) { + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0698), id); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x04e8), id); + nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0088), id++); + } + + nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]); + nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]); + } + } + + tmp = 0; + for (i = 0; i < priv->gpc_nr; i++) + tmp |= priv->tpc_nr[i] << (i * 4); + nv_wr32(priv, 0x406028, tmp); + nv_wr32(priv, 0x405870, tmp); + + nv_wr32(priv, 0x40602c, 0x0); + nv_wr32(priv, 0x405874, 0x0); + nv_wr32(priv, 0x406030, 0x0); + nv_wr32(priv, 0x405878, 0x0); + nv_wr32(priv, 0x406034, 0x0); + nv_wr32(priv, 0x40587c, 0x0); + + /* calculate first set of magics */ + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + + gpc = -1; + for (tpc = 0; tpc < priv->tpc_total; tpc++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpcnr[gpc]--; + + data[tpc / 6] |= gpc << ((tpc % 6) * 5); + } + + for (; tpc < 32; tpc++) + data[tpc / 6] |= 7 << ((tpc % 6) * 5); + + /* and the second... */ + shift = 0; + ntpcv = priv->tpc_total; + while (!(ntpcv & (1 << 4))) { + ntpcv <<= 1; + shift++; + } + + data2[0] = ntpcv << 16; + data2[0] |= shift << 21; + data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); + data2[0] |= priv->tpc_total << 8; + data2[0] |= priv->magic_not_rop_nr; + for (i = 1; i < 7; i++) + data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); + + /* and write it all the various parts of PGRAPH */ + nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) | priv->magic_not_rop_nr); + for (i = 0; i < 6; i++) + nv_wr32(priv, 0x418b08 + (i * 4), data[i]); + + nv_wr32(priv, 0x41bfd0, data2[0]); + nv_wr32(priv, 0x41bfe4, data2[1]); + for (i = 0; i < 6; i++) + nv_wr32(priv, 0x41bf00 + (i * 4), data[i]); + + nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) | priv->magic_not_rop_nr); + for (i = 0; i < 6; i++) + nv_wr32(priv, 0x40780c + (i * 4), data[i]); + + + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + for (gpc = 0; gpc < priv->gpc_nr; gpc++) + tpc_mask |= ((1 << priv->tpc_nr[gpc]) - 1) << (gpc * 8); + + for (i = 0, gpc = -1, b = -1; i < 32; i++) { + a = (i * (priv->tpc_total - 1)) / 32; + if (a != b) { + b = a; + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; + + tpc_set |= 1 << ((gpc * 8) + tpc); + } + + nv_wr32(priv, 0x406800 + (i * 0x20), tpc_set); + nv_wr32(priv, 0x406c00 + (i * 0x20), tpc_set ^ tpc_mask); + } + + for (i = 0; i < 8; i++) + nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000); + + nv_wr32(priv, 0x405b00, 0x201); + nv_wr32(priv, 0x408850, 0x2); + nv_wr32(priv, 0x408958, 0x2); + nv_wr32(priv, 0x419f78, 0xa); + + nve0_grctx_generate_icmd(priv); + nve0_grctx_generate_a097(priv); + nve0_grctx_generate_902d(priv); + + nv_mask(priv, 0x000260, 0x00000001, 0x00000001); + nv_wr32(priv, 0x418800, 0x7026860a); //XXX + nv_wr32(priv, 0x41be10, 0x00bb8bc7); //XXX + return nvc0_grctx_fini(&info); +} diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc new file mode 100644 index 00000000000..b86cc60dcd5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc @@ -0,0 +1,539 @@ +/* fuc microcode for nvc0 PGRAPH/GPC + * + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +/* To build: + * m4 gpcnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o gpcnvc0.fuc.h + */ + +/* TODO + * - bracket certain functions with scratch writes, useful for debugging + * - watchdog timer around ctx operations + */ + +.section #nvc0_grgpc_data +include(`nvc0.fuc') +gpc_id: .b32 0 +gpc_mmio_list_head: .b32 0 +gpc_mmio_list_tail: .b32 0 + +tpc_count: .b32 0 +tpc_mask: .b32 0 +tpc_mmio_list_head: .b32 0 +tpc_mmio_list_tail: .b32 0 + +cmd_queue: queue_init + +// chipset descriptions +chipsets: +.b8 0xc0 0 0 0 +.b16 #nvc0_gpc_mmio_head +.b16 #nvc0_gpc_mmio_tail +.b16 #nvc0_tpc_mmio_head +.b16 #nvc0_tpc_mmio_tail +.b8 0xc1 0 0 0 +.b16 #nvc0_gpc_mmio_head +.b16 #nvc1_gpc_mmio_tail +.b16 #nvc0_tpc_mmio_head +.b16 #nvc1_tpc_mmio_tail +.b8 0xc3 0 0 0 +.b16 #nvc0_gpc_mmio_head +.b16 #nvc0_gpc_mmio_tail +.b16 #nvc0_tpc_mmio_head +.b16 #nvc3_tpc_mmio_tail +.b8 0xc4 0 0 0 +.b16 #nvc0_gpc_mmio_head +.b16 #nvc0_gpc_mmio_tail +.b16 #nvc0_tpc_mmio_head +.b16 #nvc3_tpc_mmio_tail +.b8 0xc8 0 0 0 +.b16 #nvc0_gpc_mmio_head +.b16 #nvc0_gpc_mmio_tail +.b16 #nvc0_tpc_mmio_head +.b16 #nvc0_tpc_mmio_tail +.b8 0xce 0 0 0 +.b16 #nvc0_gpc_mmio_head +.b16 #nvc0_gpc_mmio_tail +.b16 #nvc0_tpc_mmio_head +.b16 #nvc3_tpc_mmio_tail +.b8 0xcf 0 0 0 +.b16 #nvc0_gpc_mmio_head +.b16 #nvc0_gpc_mmio_tail +.b16 #nvc0_tpc_mmio_head +.b16 #nvcf_tpc_mmio_tail +.b8 0xd9 0 0 0 +.b16 #nvd9_gpc_mmio_head +.b16 #nvd9_gpc_mmio_tail +.b16 #nvd9_tpc_mmio_head +.b16 #nvd9_tpc_mmio_tail +.b8 0 0 0 0 + +// GPC mmio lists +nvc0_gpc_mmio_head: +mmctx_data(0x000380, 1) +mmctx_data(0x000400, 6) +mmctx_data(0x000450, 9) +mmctx_data(0x000600, 1) +mmctx_data(0x000684, 1) +mmctx_data(0x000700, 5) +mmctx_data(0x000800, 1) +mmctx_data(0x000808, 3) +mmctx_data(0x000828, 1) +mmctx_data(0x000830, 1) +mmctx_data(0x0008d8, 1) +mmctx_data(0x0008e0, 1) +mmctx_data(0x0008e8, 6) +mmctx_data(0x00091c, 1) +mmctx_data(0x000924, 3) +mmctx_data(0x000b00, 1) +mmctx_data(0x000b08, 6) +mmctx_data(0x000bb8, 1) +mmctx_data(0x000c08, 1) +mmctx_data(0x000c10, 8) +mmctx_data(0x000c80, 1) +mmctx_data(0x000c8c, 1) +mmctx_data(0x001000, 3) +mmctx_data(0x001014, 1) +nvc0_gpc_mmio_tail: +mmctx_data(0x000c6c, 1); +nvc1_gpc_mmio_tail: + +nvd9_gpc_mmio_head: +mmctx_data(0x000380, 1) +mmctx_data(0x000400, 2) +mmctx_data(0x00040c, 3) +mmctx_data(0x000450, 9) +mmctx_data(0x000600, 1) +mmctx_data(0x000684, 1) +mmctx_data(0x000700, 5) +mmctx_data(0x000800, 1) +mmctx_data(0x000808, 3) +mmctx_data(0x000828, 1) +mmctx_data(0x000830, 1) +mmctx_data(0x0008d8, 1) +mmctx_data(0x0008e0, 1) +mmctx_data(0x0008e8, 6) +mmctx_data(0x00091c, 1) +mmctx_data(0x000924, 3) +mmctx_data(0x000b00, 1) +mmctx_data(0x000b08, 6) +mmctx_data(0x000bb8, 1) +mmctx_data(0x000c08, 1) +mmctx_data(0x000c10, 8) +mmctx_data(0x000c6c, 1) +mmctx_data(0x000c80, 1) +mmctx_data(0x000c8c, 1) +mmctx_data(0x001000, 3) +mmctx_data(0x001014, 1) +nvd9_gpc_mmio_tail: + +// TPC mmio lists +nvc0_tpc_mmio_head: +mmctx_data(0x000018, 1) +mmctx_data(0x00003c, 1) +mmctx_data(0x000048, 1) +mmctx_data(0x000064, 1) +mmctx_data(0x000088, 1) +mmctx_data(0x000200, 6) +mmctx_data(0x00021c, 2) +mmctx_data(0x000300, 6) +mmctx_data(0x0003d0, 1) +mmctx_data(0x0003e0, 2) +mmctx_data(0x000400, 3) +mmctx_data(0x000420, 1) +mmctx_data(0x0004b0, 1) +mmctx_data(0x0004e8, 1) +mmctx_data(0x0004f4, 1) +mmctx_data(0x000520, 2) +mmctx_data(0x000604, 4) +mmctx_data(0x000644, 20) +mmctx_data(0x000698, 1) +mmctx_data(0x000750, 2) +nvc0_tpc_mmio_tail: +mmctx_data(0x000758, 1) +mmctx_data(0x0002c4, 1) +mmctx_data(0x0006e0, 1) +nvcf_tpc_mmio_tail: +mmctx_data(0x0004bc, 1) +nvc3_tpc_mmio_tail: +mmctx_data(0x000544, 1) +nvc1_tpc_mmio_tail: + +nvd9_tpc_mmio_head: +mmctx_data(0x000018, 1) +mmctx_data(0x00003c, 1) +mmctx_data(0x000048, 1) +mmctx_data(0x000064, 1) +mmctx_data(0x000088, 1) +mmctx_data(0x000200, 6) +mmctx_data(0x00021c, 2) +mmctx_data(0x0002c4, 1) +mmctx_data(0x000300, 6) +mmctx_data(0x0003d0, 1) +mmctx_data(0x0003e0, 2) +mmctx_data(0x000400, 3) +mmctx_data(0x000420, 3) +mmctx_data(0x0004b0, 1) +mmctx_data(0x0004e8, 1) +mmctx_data(0x0004f4, 1) +mmctx_data(0x000520, 2) +mmctx_data(0x000544, 1) +mmctx_data(0x000604, 4) +mmctx_data(0x000644, 20) +mmctx_data(0x000698, 1) +mmctx_data(0x0006e0, 1) +mmctx_data(0x000750, 3) +nvd9_tpc_mmio_tail: + +.section #nvc0_grgpc_code +bra #init +define(`include_code') +include(`nvc0.fuc') + +// reports an exception to the host +// +// In: $r15 error code (see nvc0.fuc) +// +error: + push $r14 + mov $r14 -0x67ec // 0x9814 + sethi $r14 0x400000 + call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code + add b32 $r14 0x41c + mov $r15 1 + call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET + pop $r14 + ret + +// GPC fuc initialisation, executed by triggering ucode start, will +// fall through to main loop after completion. +// +// Input: +// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh) +// CC_SCRATCH[1]: context base +// +// Output: +// CC_SCRATCH[0]: +// 31:31: set to signal completion +// CC_SCRATCH[1]: +// 31:0: GPC context size +// +init: + clear b32 $r0 + mov $sp $r0 + + // enable fifo access + mov $r1 0x1200 + mov $r2 2 + iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE + + // setup i0 handler, and route all interrupts to it + mov $r1 #ih + mov $iv0 $r1 + mov $r1 0x400 + iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH + + // enable fifo interrupt + mov $r2 4 + iowr I[$r1 + 0x000] $r2 // INTR_EN_SET + + // enable interrupts + bset $flags ie0 + + // figure out which GPC we are, and how many TPCs we have + mov $r1 0x608 + shl b32 $r1 6 + iord $r2 I[$r1 + 0x000] // UNITS + mov $r3 1 + and $r2 0x1f + shl b32 $r3 $r2 + sub b32 $r3 1 + st b32 D[$r0 + #tpc_count] $r2 + st b32 D[$r0 + #tpc_mask] $r3 + add b32 $r1 0x400 + iord $r2 I[$r1 + 0x000] // MYINDEX + st b32 D[$r0 + #gpc_id] $r2 + + // find context data for this chipset + mov $r2 0x800 + shl b32 $r2 6 + iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0] + mov $r1 #chipsets - 12 + init_find_chipset: + add b32 $r1 12 + ld b32 $r3 D[$r1 + 0x00] + cmpu b32 $r3 $r2 + bra e #init_context + cmpu b32 $r3 0 + bra ne #init_find_chipset + // unknown chipset + ret + + // initialise context base, and size tracking + init_context: + mov $r2 0x800 + shl b32 $r2 6 + iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base + clear b32 $r3 // track GPC context size here + + // set mmctx base addresses now so we don't have to do it later, + // they don't currently ever change + mov $r4 0x700 + shl b32 $r4 6 + shr b32 $r5 $r2 8 + iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE + iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE + + // calculate GPC mmio context size, store the chipset-specific + // mmio list pointers somewhere we can get at them later without + // re-parsing the chipset list + clear b32 $r14 + clear b32 $r15 + ld b16 $r14 D[$r1 + 4] + ld b16 $r15 D[$r1 + 6] + st b16 D[$r0 + #gpc_mmio_list_head] $r14 + st b16 D[$r0 + #gpc_mmio_list_tail] $r15 + call #mmctx_size + add b32 $r2 $r15 + add b32 $r3 $r15 + + // calculate per-TPC mmio context size, store the list pointers + ld b16 $r14 D[$r1 + 8] + ld b16 $r15 D[$r1 + 10] + st b16 D[$r0 + #tpc_mmio_list_head] $r14 + st b16 D[$r0 + #tpc_mmio_list_tail] $r15 + call #mmctx_size + ld b32 $r14 D[$r0 + #tpc_count] + mulu $r14 $r15 + add b32 $r2 $r14 + add b32 $r3 $r14 + + // round up base/size to 256 byte boundary (for strand SWBASE) + add b32 $r4 0x1300 + shr b32 $r3 2 + iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!? + shr b32 $r2 8 + shr b32 $r3 6 + add b32 $r2 1 + add b32 $r3 1 + shl b32 $r2 8 + shl b32 $r3 8 + + // calculate size of strand context data + mov b32 $r15 $r2 + call #strand_ctx_init + add b32 $r3 $r15 + + // save context size, and tell HUB we're done + mov $r1 0x800 + shl b32 $r1 6 + iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size + add b32 $r1 0x800 + clear b32 $r2 + bset $r2 31 + iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000 + +// Main program loop, very simple, sleeps until woken up by the interrupt +// handler, pulls a command from the queue and executes its handler +// +main: + bset $flags $p0 + sleep $p0 + mov $r13 #cmd_queue + call #queue_get + bra $p1 #main + + // 0x0000-0x0003 are all context transfers + cmpu b32 $r14 0x04 + bra nc #main_not_ctx_xfer + // fetch $flags and mask off $p1/$p2 + mov $r1 $flags + mov $r2 0x0006 + not b32 $r2 + and $r1 $r2 + // set $p1/$p2 according to transfer type + shl b32 $r14 1 + or $r1 $r14 + mov $flags $r1 + // transfer context data + call #ctx_xfer + bra #main + + main_not_ctx_xfer: + shl b32 $r15 $r14 16 + or $r15 E_BAD_COMMAND + call #error + bra #main + +// interrupt handler +ih: + push $r8 + mov $r8 $flags + push $r8 + push $r9 + push $r10 + push $r11 + push $r13 + push $r14 + push $r15 + + // incoming fifo command? + iord $r10 I[$r0 + 0x200] // INTR + and $r11 $r10 0x00000004 + bra e #ih_no_fifo + // queue incoming fifo command for later processing + mov $r11 0x1900 + mov $r13 #cmd_queue + iord $r14 I[$r11 + 0x100] // FIFO_CMD + iord $r15 I[$r11 + 0x000] // FIFO_DATA + call #queue_put + add b32 $r11 0x400 + mov $r14 1 + iowr I[$r11 + 0x000] $r14 // FIFO_ACK + + // ack, and wake up main() + ih_no_fifo: + iowr I[$r0 + 0x100] $r10 // INTR_ACK + + pop $r15 + pop $r14 + pop $r13 + pop $r11 + pop $r10 + pop $r9 + pop $r8 + mov $flags $r8 + pop $r8 + bclr $flags $p0 + iret + +// Set this GPC's bit in HUB_BAR, used to signal completion of various +// activities to the HUB fuc +// +hub_barrier_done: + mov $r15 1 + ld b32 $r14 D[$r0 + #gpc_id] + shl b32 $r15 $r14 + mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET + sethi $r14 0x400000 + call #nv_wr32 + ret + +// Disables various things, waits a bit, and re-enables them.. +// +// Not sure how exactly this helps, perhaps "ENABLE" is not such a +// good description for the bits we turn off? Anyways, without this, +// funny things happen. +// +ctx_redswitch: + mov $r14 0x614 + shl b32 $r14 6 + mov $r15 0x020 + iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER + mov $r15 8 + ctx_redswitch_delay: + sub b32 $r15 1 + bra ne #ctx_redswitch_delay + mov $r15 0xa20 + iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER + ret + +// Transfer GPC context data between GPU and storage area +// +// In: $r15 context base address +// $p1 clear on save, set on load +// $p2 set if opposite direction done/will be done, so: +// on save it means: "a load will follow this save" +// on load it means: "a save preceeded this load" +// +ctx_xfer: + // set context base address + mov $r1 0xa04 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r15// MEM_BASE + bra not $p1 #ctx_xfer_not_load + call #ctx_redswitch + ctx_xfer_not_load: + + // strands + mov $r1 0x4afc + sethi $r1 0x20000 + mov $r2 0xc + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c + call #strand_wait + mov $r2 0x47fc + sethi $r2 0x20000 + iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00 + xbit $r2 $flags $p1 + add b32 $r2 3 + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD) + + // mmio context + xbit $r10 $flags $p1 // direction + or $r10 2 // first + mov $r11 0x0000 + sethi $r11 0x500000 + ld b32 $r12 D[$r0 + #gpc_id] + shl b32 $r12 15 + add b32 $r11 $r12 // base = NV_PGRAPH_GPCn + ld b32 $r12 D[$r0 + #gpc_mmio_list_head] + ld b32 $r13 D[$r0 + #gpc_mmio_list_tail] + mov $r14 0 // not multi + call #mmctx_xfer + + // per-TPC mmio context + xbit $r10 $flags $p1 // direction + or $r10 4 // last + mov $r11 0x4000 + sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0 + ld b32 $r12 D[$r0 + #gpc_id] + shl b32 $r12 15 + add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0 + ld b32 $r12 D[$r0 + #tpc_mmio_list_head] + ld b32 $r13 D[$r0 + #tpc_mmio_list_tail] + ld b32 $r15 D[$r0 + #tpc_mask] + mov $r14 0x800 // stride = 0x800 + call #mmctx_xfer + + // wait for strands to finish + call #strand_wait + + // if load, or a save without a load following, do some + // unknown stuff that's done after finishing a block of + // strand commands + bra $p1 #ctx_xfer_post + bra not $p2 #ctx_xfer_done + ctx_xfer_post: + mov $r1 0x4afc + sethi $r1 0x20000 + mov $r2 0xd + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d + call #strand_wait + + // mark completion in HUB's barrier + ctx_xfer_done: + call #hub_barrier_done + ret + +.align 256 diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h new file mode 100644 index 00000000000..96050ddb22c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h @@ -0,0 +1,604 @@ +uint32_t nvc0_grgpc_data[] = { +/* 0x0000: gpc_id */ + 0x00000000, +/* 0x0004: gpc_mmio_list_head */ + 0x00000000, +/* 0x0008: gpc_mmio_list_tail */ + 0x00000000, +/* 0x000c: tpc_count */ + 0x00000000, +/* 0x0010: tpc_mask */ + 0x00000000, +/* 0x0014: tpc_mmio_list_head */ + 0x00000000, +/* 0x0018: tpc_mmio_list_tail */ + 0x00000000, +/* 0x001c: cmd_queue */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0064: chipsets */ + 0x000000c0, + 0x012800c8, + 0x01e40194, + 0x000000c1, + 0x012c00c8, + 0x01f80194, + 0x000000c3, + 0x012800c8, + 0x01f40194, + 0x000000c4, + 0x012800c8, + 0x01f40194, + 0x000000c8, + 0x012800c8, + 0x01e40194, + 0x000000ce, + 0x012800c8, + 0x01f40194, + 0x000000cf, + 0x012800c8, + 0x01f00194, + 0x000000d9, + 0x0194012c, + 0x025401f8, + 0x00000000, +/* 0x00c8: nvc0_gpc_mmio_head */ + 0x00000380, + 0x14000400, + 0x20000450, + 0x00000600, + 0x00000684, + 0x10000700, + 0x00000800, + 0x08000808, + 0x00000828, + 0x00000830, + 0x000008d8, + 0x000008e0, + 0x140008e8, + 0x0000091c, + 0x08000924, + 0x00000b00, + 0x14000b08, + 0x00000bb8, + 0x00000c08, + 0x1c000c10, + 0x00000c80, + 0x00000c8c, + 0x08001000, + 0x00001014, +/* 0x0128: nvc0_gpc_mmio_tail */ + 0x00000c6c, +/* 0x012c: nvc1_gpc_mmio_tail */ +/* 0x012c: nvd9_gpc_mmio_head */ + 0x00000380, + 0x04000400, + 0x0800040c, + 0x20000450, + 0x00000600, + 0x00000684, + 0x10000700, + 0x00000800, + 0x08000808, + 0x00000828, + 0x00000830, + 0x000008d8, + 0x000008e0, + 0x140008e8, + 0x0000091c, + 0x08000924, + 0x00000b00, + 0x14000b08, + 0x00000bb8, + 0x00000c08, + 0x1c000c10, + 0x00000c6c, + 0x00000c80, + 0x00000c8c, + 0x08001000, + 0x00001014, +/* 0x0194: nvd9_gpc_mmio_tail */ +/* 0x0194: nvc0_tpc_mmio_head */ + 0x00000018, + 0x0000003c, + 0x00000048, + 0x00000064, + 0x00000088, + 0x14000200, + 0x0400021c, + 0x14000300, + 0x000003d0, + 0x040003e0, + 0x08000400, + 0x00000420, + 0x000004b0, + 0x000004e8, + 0x000004f4, + 0x04000520, + 0x0c000604, + 0x4c000644, + 0x00000698, + 0x04000750, +/* 0x01e4: nvc0_tpc_mmio_tail */ + 0x00000758, + 0x000002c4, + 0x000006e0, +/* 0x01f0: nvcf_tpc_mmio_tail */ + 0x000004bc, +/* 0x01f4: nvc3_tpc_mmio_tail */ + 0x00000544, +/* 0x01f8: nvc1_tpc_mmio_tail */ +/* 0x01f8: nvd9_tpc_mmio_head */ + 0x00000018, + 0x0000003c, + 0x00000048, + 0x00000064, + 0x00000088, + 0x14000200, + 0x0400021c, + 0x000002c4, + 0x14000300, + 0x000003d0, + 0x040003e0, + 0x08000400, + 0x08000420, + 0x000004b0, + 0x000004e8, + 0x000004f4, + 0x04000520, + 0x00000544, + 0x0c000604, + 0x4c000644, + 0x00000698, + 0x000006e0, + 0x08000750, +}; + +uint32_t nvc0_grgpc_code[] = { + 0x03060ef5, +/* 0x0004: queue_put */ + 0x9800d898, + 0x86f001d9, + 0x0489b808, + 0xf00c1bf4, + 0x21f502f7, + 0x00f802ec, +/* 0x001c: queue_put_next */ + 0xb60798c4, + 0x8dbb0384, + 0x0880b600, + 0x80008e80, + 0x90b6018f, + 0x0f94f001, + 0xf801d980, +/* 0x0039: queue_get */ + 0x0131f400, + 0x9800d898, + 0x89b801d9, + 0x210bf404, + 0xb60789c4, + 0x9dbb0394, + 0x0890b600, + 0x98009e98, + 0x80b6019f, + 0x0f84f001, + 0xf400d880, +/* 0x0066: queue_get_done */ + 0x00f80132, +/* 0x0068: nv_rd32 */ + 0x0728b7f1, + 0xb906b4b6, + 0xc9f002ec, + 0x00bcd01f, +/* 0x0078: nv_rd32_wait */ + 0xc800bccf, + 0x1bf41fcc, + 0x06a7f0fa, + 0x010321f5, + 0xf840bfcf, +/* 0x008d: nv_wr32 */ + 0x28b7f100, + 0x06b4b607, + 0xb980bfd0, + 0xc9f002ec, + 0x1ec9f01f, +/* 0x00a3: nv_wr32_wait */ + 0xcf00bcd0, + 0xccc800bc, + 0xfa1bf41f, +/* 0x00ae: watchdog_reset */ + 0x87f100f8, + 0x84b60430, + 0x1ff9f006, + 0xf8008fd0, +/* 0x00bd: watchdog_clear */ + 0x3087f100, + 0x0684b604, + 0xf80080d0, +/* 0x00c9: wait_donez */ + 0x3c87f100, + 0x0684b608, + 0x99f094bd, + 0x0089d000, + 0x081887f1, + 0xd00684b6, +/* 0x00e2: wait_done_wait_donez */ + 0x87f1008a, + 0x84b60400, + 0x0088cf06, + 0xf4888aff, + 0x87f1f31b, + 0x84b6085c, + 0xf094bd06, + 0x89d00099, +/* 0x0103: wait_doneo */ + 0xf100f800, + 0xb6083c87, + 0x94bd0684, + 0xd00099f0, + 0x87f10089, + 0x84b60818, + 0x008ad006, +/* 0x011c: wait_done_wait_doneo */ + 0x040087f1, + 0xcf0684b6, + 0x8aff0088, + 0xf30bf488, + 0x085c87f1, + 0xbd0684b6, + 0x0099f094, + 0xf80089d0, +/* 0x013d: mmctx_size */ +/* 0x013f: nv_mmctx_size_loop */ + 0x9894bd00, + 0x85b600e8, + 0x0180b61a, + 0xbb0284b6, + 0xe0b60098, + 0x04efb804, + 0xb9eb1bf4, + 0x00f8029f, +/* 0x015c: mmctx_xfer */ + 0x083c87f1, + 0xbd0684b6, + 0x0199f094, + 0xf10089d0, + 0xb6071087, + 0x94bd0684, + 0xf405bbfd, + 0x8bd0090b, + 0x0099f000, +/* 0x0180: mmctx_base_disabled */ + 0xf405eefd, + 0x8ed00c0b, + 0xc08fd080, +/* 0x018f: mmctx_multi_disabled */ + 0xb70199f0, + 0xc8010080, + 0xb4b600ab, + 0x0cb9f010, + 0xb601aec8, + 0xbefd11e4, + 0x008bd005, +/* 0x01a8: mmctx_exec_loop */ +/* 0x01a8: mmctx_wait_free */ + 0xf0008ecf, + 0x0bf41fe4, + 0x00ce98fa, + 0xd005e9fd, + 0xc0b6c08e, + 0x04cdb804, + 0xc8e81bf4, + 0x1bf402ab, +/* 0x01c9: mmctx_fini_wait */ + 0x008bcf18, + 0xb01fb4f0, + 0x1bf410b4, + 0x02a7f0f7, + 0xf4c921f4, +/* 0x01de: mmctx_stop */ + 0xabc81b0e, + 0x10b4b600, + 0xf00cb9f0, + 0x8bd012b9, +/* 0x01ed: mmctx_stop_wait */ + 0x008bcf00, + 0xf412bbc8, +/* 0x01f6: mmctx_done */ + 0x87f1fa1b, + 0x84b6085c, + 0xf094bd06, + 0x89d00199, +/* 0x0207: strand_wait */ + 0xf900f800, + 0x02a7f0a0, + 0xfcc921f4, +/* 0x0213: strand_pre */ + 0xf100f8a0, + 0xf04afc87, + 0x97f00283, + 0x0089d00c, + 0x020721f5, +/* 0x0226: strand_post */ + 0x87f100f8, + 0x83f04afc, + 0x0d97f002, + 0xf50089d0, + 0xf8020721, +/* 0x0239: strand_set */ + 0xfca7f100, + 0x02a3f04f, + 0x0500aba2, + 0xd00fc7f0, + 0xc7f000ac, + 0x00bcd00b, + 0x020721f5, + 0xf000aed0, + 0xbcd00ac7, + 0x0721f500, +/* 0x0263: strand_ctx_init */ + 0xf100f802, + 0xb6083c87, + 0x94bd0684, + 0xd00399f0, + 0x21f50089, + 0xe7f00213, + 0x3921f503, + 0xfca7f102, + 0x02a3f046, + 0x0400aba0, + 0xf040a0d0, + 0xbcd001c7, + 0x0721f500, + 0x010c9202, + 0xf000acd0, + 0xbcd002c7, + 0x0721f500, + 0x2621f502, + 0x8087f102, + 0x0684b608, + 0xb70089cf, + 0x95220080, +/* 0x02ba: ctx_init_strand_loop */ + 0x8ed008fe, + 0x408ed000, + 0xb6808acf, + 0xa0b606a5, + 0x00eabb01, + 0xb60480b6, + 0x1bf40192, + 0x08e4b6e8, + 0xf1f2efbc, + 0xb6085c87, + 0x94bd0684, + 0xd00399f0, + 0x00f80089, +/* 0x02ec: error */ + 0xe7f1e0f9, + 0xe3f09814, + 0x8d21f440, + 0x041ce0b7, + 0xf401f7f0, + 0xe0fc8d21, +/* 0x0306: init */ + 0x04bd00f8, + 0xf10004fe, + 0xf0120017, + 0x12d00227, + 0x3e17f100, + 0x0010fe04, + 0x040017f1, + 0xf0c010d0, + 0x12d00427, + 0x1031f400, + 0x060817f1, + 0xcf0614b6, + 0x37f00012, + 0x1f24f001, + 0xb60432bb, + 0x02800132, + 0x04038003, + 0x040010b7, + 0x800012cf, + 0x27f10002, + 0x24b60800, + 0x0022cf06, +/* 0x035f: init_find_chipset */ + 0xb65817f0, + 0x13980c10, + 0x0432b800, + 0xb00b0bf4, + 0x1bf40034, +/* 0x0373: init_context */ + 0xf100f8f1, + 0xb6080027, + 0x22cf0624, + 0xf134bd40, + 0xb6070047, + 0x25950644, + 0x0045d008, + 0xbd4045d0, + 0x58f4bde4, + 0x1f58021e, + 0x020e4003, + 0xf5040f40, + 0xbb013d21, + 0x3fbb002f, + 0x041e5800, + 0x40051f58, + 0x0f400a0e, + 0x3d21f50c, + 0x030e9801, + 0xbb00effd, + 0x3ebb002e, + 0x0040b700, + 0x0235b613, + 0xb60043d0, + 0x35b60825, + 0x0120b606, + 0xb60130b6, + 0x34b60824, + 0x022fb908, + 0x026321f5, + 0xf1003fbb, + 0xb6080017, + 0x13d00614, + 0x0010b740, + 0xf024bd08, + 0x12d01f29, +/* 0x0401: main */ + 0x0031f400, + 0xf00028f4, + 0x21f41cd7, + 0xf401f439, + 0xf404e4b0, + 0x81fe1e18, + 0x0627f001, + 0x12fd20bd, + 0x01e4b604, + 0xfe051efd, + 0x21f50018, + 0x0ef404c3, +/* 0x0431: main_not_ctx_xfer */ + 0x10ef94d3, + 0xf501f5f0, + 0xf402ec21, +/* 0x043e: ih */ + 0x80f9c60e, + 0xf90188fe, + 0xf990f980, + 0xf9b0f9a0, + 0xf9e0f9d0, + 0x800acff0, + 0xf404abc4, + 0xb7f11d0b, + 0xd7f01900, + 0x40becf1c, + 0xf400bfcf, + 0xb0b70421, + 0xe7f00400, + 0x00bed001, +/* 0x0474: ih_no_fifo */ + 0xfc400ad0, + 0xfce0fcf0, + 0xfcb0fcd0, + 0xfc90fca0, + 0x0088fe80, + 0x32f480fc, +/* 0x048f: hub_barrier_done */ + 0xf001f800, + 0x0e9801f7, + 0x04febb00, + 0x9418e7f1, + 0xf440e3f0, + 0x00f88d21, +/* 0x04a4: ctx_redswitch */ + 0x0614e7f1, + 0xf006e4b6, + 0xefd020f7, + 0x08f7f000, +/* 0x04b4: ctx_redswitch_delay */ + 0xf401f2b6, + 0xf7f1fd1b, + 0xefd00a20, +/* 0x04c3: ctx_xfer */ + 0xf100f800, + 0xb60a0417, + 0x1fd00614, + 0x0711f400, + 0x04a421f5, +/* 0x04d4: ctx_xfer_not_load */ + 0x4afc17f1, + 0xf00213f0, + 0x12d00c27, + 0x0721f500, + 0xfc27f102, + 0x0223f047, + 0xf00020d0, + 0x20b6012c, + 0x0012d003, + 0xf001acf0, + 0xb7f002a5, + 0x50b3f000, + 0xb6000c98, + 0xbcbb0fc4, + 0x010c9800, + 0xf0020d98, + 0x21f500e7, + 0xacf0015c, + 0x04a5f001, + 0x4000b7f1, + 0x9850b3f0, + 0xc4b6000c, + 0x00bcbb0f, + 0x98050c98, + 0x0f98060d, + 0x00e7f104, + 0x5c21f508, + 0x0721f501, + 0x0601f402, +/* 0x054b: ctx_xfer_post */ + 0xf11412f4, + 0xf04afc17, + 0x27f00213, + 0x0012d00d, + 0x020721f5, +/* 0x055c: ctx_xfer_done */ + 0x048f21f5, + 0x000000f8, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc new file mode 100644 index 00000000000..7b715fda276 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc @@ -0,0 +1,451 @@ +/* fuc microcode for nve0 PGRAPH/GPC + * + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +/* To build: + * m4 nve0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grgpc.fuc.h + */ + +/* TODO + * - bracket certain functions with scratch writes, useful for debugging + * - watchdog timer around ctx operations + */ + +.section #nve0_grgpc_data +include(`nve0.fuc') +gpc_id: .b32 0 +gpc_mmio_list_head: .b32 0 +gpc_mmio_list_tail: .b32 0 + +tpc_count: .b32 0 +tpc_mask: .b32 0 +tpc_mmio_list_head: .b32 0 +tpc_mmio_list_tail: .b32 0 + +cmd_queue: queue_init + +// chipset descriptions +chipsets: +.b8 0xe4 0 0 0 +.b16 #nve4_gpc_mmio_head +.b16 #nve4_gpc_mmio_tail +.b16 #nve4_tpc_mmio_head +.b16 #nve4_tpc_mmio_tail +.b8 0xe7 0 0 0 +.b16 #nve4_gpc_mmio_head +.b16 #nve4_gpc_mmio_tail +.b16 #nve4_tpc_mmio_head +.b16 #nve4_tpc_mmio_tail +.b8 0 0 0 0 + +// GPC mmio lists +nve4_gpc_mmio_head: +mmctx_data(0x000380, 1) +mmctx_data(0x000400, 2) +mmctx_data(0x00040c, 3) +mmctx_data(0x000450, 9) +mmctx_data(0x000600, 1) +mmctx_data(0x000684, 1) +mmctx_data(0x000700, 5) +mmctx_data(0x000800, 1) +mmctx_data(0x000808, 3) +mmctx_data(0x000828, 1) +mmctx_data(0x000830, 1) +mmctx_data(0x0008d8, 1) +mmctx_data(0x0008e0, 1) +mmctx_data(0x0008e8, 6) +mmctx_data(0x00091c, 1) +mmctx_data(0x000924, 3) +mmctx_data(0x000b00, 1) +mmctx_data(0x000b08, 6) +mmctx_data(0x000bb8, 1) +mmctx_data(0x000c08, 1) +mmctx_data(0x000c10, 8) +mmctx_data(0x000c40, 1) +mmctx_data(0x000c6c, 1) +mmctx_data(0x000c80, 1) +mmctx_data(0x000c8c, 1) +mmctx_data(0x001000, 3) +mmctx_data(0x001014, 1) +mmctx_data(0x003024, 1) +mmctx_data(0x0030c0, 2) +mmctx_data(0x0030e4, 1) +mmctx_data(0x003100, 6) +mmctx_data(0x0031d0, 1) +mmctx_data(0x0031e0, 2) +nve4_gpc_mmio_tail: + +// TPC mmio lists +nve4_tpc_mmio_head: +mmctx_data(0x000048, 1) +mmctx_data(0x000064, 1) +mmctx_data(0x000088, 1) +mmctx_data(0x000200, 6) +mmctx_data(0x00021c, 2) +mmctx_data(0x000230, 1) +mmctx_data(0x0002c4, 1) +mmctx_data(0x000400, 3) +mmctx_data(0x000420, 3) +mmctx_data(0x0004e8, 1) +mmctx_data(0x0004f4, 1) +mmctx_data(0x000604, 4) +mmctx_data(0x000644, 22) +mmctx_data(0x0006ac, 2) +mmctx_data(0x0006c8, 1) +mmctx_data(0x000730, 8) +mmctx_data(0x000758, 1) +mmctx_data(0x000778, 1) +nve4_tpc_mmio_tail: + +.section #nve0_grgpc_code +bra #init +define(`include_code') +include(`nve0.fuc') + +// reports an exception to the host +// +// In: $r15 error code (see nve0.fuc) +// +error: + push $r14 + mov $r14 -0x67ec // 0x9814 + sethi $r14 0x400000 + call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code + add b32 $r14 0x41c + mov $r15 1 + call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET + pop $r14 + ret + +// GPC fuc initialisation, executed by triggering ucode start, will +// fall through to main loop after completion. +// +// Input: +// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh) +// CC_SCRATCH[1]: context base +// +// Output: +// CC_SCRATCH[0]: +// 31:31: set to signal completion +// CC_SCRATCH[1]: +// 31:0: GPC context size +// +init: + clear b32 $r0 + mov $sp $r0 + + // enable fifo access + mov $r1 0x1200 + mov $r2 2 + iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE + + // setup i0 handler, and route all interrupts to it + mov $r1 #ih + mov $iv0 $r1 + mov $r1 0x400 + iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH + + // enable fifo interrupt + mov $r2 4 + iowr I[$r1 + 0x000] $r2 // INTR_EN_SET + + // enable interrupts + bset $flags ie0 + + // figure out which GPC we are, and how many TPCs we have + mov $r1 0x608 + shl b32 $r1 6 + iord $r2 I[$r1 + 0x000] // UNITS + mov $r3 1 + and $r2 0x1f + shl b32 $r3 $r2 + sub b32 $r3 1 + st b32 D[$r0 + #tpc_count] $r2 + st b32 D[$r0 + #tpc_mask] $r3 + add b32 $r1 0x400 + iord $r2 I[$r1 + 0x000] // MYINDEX + st b32 D[$r0 + #gpc_id] $r2 + + // find context data for this chipset + mov $r2 0x800 + shl b32 $r2 6 + iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0] + mov $r1 #chipsets - 12 + init_find_chipset: + add b32 $r1 12 + ld b32 $r3 D[$r1 + 0x00] + cmpu b32 $r3 $r2 + bra e #init_context + cmpu b32 $r3 0 + bra ne #init_find_chipset + // unknown chipset + ret + + // initialise context base, and size tracking + init_context: + mov $r2 0x800 + shl b32 $r2 6 + iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base + clear b32 $r3 // track GPC context size here + + // set mmctx base addresses now so we don't have to do it later, + // they don't currently ever change + mov $r4 0x700 + shl b32 $r4 6 + shr b32 $r5 $r2 8 + iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE + iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE + + // calculate GPC mmio context size, store the chipset-specific + // mmio list pointers somewhere we can get at them later without + // re-parsing the chipset list + clear b32 $r14 + clear b32 $r15 + ld b16 $r14 D[$r1 + 4] + ld b16 $r15 D[$r1 + 6] + st b16 D[$r0 + #gpc_mmio_list_head] $r14 + st b16 D[$r0 + #gpc_mmio_list_tail] $r15 + call #mmctx_size + add b32 $r2 $r15 + add b32 $r3 $r15 + + // calculate per-TPC mmio context size, store the list pointers + ld b16 $r14 D[$r1 + 8] + ld b16 $r15 D[$r1 + 10] + st b16 D[$r0 + #tpc_mmio_list_head] $r14 + st b16 D[$r0 + #tpc_mmio_list_tail] $r15 + call #mmctx_size + ld b32 $r14 D[$r0 + #tpc_count] + mulu $r14 $r15 + add b32 $r2 $r14 + add b32 $r3 $r14 + + // round up base/size to 256 byte boundary (for strand SWBASE) + add b32 $r4 0x1300 + shr b32 $r3 2 + iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!? + shr b32 $r2 8 + shr b32 $r3 6 + add b32 $r2 1 + add b32 $r3 1 + shl b32 $r2 8 + shl b32 $r3 8 + + // calculate size of strand context data + mov b32 $r15 $r2 + call #strand_ctx_init + add b32 $r3 $r15 + + // save context size, and tell HUB we're done + mov $r1 0x800 + shl b32 $r1 6 + iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size + add b32 $r1 0x800 + clear b32 $r2 + bset $r2 31 + iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000 + +// Main program loop, very simple, sleeps until woken up by the interrupt +// handler, pulls a command from the queue and executes its handler +// +main: + bset $flags $p0 + sleep $p0 + mov $r13 #cmd_queue + call #queue_get + bra $p1 #main + + // 0x0000-0x0003 are all context transfers + cmpu b32 $r14 0x04 + bra nc #main_not_ctx_xfer + // fetch $flags and mask off $p1/$p2 + mov $r1 $flags + mov $r2 0x0006 + not b32 $r2 + and $r1 $r2 + // set $p1/$p2 according to transfer type + shl b32 $r14 1 + or $r1 $r14 + mov $flags $r1 + // transfer context data + call #ctx_xfer + bra #main + + main_not_ctx_xfer: + shl b32 $r15 $r14 16 + or $r15 E_BAD_COMMAND + call #error + bra #main + +// interrupt handler +ih: + push $r8 + mov $r8 $flags + push $r8 + push $r9 + push $r10 + push $r11 + push $r13 + push $r14 + push $r15 + + // incoming fifo command? + iord $r10 I[$r0 + 0x200] // INTR + and $r11 $r10 0x00000004 + bra e #ih_no_fifo + // queue incoming fifo command for later processing + mov $r11 0x1900 + mov $r13 #cmd_queue + iord $r14 I[$r11 + 0x100] // FIFO_CMD + iord $r15 I[$r11 + 0x000] // FIFO_DATA + call #queue_put + add b32 $r11 0x400 + mov $r14 1 + iowr I[$r11 + 0x000] $r14 // FIFO_ACK + + // ack, and wake up main() + ih_no_fifo: + iowr I[$r0 + 0x100] $r10 // INTR_ACK + + pop $r15 + pop $r14 + pop $r13 + pop $r11 + pop $r10 + pop $r9 + pop $r8 + mov $flags $r8 + pop $r8 + bclr $flags $p0 + iret + +// Set this GPC's bit in HUB_BAR, used to signal completion of various +// activities to the HUB fuc +// +hub_barrier_done: + mov $r15 1 + ld b32 $r14 D[$r0 + #gpc_id] + shl b32 $r15 $r14 + mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET + sethi $r14 0x400000 + call #nv_wr32 + ret + +// Disables various things, waits a bit, and re-enables them.. +// +// Not sure how exactly this helps, perhaps "ENABLE" is not such a +// good description for the bits we turn off? Anyways, without this, +// funny things happen. +// +ctx_redswitch: + mov $r14 0x614 + shl b32 $r14 6 + mov $r15 0x020 + iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER + mov $r15 8 + ctx_redswitch_delay: + sub b32 $r15 1 + bra ne #ctx_redswitch_delay + mov $r15 0xa20 + iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER + ret + +// Transfer GPC context data between GPU and storage area +// +// In: $r15 context base address +// $p1 clear on save, set on load +// $p2 set if opposite direction done/will be done, so: +// on save it means: "a load will follow this save" +// on load it means: "a save preceeded this load" +// +ctx_xfer: + // set context base address + mov $r1 0xa04 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r15// MEM_BASE + bra not $p1 #ctx_xfer_not_load + call #ctx_redswitch + ctx_xfer_not_load: + + // strands + mov $r1 0x4afc + sethi $r1 0x20000 + mov $r2 0xc + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c + call #strand_wait + mov $r2 0x47fc + sethi $r2 0x20000 + iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00 + xbit $r2 $flags $p1 + add b32 $r2 3 + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD) + + // mmio context + xbit $r10 $flags $p1 // direction + or $r10 2 // first + mov $r11 0x0000 + sethi $r11 0x500000 + ld b32 $r12 D[$r0 + #gpc_id] + shl b32 $r12 15 + add b32 $r11 $r12 // base = NV_PGRAPH_GPCn + ld b32 $r12 D[$r0 + #gpc_mmio_list_head] + ld b32 $r13 D[$r0 + #gpc_mmio_list_tail] + mov $r14 0 // not multi + call #mmctx_xfer + + // per-TPC mmio context + xbit $r10 $flags $p1 // direction + or $r10 4 // last + mov $r11 0x4000 + sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0 + ld b32 $r12 D[$r0 + #gpc_id] + shl b32 $r12 15 + add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0 + ld b32 $r12 D[$r0 + #tpc_mmio_list_head] + ld b32 $r13 D[$r0 + #tpc_mmio_list_tail] + ld b32 $r15 D[$r0 + #tpc_mask] + mov $r14 0x800 // stride = 0x800 + call #mmctx_xfer + + // wait for strands to finish + call #strand_wait + + // if load, or a save without a load following, do some + // unknown stuff that's done after finishing a block of + // strand commands + bra $p1 #ctx_xfer_post + bra not $p2 #ctx_xfer_done + ctx_xfer_post: + mov $r1 0x4afc + sethi $r1 0x20000 + mov $r2 0xd + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d + call #strand_wait + + // mark completion in HUB's barrier + ctx_xfer_done: + call #hub_barrier_done + ret + +.align 256 diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h new file mode 100644 index 00000000000..26c2165bad0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h @@ -0,0 +1,530 @@ +uint32_t nve0_grgpc_data[] = { +/* 0x0000: gpc_id */ + 0x00000000, +/* 0x0004: gpc_mmio_list_head */ + 0x00000000, +/* 0x0008: gpc_mmio_list_tail */ + 0x00000000, +/* 0x000c: tpc_count */ + 0x00000000, +/* 0x0010: tpc_mask */ + 0x00000000, +/* 0x0014: tpc_mmio_list_head */ + 0x00000000, +/* 0x0018: tpc_mmio_list_tail */ + 0x00000000, +/* 0x001c: cmd_queue */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0064: chipsets */ + 0x000000e4, + 0x01040080, + 0x014c0104, + 0x000000e7, + 0x01040080, + 0x014c0104, + 0x00000000, +/* 0x0080: nve4_gpc_mmio_head */ + 0x00000380, + 0x04000400, + 0x0800040c, + 0x20000450, + 0x00000600, + 0x00000684, + 0x10000700, + 0x00000800, + 0x08000808, + 0x00000828, + 0x00000830, + 0x000008d8, + 0x000008e0, + 0x140008e8, + 0x0000091c, + 0x08000924, + 0x00000b00, + 0x14000b08, + 0x00000bb8, + 0x00000c08, + 0x1c000c10, + 0x00000c40, + 0x00000c6c, + 0x00000c80, + 0x00000c8c, + 0x08001000, + 0x00001014, + 0x00003024, + 0x040030c0, + 0x000030e4, + 0x14003100, + 0x000031d0, + 0x040031e0, +/* 0x0104: nve4_gpc_mmio_tail */ +/* 0x0104: nve4_tpc_mmio_head */ + 0x00000048, + 0x00000064, + 0x00000088, + 0x14000200, + 0x0400021c, + 0x00000230, + 0x000002c4, + 0x08000400, + 0x08000420, + 0x000004e8, + 0x000004f4, + 0x0c000604, + 0x54000644, + 0x040006ac, + 0x000006c8, + 0x1c000730, + 0x00000758, + 0x00000778, +}; + +uint32_t nve0_grgpc_code[] = { + 0x03060ef5, +/* 0x0004: queue_put */ + 0x9800d898, + 0x86f001d9, + 0x0489b808, + 0xf00c1bf4, + 0x21f502f7, + 0x00f802ec, +/* 0x001c: queue_put_next */ + 0xb60798c4, + 0x8dbb0384, + 0x0880b600, + 0x80008e80, + 0x90b6018f, + 0x0f94f001, + 0xf801d980, +/* 0x0039: queue_get */ + 0x0131f400, + 0x9800d898, + 0x89b801d9, + 0x210bf404, + 0xb60789c4, + 0x9dbb0394, + 0x0890b600, + 0x98009e98, + 0x80b6019f, + 0x0f84f001, + 0xf400d880, +/* 0x0066: queue_get_done */ + 0x00f80132, +/* 0x0068: nv_rd32 */ + 0x0728b7f1, + 0xb906b4b6, + 0xc9f002ec, + 0x00bcd01f, +/* 0x0078: nv_rd32_wait */ + 0xc800bccf, + 0x1bf41fcc, + 0x06a7f0fa, + 0x010321f5, + 0xf840bfcf, +/* 0x008d: nv_wr32 */ + 0x28b7f100, + 0x06b4b607, + 0xb980bfd0, + 0xc9f002ec, + 0x1ec9f01f, +/* 0x00a3: nv_wr32_wait */ + 0xcf00bcd0, + 0xccc800bc, + 0xfa1bf41f, +/* 0x00ae: watchdog_reset */ + 0x87f100f8, + 0x84b60430, + 0x1ff9f006, + 0xf8008fd0, +/* 0x00bd: watchdog_clear */ + 0x3087f100, + 0x0684b604, + 0xf80080d0, +/* 0x00c9: wait_donez */ + 0x3c87f100, + 0x0684b608, + 0x99f094bd, + 0x0089d000, + 0x081887f1, + 0xd00684b6, +/* 0x00e2: wait_done_wait_donez */ + 0x87f1008a, + 0x84b60400, + 0x0088cf06, + 0xf4888aff, + 0x87f1f31b, + 0x84b6085c, + 0xf094bd06, + 0x89d00099, +/* 0x0103: wait_doneo */ + 0xf100f800, + 0xb6083c87, + 0x94bd0684, + 0xd00099f0, + 0x87f10089, + 0x84b60818, + 0x008ad006, +/* 0x011c: wait_done_wait_doneo */ + 0x040087f1, + 0xcf0684b6, + 0x8aff0088, + 0xf30bf488, + 0x085c87f1, + 0xbd0684b6, + 0x0099f094, + 0xf80089d0, +/* 0x013d: mmctx_size */ +/* 0x013f: nv_mmctx_size_loop */ + 0x9894bd00, + 0x85b600e8, + 0x0180b61a, + 0xbb0284b6, + 0xe0b60098, + 0x04efb804, + 0xb9eb1bf4, + 0x00f8029f, +/* 0x015c: mmctx_xfer */ + 0x083c87f1, + 0xbd0684b6, + 0x0199f094, + 0xf10089d0, + 0xb6071087, + 0x94bd0684, + 0xf405bbfd, + 0x8bd0090b, + 0x0099f000, +/* 0x0180: mmctx_base_disabled */ + 0xf405eefd, + 0x8ed00c0b, + 0xc08fd080, +/* 0x018f: mmctx_multi_disabled */ + 0xb70199f0, + 0xc8010080, + 0xb4b600ab, + 0x0cb9f010, + 0xb601aec8, + 0xbefd11e4, + 0x008bd005, +/* 0x01a8: mmctx_exec_loop */ +/* 0x01a8: mmctx_wait_free */ + 0xf0008ecf, + 0x0bf41fe4, + 0x00ce98fa, + 0xd005e9fd, + 0xc0b6c08e, + 0x04cdb804, + 0xc8e81bf4, + 0x1bf402ab, +/* 0x01c9: mmctx_fini_wait */ + 0x008bcf18, + 0xb01fb4f0, + 0x1bf410b4, + 0x02a7f0f7, + 0xf4c921f4, +/* 0x01de: mmctx_stop */ + 0xabc81b0e, + 0x10b4b600, + 0xf00cb9f0, + 0x8bd012b9, +/* 0x01ed: mmctx_stop_wait */ + 0x008bcf00, + 0xf412bbc8, +/* 0x01f6: mmctx_done */ + 0x87f1fa1b, + 0x84b6085c, + 0xf094bd06, + 0x89d00199, +/* 0x0207: strand_wait */ + 0xf900f800, + 0x02a7f0a0, + 0xfcc921f4, +/* 0x0213: strand_pre */ + 0xf100f8a0, + 0xf04afc87, + 0x97f00283, + 0x0089d00c, + 0x020721f5, +/* 0x0226: strand_post */ + 0x87f100f8, + 0x83f04afc, + 0x0d97f002, + 0xf50089d0, + 0xf8020721, +/* 0x0239: strand_set */ + 0xfca7f100, + 0x02a3f04f, + 0x0500aba2, + 0xd00fc7f0, + 0xc7f000ac, + 0x00bcd00b, + 0x020721f5, + 0xf000aed0, + 0xbcd00ac7, + 0x0721f500, +/* 0x0263: strand_ctx_init */ + 0xf100f802, + 0xb6083c87, + 0x94bd0684, + 0xd00399f0, + 0x21f50089, + 0xe7f00213, + 0x3921f503, + 0xfca7f102, + 0x02a3f046, + 0x0400aba0, + 0xf040a0d0, + 0xbcd001c7, + 0x0721f500, + 0x010c9202, + 0xf000acd0, + 0xbcd002c7, + 0x0721f500, + 0x2621f502, + 0x8087f102, + 0x0684b608, + 0xb70089cf, + 0x95220080, +/* 0x02ba: ctx_init_strand_loop */ + 0x8ed008fe, + 0x408ed000, + 0xb6808acf, + 0xa0b606a5, + 0x00eabb01, + 0xb60480b6, + 0x1bf40192, + 0x08e4b6e8, + 0xf1f2efbc, + 0xb6085c87, + 0x94bd0684, + 0xd00399f0, + 0x00f80089, +/* 0x02ec: error */ + 0xe7f1e0f9, + 0xe3f09814, + 0x8d21f440, + 0x041ce0b7, + 0xf401f7f0, + 0xe0fc8d21, +/* 0x0306: init */ + 0x04bd00f8, + 0xf10004fe, + 0xf0120017, + 0x12d00227, + 0x3e17f100, + 0x0010fe04, + 0x040017f1, + 0xf0c010d0, + 0x12d00427, + 0x1031f400, + 0x060817f1, + 0xcf0614b6, + 0x37f00012, + 0x1f24f001, + 0xb60432bb, + 0x02800132, + 0x04038003, + 0x040010b7, + 0x800012cf, + 0x27f10002, + 0x24b60800, + 0x0022cf06, +/* 0x035f: init_find_chipset */ + 0xb65817f0, + 0x13980c10, + 0x0432b800, + 0xb00b0bf4, + 0x1bf40034, +/* 0x0373: init_context */ + 0xf100f8f1, + 0xb6080027, + 0x22cf0624, + 0xf134bd40, + 0xb6070047, + 0x25950644, + 0x0045d008, + 0xbd4045d0, + 0x58f4bde4, + 0x1f58021e, + 0x020e4003, + 0xf5040f40, + 0xbb013d21, + 0x3fbb002f, + 0x041e5800, + 0x40051f58, + 0x0f400a0e, + 0x3d21f50c, + 0x030e9801, + 0xbb00effd, + 0x3ebb002e, + 0x0040b700, + 0x0235b613, + 0xb60043d0, + 0x35b60825, + 0x0120b606, + 0xb60130b6, + 0x34b60824, + 0x022fb908, + 0x026321f5, + 0xf1003fbb, + 0xb6080017, + 0x13d00614, + 0x0010b740, + 0xf024bd08, + 0x12d01f29, +/* 0x0401: main */ + 0x0031f400, + 0xf00028f4, + 0x21f41cd7, + 0xf401f439, + 0xf404e4b0, + 0x81fe1e18, + 0x0627f001, + 0x12fd20bd, + 0x01e4b604, + 0xfe051efd, + 0x21f50018, + 0x0ef404c3, +/* 0x0431: main_not_ctx_xfer */ + 0x10ef94d3, + 0xf501f5f0, + 0xf402ec21, +/* 0x043e: ih */ + 0x80f9c60e, + 0xf90188fe, + 0xf990f980, + 0xf9b0f9a0, + 0xf9e0f9d0, + 0x800acff0, + 0xf404abc4, + 0xb7f11d0b, + 0xd7f01900, + 0x40becf1c, + 0xf400bfcf, + 0xb0b70421, + 0xe7f00400, + 0x00bed001, +/* 0x0474: ih_no_fifo */ + 0xfc400ad0, + 0xfce0fcf0, + 0xfcb0fcd0, + 0xfc90fca0, + 0x0088fe80, + 0x32f480fc, +/* 0x048f: hub_barrier_done */ + 0xf001f800, + 0x0e9801f7, + 0x04febb00, + 0x9418e7f1, + 0xf440e3f0, + 0x00f88d21, +/* 0x04a4: ctx_redswitch */ + 0x0614e7f1, + 0xf006e4b6, + 0xefd020f7, + 0x08f7f000, +/* 0x04b4: ctx_redswitch_delay */ + 0xf401f2b6, + 0xf7f1fd1b, + 0xefd00a20, +/* 0x04c3: ctx_xfer */ + 0xf100f800, + 0xb60a0417, + 0x1fd00614, + 0x0711f400, + 0x04a421f5, +/* 0x04d4: ctx_xfer_not_load */ + 0x4afc17f1, + 0xf00213f0, + 0x12d00c27, + 0x0721f500, + 0xfc27f102, + 0x0223f047, + 0xf00020d0, + 0x20b6012c, + 0x0012d003, + 0xf001acf0, + 0xb7f002a5, + 0x50b3f000, + 0xb6000c98, + 0xbcbb0fc4, + 0x010c9800, + 0xf0020d98, + 0x21f500e7, + 0xacf0015c, + 0x04a5f001, + 0x4000b7f1, + 0x9850b3f0, + 0xc4b6000c, + 0x00bcbb0f, + 0x98050c98, + 0x0f98060d, + 0x00e7f104, + 0x5c21f508, + 0x0721f501, + 0x0601f402, +/* 0x054b: ctx_xfer_post */ + 0xf11412f4, + 0xf04afc17, + 0x27f00213, + 0x0012d00d, + 0x020721f5, +/* 0x055c: ctx_xfer_done */ + 0x048f21f5, + 0x000000f8, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc new file mode 100644 index 00000000000..acfc457654b --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc @@ -0,0 +1,856 @@ +/* fuc microcode for nvc0 PGRAPH/HUB + * + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +/* To build: + * m4 hubnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o hubnvc0.fuc.h + */ + +.section #nvc0_grhub_data +include(`nvc0.fuc') +gpc_count: .b32 0 +rop_count: .b32 0 +cmd_queue: queue_init +hub_mmio_list_head: .b32 0 +hub_mmio_list_tail: .b32 0 + +ctx_current: .b32 0 + +chipsets: +.b8 0xc0 0 0 0 +.b16 #nvc0_hub_mmio_head +.b16 #nvc0_hub_mmio_tail +.b8 0xc1 0 0 0 +.b16 #nvc0_hub_mmio_head +.b16 #nvc1_hub_mmio_tail +.b8 0xc3 0 0 0 +.b16 #nvc0_hub_mmio_head +.b16 #nvc0_hub_mmio_tail +.b8 0xc4 0 0 0 +.b16 #nvc0_hub_mmio_head +.b16 #nvc0_hub_mmio_tail +.b8 0xc8 0 0 0 +.b16 #nvc0_hub_mmio_head +.b16 #nvc0_hub_mmio_tail +.b8 0xce 0 0 0 +.b16 #nvc0_hub_mmio_head +.b16 #nvc0_hub_mmio_tail +.b8 0xcf 0 0 0 +.b16 #nvc0_hub_mmio_head +.b16 #nvc0_hub_mmio_tail +.b8 0xd9 0 0 0 +.b16 #nvd9_hub_mmio_head +.b16 #nvd9_hub_mmio_tail +.b8 0 0 0 0 + +nvc0_hub_mmio_head: +mmctx_data(0x17e91c, 2) +mmctx_data(0x400204, 2) +mmctx_data(0x404004, 11) +mmctx_data(0x404044, 1) +mmctx_data(0x404094, 14) +mmctx_data(0x4040d0, 7) +mmctx_data(0x4040f8, 1) +mmctx_data(0x404130, 3) +mmctx_data(0x404150, 3) +mmctx_data(0x404164, 2) +mmctx_data(0x404174, 3) +mmctx_data(0x404200, 8) +mmctx_data(0x404404, 14) +mmctx_data(0x404460, 4) +mmctx_data(0x404480, 1) +mmctx_data(0x404498, 1) +mmctx_data(0x404604, 4) +mmctx_data(0x404618, 32) +mmctx_data(0x404698, 21) +mmctx_data(0x4046f0, 2) +mmctx_data(0x404700, 22) +mmctx_data(0x405800, 1) +mmctx_data(0x405830, 3) +mmctx_data(0x405854, 1) +mmctx_data(0x405870, 4) +mmctx_data(0x405a00, 2) +mmctx_data(0x405a18, 1) +mmctx_data(0x406020, 1) +mmctx_data(0x406028, 4) +mmctx_data(0x4064a8, 2) +mmctx_data(0x4064b4, 2) +mmctx_data(0x407804, 1) +mmctx_data(0x40780c, 6) +mmctx_data(0x4078bc, 1) +mmctx_data(0x408000, 7) +mmctx_data(0x408064, 1) +mmctx_data(0x408800, 3) +mmctx_data(0x408900, 4) +mmctx_data(0x408980, 1) +nvc0_hub_mmio_tail: +mmctx_data(0x4064c0, 2) +nvc1_hub_mmio_tail: + +nvd9_hub_mmio_head: +mmctx_data(0x17e91c, 2) +mmctx_data(0x400204, 2) +mmctx_data(0x404004, 10) +mmctx_data(0x404044, 1) +mmctx_data(0x404094, 14) +mmctx_data(0x4040d0, 7) +mmctx_data(0x4040f8, 1) +mmctx_data(0x404130, 3) +mmctx_data(0x404150, 3) +mmctx_data(0x404164, 2) +mmctx_data(0x404178, 2) +mmctx_data(0x404200, 8) +mmctx_data(0x404404, 14) +mmctx_data(0x404460, 4) +mmctx_data(0x404480, 1) +mmctx_data(0x404498, 1) +mmctx_data(0x404604, 4) +mmctx_data(0x404618, 32) +mmctx_data(0x404698, 21) +mmctx_data(0x4046f0, 2) +mmctx_data(0x404700, 22) +mmctx_data(0x405800, 1) +mmctx_data(0x405830, 3) +mmctx_data(0x405854, 1) +mmctx_data(0x405870, 4) +mmctx_data(0x405a00, 2) +mmctx_data(0x405a18, 1) +mmctx_data(0x406020, 1) +mmctx_data(0x406028, 4) +mmctx_data(0x4064a8, 2) +mmctx_data(0x4064b4, 5) +mmctx_data(0x407804, 1) +mmctx_data(0x40780c, 6) +mmctx_data(0x4078bc, 1) +mmctx_data(0x408000, 7) +mmctx_data(0x408064, 1) +mmctx_data(0x408800, 3) +mmctx_data(0x408900, 4) +mmctx_data(0x408980, 1) +nvd9_hub_mmio_tail: + +.align 256 +chan_data: +chan_mmio_count: .b32 0 +chan_mmio_address: .b32 0 + +.align 256 +xfer_data: .b32 0 + +.section #nvc0_grhub_code +bra #init +define(`include_code') +include(`nvc0.fuc') + +// reports an exception to the host +// +// In: $r15 error code (see nvc0.fuc) +// +error: + push $r14 + mov $r14 0x814 + shl b32 $r14 6 + iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code + mov $r14 0xc1c + shl b32 $r14 6 + mov $r15 1 + iowr I[$r14 + 0x000] $r15 // INTR_UP_SET + pop $r14 + ret + +// HUB fuc initialisation, executed by triggering ucode start, will +// fall through to main loop after completion. +// +// Input: +// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh) +// +// Output: +// CC_SCRATCH[0]: +// 31:31: set to signal completion +// CC_SCRATCH[1]: +// 31:0: total PGRAPH context size +// +init: + clear b32 $r0 + mov $sp $r0 + mov $xdbase $r0 + + // enable fifo access + mov $r1 0x1200 + mov $r2 2 + iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE + + // setup i0 handler, and route all interrupts to it + mov $r1 #ih + mov $iv0 $r1 + mov $r1 0x400 + iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH + + // route HUB_CHANNEL_SWITCH to fuc interrupt 8 + mov $r3 0x404 + shl b32 $r3 6 + mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8 + iowr I[$r3 + 0x000] $r2 + + // not sure what these are, route them because NVIDIA does, and + // the IRQ handler will signal the host if we ever get one.. we + // may find out if/why we need to handle these if so.. + // + mov $r2 0x2004 + iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9 + mov $r2 0x200b + iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10 + mov $r2 0x200c + iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15 + + // enable all INTR_UP interrupts + mov $r2 0xc24 + shl b32 $r2 6 + not b32 $r3 $r0 + iowr I[$r2] $r3 + + // enable fifo, ctxsw, 9, 10, 15 interrupts + mov $r2 -0x78fc // 0x8704 + sethi $r2 0 + iowr I[$r1 + 0x000] $r2 // INTR_EN_SET + + // fifo level triggered, rest edge + sub b32 $r1 0x100 + mov $r2 4 + iowr I[$r1] $r2 + + // enable interrupts + bset $flags ie0 + + // fetch enabled GPC/ROP counts + mov $r14 -0x69fc // 0x409604 + sethi $r14 0x400000 + call #nv_rd32 + extr $r1 $r15 16:20 + st b32 D[$r0 + #rop_count] $r1 + and $r15 0x1f + st b32 D[$r0 + #gpc_count] $r15 + + // set BAR_REQMASK to GPC mask + mov $r1 1 + shl b32 $r1 $r15 + sub b32 $r1 1 + mov $r2 0x40c + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r1 + iowr I[$r2 + 0x100] $r1 + + // find context data for this chipset + mov $r2 0x800 + shl b32 $r2 6 + iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0] + mov $r15 #chipsets - 8 + init_find_chipset: + add b32 $r15 8 + ld b32 $r3 D[$r15 + 0x00] + cmpu b32 $r3 $r2 + bra e #init_context + cmpu b32 $r3 0 + bra ne #init_find_chipset + // unknown chipset + ret + + // context size calculation, reserve first 256 bytes for use by fuc + init_context: + mov $r1 256 + + // calculate size of mmio context data + ld b16 $r14 D[$r15 + 4] + ld b16 $r15 D[$r15 + 6] + sethi $r14 0 + st b32 D[$r0 + #hub_mmio_list_head] $r14 + st b32 D[$r0 + #hub_mmio_list_tail] $r15 + call #mmctx_size + + // set mmctx base addresses now so we don't have to do it later, + // they don't (currently) ever change + mov $r3 0x700 + shl b32 $r3 6 + shr b32 $r4 $r1 8 + iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE + iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE + add b32 $r3 0x1300 + add b32 $r1 $r15 + shr b32 $r15 2 + iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!? + + // strands, base offset needs to be aligned to 256 bytes + shr b32 $r1 8 + add b32 $r1 1 + shl b32 $r1 8 + mov b32 $r15 $r1 + call #strand_ctx_init + add b32 $r1 $r15 + + // initialise each GPC in sequence by passing in the offset of its + // context data in GPCn_CC_SCRATCH[1], and starting its FUC (which + // has previously been uploaded by the host) running. + // + // the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31 + // when it has completed, and return the size of its context data + // in GPCn_CC_SCRATCH[1] + // + ld b32 $r3 D[$r0 + #gpc_count] + mov $r4 0x2000 + sethi $r4 0x500000 + init_gpc: + // setup, and start GPC ucode running + add b32 $r14 $r4 0x804 + mov b32 $r15 $r1 + call #nv_wr32 // CC_SCRATCH[1] = ctx offset + add b32 $r14 $r4 0x800 + mov b32 $r15 $r2 + call #nv_wr32 // CC_SCRATCH[0] = chipset + add b32 $r14 $r4 0x10c + clear b32 $r15 + call #nv_wr32 + add b32 $r14 $r4 0x104 + call #nv_wr32 // ENTRY + add b32 $r14 $r4 0x100 + mov $r15 2 // CTRL_START_TRIGGER + call #nv_wr32 // CTRL + + // wait for it to complete, and adjust context size + add b32 $r14 $r4 0x800 + init_gpc_wait: + call #nv_rd32 + xbit $r15 $r15 31 + bra e #init_gpc_wait + add b32 $r14 $r4 0x804 + call #nv_rd32 + add b32 $r1 $r15 + + // next! + add b32 $r4 0x8000 + sub b32 $r3 1 + bra ne #init_gpc + + // save context size, and tell host we're ready + mov $r2 0x800 + shl b32 $r2 6 + iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size + add b32 $r2 0x800 + clear b32 $r1 + bset $r1 31 + iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000 + +// Main program loop, very simple, sleeps until woken up by the interrupt +// handler, pulls a command from the queue and executes its handler +// +main: + // sleep until we have something to do + bset $flags $p0 + sleep $p0 + mov $r13 #cmd_queue + call #queue_get + bra $p1 #main + + // context switch, requested by GPU? + cmpu b32 $r14 0x4001 + bra ne #main_not_ctx_switch + trace_set(T_AUTO) + mov $r1 0xb00 + shl b32 $r1 6 + iord $r2 I[$r1 + 0x100] // CHAN_NEXT + iord $r1 I[$r1 + 0x000] // CHAN_CUR + + xbit $r3 $r1 31 + bra e #chsw_no_prev + xbit $r3 $r2 31 + bra e #chsw_prev_no_next + push $r2 + mov b32 $r2 $r1 + trace_set(T_SAVE) + bclr $flags $p1 + bset $flags $p2 + call #ctx_xfer + trace_clr(T_SAVE); + pop $r2 + trace_set(T_LOAD); + bset $flags $p1 + call #ctx_xfer + trace_clr(T_LOAD); + bra #chsw_done + chsw_prev_no_next: + push $r2 + mov b32 $r2 $r1 + bclr $flags $p1 + bclr $flags $p2 + call #ctx_xfer + pop $r2 + mov $r1 0xb00 + shl b32 $r1 6 + iowr I[$r1] $r2 + bra #chsw_done + chsw_no_prev: + xbit $r3 $r2 31 + bra e #chsw_done + bset $flags $p1 + bclr $flags $p2 + call #ctx_xfer + + // ack the context switch request + chsw_done: + mov $r1 0xb0c + shl b32 $r1 6 + mov $r2 1 + iowr I[$r1 + 0x000] $r2 // 0x409b0c + trace_clr(T_AUTO) + bra #main + + // request to set current channel? (*not* a context switch) + main_not_ctx_switch: + cmpu b32 $r14 0x0001 + bra ne #main_not_ctx_chan + mov b32 $r2 $r15 + call #ctx_chan + bra #main_done + + // request to store current channel context? + main_not_ctx_chan: + cmpu b32 $r14 0x0002 + bra ne #main_not_ctx_save + trace_set(T_SAVE) + bclr $flags $p1 + bclr $flags $p2 + call #ctx_xfer + trace_clr(T_SAVE) + bra #main_done + + main_not_ctx_save: + shl b32 $r15 $r14 16 + or $r15 E_BAD_COMMAND + call #error + bra #main + + main_done: + mov $r1 0x820 + shl b32 $r1 6 + clear b32 $r2 + bset $r2 31 + iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000 + bra #main + +// interrupt handler +ih: + push $r8 + mov $r8 $flags + push $r8 + push $r9 + push $r10 + push $r11 + push $r13 + push $r14 + push $r15 + + // incoming fifo command? + iord $r10 I[$r0 + 0x200] // INTR + and $r11 $r10 0x00000004 + bra e #ih_no_fifo + // queue incoming fifo command for later processing + mov $r11 0x1900 + mov $r13 #cmd_queue + iord $r14 I[$r11 + 0x100] // FIFO_CMD + iord $r15 I[$r11 + 0x000] // FIFO_DATA + call #queue_put + add b32 $r11 0x400 + mov $r14 1 + iowr I[$r11 + 0x000] $r14 // FIFO_ACK + + // context switch request? + ih_no_fifo: + and $r11 $r10 0x00000100 + bra e #ih_no_ctxsw + // enqueue a context switch for later processing + mov $r13 #cmd_queue + mov $r14 0x4001 + call #queue_put + + // anything we didn't handle, bring it to the host's attention + ih_no_ctxsw: + mov $r11 0x104 + not b32 $r11 + and $r11 $r10 $r11 + bra e #ih_no_other + mov $r10 0xc1c + shl b32 $r10 6 + iowr I[$r10] $r11 // INTR_UP_SET + + // ack, and wake up main() + ih_no_other: + iowr I[$r0 + 0x100] $r10 // INTR_ACK + + pop $r15 + pop $r14 + pop $r13 + pop $r11 + pop $r10 + pop $r9 + pop $r8 + mov $flags $r8 + pop $r8 + bclr $flags $p0 + iret + +// Not real sure, but, MEM_CMD 7 will hang forever if this isn't done +ctx_4160s: + mov $r14 0x4160 + sethi $r14 0x400000 + mov $r15 1 + call #nv_wr32 + ctx_4160s_wait: + call #nv_rd32 + xbit $r15 $r15 4 + bra e #ctx_4160s_wait + ret + +// Without clearing again at end of xfer, some things cause PGRAPH +// to hang with STATUS=0x00000007 until it's cleared.. fbcon can +// still function with it set however... +ctx_4160c: + mov $r14 0x4160 + sethi $r14 0x400000 + clear b32 $r15 + call #nv_wr32 + ret + +// Again, not real sure +// +// In: $r15 value to set 0x404170 to +// +ctx_4170s: + mov $r14 0x4170 + sethi $r14 0x400000 + or $r15 0x10 + call #nv_wr32 + ret + +// Waits for a ctx_4170s() call to complete +// +ctx_4170w: + mov $r14 0x4170 + sethi $r14 0x400000 + call #nv_rd32 + and $r15 0x10 + bra ne #ctx_4170w + ret + +// Disables various things, waits a bit, and re-enables them.. +// +// Not sure how exactly this helps, perhaps "ENABLE" is not such a +// good description for the bits we turn off? Anyways, without this, +// funny things happen. +// +ctx_redswitch: + mov $r14 0x614 + shl b32 $r14 6 + mov $r15 0x270 + iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL + mov $r15 8 + ctx_redswitch_delay: + sub b32 $r15 1 + bra ne #ctx_redswitch_delay + mov $r15 0x770 + iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL + ret + +// Not a clue what this is for, except that unless the value is 0x10, the +// strand context is saved (and presumably restored) incorrectly.. +// +// In: $r15 value to set to (0x00/0x10 are used) +// +ctx_86c: + mov $r14 0x86c + shl b32 $r14 6 + iowr I[$r14] $r15 // HUB(0x86c) = val + mov $r14 -0x75ec + sethi $r14 0x400000 + call #nv_wr32 // ROP(0xa14) = val + mov $r14 -0x5794 + sethi $r14 0x410000 + call #nv_wr32 // GPC(0x86c) = val + ret + +// ctx_load - load's a channel's ctxctl data, and selects its vm +// +// In: $r2 channel address +// +ctx_load: + trace_set(T_CHAN) + + // switch to channel, somewhat magic in parts.. + mov $r10 12 // DONE_UNK12 + call #wait_donez + mov $r1 0xa24 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r0 // 0x409a24 + mov $r3 0xb00 + shl b32 $r3 6 + iowr I[$r3 + 0x100] $r2 // CHAN_NEXT + mov $r1 0xa0c + shl b32 $r1 6 + mov $r4 7 + iowr I[$r1 + 0x000] $r2 // MEM_CHAN + iowr I[$r1 + 0x100] $r4 // MEM_CMD + ctx_chan_wait_0: + iord $r4 I[$r1 + 0x100] + and $r4 0x1f + bra ne #ctx_chan_wait_0 + iowr I[$r3 + 0x000] $r2 // CHAN_CUR + + // load channel header, fetch PGRAPH context pointer + mov $xtargets $r0 + bclr $r2 31 + shl b32 $r2 4 + add b32 $r2 2 + + trace_set(T_LCHAN) + mov $r1 0xa04 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r2 // MEM_BASE + mov $r1 0xa20 + shl b32 $r1 6 + mov $r2 0x0002 + sethi $r2 0x80000000 + iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram + mov $r1 0x10 // chan + 0x0210 + mov $r2 #xfer_data + sethi $r2 0x00020000 // 16 bytes + xdld $r1 $r2 + xdwait + trace_clr(T_LCHAN) + + // update current context + ld b32 $r1 D[$r0 + #xfer_data + 4] + shl b32 $r1 24 + ld b32 $r2 D[$r0 + #xfer_data + 0] + shr b32 $r2 8 + or $r1 $r2 + st b32 D[$r0 + #ctx_current] $r1 + + // set transfer base to start of context, and fetch context header + trace_set(T_LCTXH) + mov $r2 0xa04 + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r1 // MEM_BASE + mov $r2 1 + mov $r1 0xa20 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm + mov $r1 #chan_data + sethi $r1 0x00060000 // 256 bytes + xdld $r0 $r1 + xdwait + trace_clr(T_LCTXH) + + trace_clr(T_CHAN) + ret + +// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as +// the active channel for ctxctl, but not actually transfer +// any context data. intended for use only during initial +// context construction. +// +// In: $r2 channel address +// +ctx_chan: + call #ctx_4160s + call #ctx_load + mov $r10 12 // DONE_UNK12 + call #wait_donez + mov $r1 0xa10 + shl b32 $r1 6 + mov $r2 5 + iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???) + ctx_chan_wait: + iord $r2 I[$r1 + 0x000] + or $r2 $r2 + bra ne #ctx_chan_wait + call #ctx_4160c + ret + +// Execute per-context state overrides list +// +// Only executed on the first load of a channel. Might want to look into +// removing this and having the host directly modify the channel's context +// to change this state... The nouveau DRM already builds this list as +// it's definitely needed for NVIDIA's, so we may as well use it for now +// +// Input: $r1 mmio list length +// +ctx_mmio_exec: + // set transfer base to be the mmio list + ld b32 $r3 D[$r0 + #chan_mmio_address] + mov $r2 0xa04 + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r3 // MEM_BASE + + clear b32 $r3 + ctx_mmio_loop: + // fetch next 256 bytes of mmio list if necessary + and $r4 $r3 0xff + bra ne #ctx_mmio_pull + mov $r5 #xfer_data + sethi $r5 0x00060000 // 256 bytes + xdld $r3 $r5 + xdwait + + // execute a single list entry + ctx_mmio_pull: + ld b32 $r14 D[$r4 + #xfer_data + 0x00] + ld b32 $r15 D[$r4 + #xfer_data + 0x04] + call #nv_wr32 + + // next! + add b32 $r3 8 + sub b32 $r1 1 + bra ne #ctx_mmio_loop + + // set transfer base back to the current context + ctx_mmio_done: + ld b32 $r3 D[$r0 + #ctx_current] + iowr I[$r2 + 0x000] $r3 // MEM_BASE + + // disable the mmio list now, we don't need/want to execute it again + st b32 D[$r0 + #chan_mmio_count] $r0 + mov $r1 #chan_data + sethi $r1 0x00060000 // 256 bytes + xdst $r0 $r1 + xdwait + ret + +// Transfer HUB context data between GPU and storage area +// +// In: $r2 channel address +// $p1 clear on save, set on load +// $p2 set if opposite direction done/will be done, so: +// on save it means: "a load will follow this save" +// on load it means: "a save preceeded this load" +// +ctx_xfer: + bra not $p1 #ctx_xfer_pre + bra $p2 #ctx_xfer_pre_load + ctx_xfer_pre: + mov $r15 0x10 + call #ctx_86c + call #ctx_4160s + bra not $p1 #ctx_xfer_exec + + ctx_xfer_pre_load: + mov $r15 2 + call #ctx_4170s + call #ctx_4170w + call #ctx_redswitch + clear b32 $r15 + call #ctx_4170s + call #ctx_load + + // fetch context pointer, and initiate xfer on all GPCs + ctx_xfer_exec: + ld b32 $r1 D[$r0 + #ctx_current] + mov $r2 0x414 + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset + mov $r14 -0x5b00 + sethi $r14 0x410000 + mov b32 $r15 $r1 + call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer + add b32 $r14 4 + xbit $r15 $flags $p1 + xbit $r2 $flags $p2 + shl b32 $r2 1 + or $r15 $r2 + call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type) + + // strands + mov $r1 0x4afc + sethi $r1 0x20000 + mov $r2 0xc + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c + call #strand_wait + mov $r2 0x47fc + sethi $r2 0x20000 + iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00 + xbit $r2 $flags $p1 + add b32 $r2 3 + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD) + + // mmio context + xbit $r10 $flags $p1 // direction + or $r10 6 // first, last + mov $r11 0 // base = 0 + ld b32 $r12 D[$r0 + #hub_mmio_list_head] + ld b32 $r13 D[$r0 + #hub_mmio_list_tail] + mov $r14 0 // not multi + call #mmctx_xfer + + // wait for GPCs to all complete + mov $r10 8 // DONE_BAR + call #wait_doneo + + // wait for strand xfer to complete + call #strand_wait + + // post-op + bra $p1 #ctx_xfer_post + mov $r10 12 // DONE_UNK12 + call #wait_donez + mov $r1 0xa10 + shl b32 $r1 6 + mov $r2 5 + iowr I[$r1] $r2 // MEM_CMD + ctx_xfer_post_save_wait: + iord $r2 I[$r1] + or $r2 $r2 + bra ne #ctx_xfer_post_save_wait + + bra $p2 #ctx_xfer_done + ctx_xfer_post: + mov $r15 2 + call #ctx_4170s + clear b32 $r15 + call #ctx_86c + call #strand_post + call #ctx_4170w + clear b32 $r15 + call #ctx_4170s + + bra not $p1 #ctx_xfer_no_post_mmio + ld b32 $r1 D[$r0 + #chan_mmio_count] + or $r1 $r1 + bra e #ctx_xfer_no_post_mmio + call #ctx_mmio_exec + + ctx_xfer_no_post_mmio: + call #ctx_4160c + + ctx_xfer_done: + ret + +.align 256 diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h new file mode 100644 index 00000000000..85a8d556f48 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h @@ -0,0 +1,927 @@ +uint32_t nvc0_grhub_data[] = { +/* 0x0000: gpc_count */ + 0x00000000, +/* 0x0004: rop_count */ + 0x00000000, +/* 0x0008: cmd_queue */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0050: hub_mmio_list_head */ + 0x00000000, +/* 0x0054: hub_mmio_list_tail */ + 0x00000000, +/* 0x0058: ctx_current */ + 0x00000000, +/* 0x005c: chipsets */ + 0x000000c0, + 0x013c00a0, + 0x000000c1, + 0x014000a0, + 0x000000c3, + 0x013c00a0, + 0x000000c4, + 0x013c00a0, + 0x000000c8, + 0x013c00a0, + 0x000000ce, + 0x013c00a0, + 0x000000cf, + 0x013c00a0, + 0x000000d9, + 0x01dc0140, + 0x00000000, +/* 0x00a0: nvc0_hub_mmio_head */ + 0x0417e91c, + 0x04400204, + 0x28404004, + 0x00404044, + 0x34404094, + 0x184040d0, + 0x004040f8, + 0x08404130, + 0x08404150, + 0x04404164, + 0x08404174, + 0x1c404200, + 0x34404404, + 0x0c404460, + 0x00404480, + 0x00404498, + 0x0c404604, + 0x7c404618, + 0x50404698, + 0x044046f0, + 0x54404700, + 0x00405800, + 0x08405830, + 0x00405854, + 0x0c405870, + 0x04405a00, + 0x00405a18, + 0x00406020, + 0x0c406028, + 0x044064a8, + 0x044064b4, + 0x00407804, + 0x1440780c, + 0x004078bc, + 0x18408000, + 0x00408064, + 0x08408800, + 0x0c408900, + 0x00408980, +/* 0x013c: nvc0_hub_mmio_tail */ + 0x044064c0, +/* 0x0140: nvc1_hub_mmio_tail */ +/* 0x0140: nvd9_hub_mmio_head */ + 0x0417e91c, + 0x04400204, + 0x24404004, + 0x00404044, + 0x34404094, + 0x184040d0, + 0x004040f8, + 0x08404130, + 0x08404150, + 0x04404164, + 0x04404178, + 0x1c404200, + 0x34404404, + 0x0c404460, + 0x00404480, + 0x00404498, + 0x0c404604, + 0x7c404618, + 0x50404698, + 0x044046f0, + 0x54404700, + 0x00405800, + 0x08405830, + 0x00405854, + 0x0c405870, + 0x04405a00, + 0x00405a18, + 0x00406020, + 0x0c406028, + 0x044064a8, + 0x104064b4, + 0x00407804, + 0x1440780c, + 0x004078bc, + 0x18408000, + 0x00408064, + 0x08408800, + 0x0c408900, + 0x00408980, +/* 0x01dc: nvd9_hub_mmio_tail */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0200: chan_data */ +/* 0x0200: chan_mmio_count */ + 0x00000000, +/* 0x0204: chan_mmio_address */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0300: xfer_data */ + 0x00000000, +}; + +uint32_t nvc0_grhub_code[] = { + 0x03090ef5, +/* 0x0004: queue_put */ + 0x9800d898, + 0x86f001d9, + 0x0489b808, + 0xf00c1bf4, + 0x21f502f7, + 0x00f802ec, +/* 0x001c: queue_put_next */ + 0xb60798c4, + 0x8dbb0384, + 0x0880b600, + 0x80008e80, + 0x90b6018f, + 0x0f94f001, + 0xf801d980, +/* 0x0039: queue_get */ + 0x0131f400, + 0x9800d898, + 0x89b801d9, + 0x210bf404, + 0xb60789c4, + 0x9dbb0394, + 0x0890b600, + 0x98009e98, + 0x80b6019f, + 0x0f84f001, + 0xf400d880, +/* 0x0066: queue_get_done */ + 0x00f80132, +/* 0x0068: nv_rd32 */ + 0x0728b7f1, + 0xb906b4b6, + 0xc9f002ec, + 0x00bcd01f, +/* 0x0078: nv_rd32_wait */ + 0xc800bccf, + 0x1bf41fcc, + 0x06a7f0fa, + 0x010321f5, + 0xf840bfcf, +/* 0x008d: nv_wr32 */ + 0x28b7f100, + 0x06b4b607, + 0xb980bfd0, + 0xc9f002ec, + 0x1ec9f01f, +/* 0x00a3: nv_wr32_wait */ + 0xcf00bcd0, + 0xccc800bc, + 0xfa1bf41f, +/* 0x00ae: watchdog_reset */ + 0x87f100f8, + 0x84b60430, + 0x1ff9f006, + 0xf8008fd0, +/* 0x00bd: watchdog_clear */ + 0x3087f100, + 0x0684b604, + 0xf80080d0, +/* 0x00c9: wait_donez */ + 0x3c87f100, + 0x0684b608, + 0x99f094bd, + 0x0089d000, + 0x081887f1, + 0xd00684b6, +/* 0x00e2: wait_done_wait_donez */ + 0x87f1008a, + 0x84b60400, + 0x0088cf06, + 0xf4888aff, + 0x87f1f31b, + 0x84b6085c, + 0xf094bd06, + 0x89d00099, +/* 0x0103: wait_doneo */ + 0xf100f800, + 0xb6083c87, + 0x94bd0684, + 0xd00099f0, + 0x87f10089, + 0x84b60818, + 0x008ad006, +/* 0x011c: wait_done_wait_doneo */ + 0x040087f1, + 0xcf0684b6, + 0x8aff0088, + 0xf30bf488, + 0x085c87f1, + 0xbd0684b6, + 0x0099f094, + 0xf80089d0, +/* 0x013d: mmctx_size */ +/* 0x013f: nv_mmctx_size_loop */ + 0x9894bd00, + 0x85b600e8, + 0x0180b61a, + 0xbb0284b6, + 0xe0b60098, + 0x04efb804, + 0xb9eb1bf4, + 0x00f8029f, +/* 0x015c: mmctx_xfer */ + 0x083c87f1, + 0xbd0684b6, + 0x0199f094, + 0xf10089d0, + 0xb6071087, + 0x94bd0684, + 0xf405bbfd, + 0x8bd0090b, + 0x0099f000, +/* 0x0180: mmctx_base_disabled */ + 0xf405eefd, + 0x8ed00c0b, + 0xc08fd080, +/* 0x018f: mmctx_multi_disabled */ + 0xb70199f0, + 0xc8010080, + 0xb4b600ab, + 0x0cb9f010, + 0xb601aec8, + 0xbefd11e4, + 0x008bd005, +/* 0x01a8: mmctx_exec_loop */ +/* 0x01a8: mmctx_wait_free */ + 0xf0008ecf, + 0x0bf41fe4, + 0x00ce98fa, + 0xd005e9fd, + 0xc0b6c08e, + 0x04cdb804, + 0xc8e81bf4, + 0x1bf402ab, +/* 0x01c9: mmctx_fini_wait */ + 0x008bcf18, + 0xb01fb4f0, + 0x1bf410b4, + 0x02a7f0f7, + 0xf4c921f4, +/* 0x01de: mmctx_stop */ + 0xabc81b0e, + 0x10b4b600, + 0xf00cb9f0, + 0x8bd012b9, +/* 0x01ed: mmctx_stop_wait */ + 0x008bcf00, + 0xf412bbc8, +/* 0x01f6: mmctx_done */ + 0x87f1fa1b, + 0x84b6085c, + 0xf094bd06, + 0x89d00199, +/* 0x0207: strand_wait */ + 0xf900f800, + 0x02a7f0a0, + 0xfcc921f4, +/* 0x0213: strand_pre */ + 0xf100f8a0, + 0xf04afc87, + 0x97f00283, + 0x0089d00c, + 0x020721f5, +/* 0x0226: strand_post */ + 0x87f100f8, + 0x83f04afc, + 0x0d97f002, + 0xf50089d0, + 0xf8020721, +/* 0x0239: strand_set */ + 0xfca7f100, + 0x02a3f04f, + 0x0500aba2, + 0xd00fc7f0, + 0xc7f000ac, + 0x00bcd00b, + 0x020721f5, + 0xf000aed0, + 0xbcd00ac7, + 0x0721f500, +/* 0x0263: strand_ctx_init */ + 0xf100f802, + 0xb6083c87, + 0x94bd0684, + 0xd00399f0, + 0x21f50089, + 0xe7f00213, + 0x3921f503, + 0xfca7f102, + 0x02a3f046, + 0x0400aba0, + 0xf040a0d0, + 0xbcd001c7, + 0x0721f500, + 0x010c9202, + 0xf000acd0, + 0xbcd002c7, + 0x0721f500, + 0x2621f502, + 0x8087f102, + 0x0684b608, + 0xb70089cf, + 0x95220080, +/* 0x02ba: ctx_init_strand_loop */ + 0x8ed008fe, + 0x408ed000, + 0xb6808acf, + 0xa0b606a5, + 0x00eabb01, + 0xb60480b6, + 0x1bf40192, + 0x08e4b6e8, + 0xf1f2efbc, + 0xb6085c87, + 0x94bd0684, + 0xd00399f0, + 0x00f80089, +/* 0x02ec: error */ + 0xe7f1e0f9, + 0xe4b60814, + 0x00efd006, + 0x0c1ce7f1, + 0xf006e4b6, + 0xefd001f7, + 0xf8e0fc00, +/* 0x0309: init */ + 0xfe04bd00, + 0x07fe0004, + 0x0017f100, + 0x0227f012, + 0xf10012d0, + 0xfe05b917, + 0x17f10010, + 0x10d00400, + 0x0437f1c0, + 0x0634b604, + 0x200327f1, + 0xf10032d0, + 0xd0200427, + 0x27f10132, + 0x32d0200b, + 0x0c27f102, + 0x0732d020, + 0x0c2427f1, + 0xb90624b6, + 0x23d00003, + 0x0427f100, + 0x0023f087, + 0xb70012d0, + 0xf0010012, + 0x12d00427, + 0x1031f400, + 0x9604e7f1, + 0xf440e3f0, + 0xf1c76821, + 0x01018090, + 0x801ff4f0, + 0x17f0000f, + 0x041fbb01, + 0xf10112b6, + 0xb6040c27, + 0x21d00624, + 0x4021d000, + 0x080027f1, + 0xcf0624b6, + 0xf7f00022, +/* 0x03a9: init_find_chipset */ + 0x08f0b654, + 0xb800f398, + 0x0bf40432, + 0x0034b00b, + 0xf8f11bf4, +/* 0x03bd: init_context */ + 0x0017f100, + 0x02fe5801, + 0xf003ff58, + 0x0e8000e3, + 0x150f8014, + 0x013d21f5, + 0x070037f1, + 0x950634b6, + 0x34d00814, + 0x4034d000, + 0x130030b7, + 0xb6001fbb, + 0x3fd002f5, + 0x0815b600, + 0xb60110b6, + 0x1fb90814, + 0x6321f502, + 0x001fbb02, + 0xf1000398, + 0xf0200047, +/* 0x040e: init_gpc */ + 0x4ea05043, + 0x1fb90804, + 0x8d21f402, + 0x08004ea0, + 0xf4022fb9, + 0x4ea08d21, + 0xf4bd010c, + 0xa08d21f4, + 0xf401044e, + 0x4ea08d21, + 0xf7f00100, + 0x8d21f402, + 0x08004ea0, +/* 0x0440: init_gpc_wait */ + 0xc86821f4, + 0x0bf41fff, + 0x044ea0fa, + 0x6821f408, + 0xb7001fbb, + 0xb6800040, + 0x1bf40132, + 0x0027f1b4, + 0x0624b608, + 0xb74021d0, + 0xbd080020, + 0x1f19f014, +/* 0x0473: main */ + 0xf40021d0, + 0x28f40031, + 0x08d7f000, + 0xf43921f4, + 0xe4b1f401, + 0x1bf54001, + 0x87f100d1, + 0x84b6083c, + 0xf094bd06, + 0x89d00499, + 0x0017f100, + 0x0614b60b, + 0xcf4012cf, + 0x13c80011, + 0x7e0bf41f, + 0xf41f23c8, + 0x20f95a0b, + 0xf10212b9, + 0xb6083c87, + 0x94bd0684, + 0xd00799f0, + 0x32f40089, + 0x0231f401, + 0x082921f5, + 0x085c87f1, + 0xbd0684b6, + 0x0799f094, + 0xfc0089d0, + 0x3c87f120, + 0x0684b608, + 0x99f094bd, + 0x0089d006, + 0xf50131f4, + 0xf1082921, + 0xb6085c87, + 0x94bd0684, + 0xd00699f0, + 0x0ef40089, +/* 0x0509: chsw_prev_no_next */ + 0xb920f931, + 0x32f40212, + 0x0232f401, + 0x082921f5, + 0x17f120fc, + 0x14b60b00, + 0x0012d006, +/* 0x0527: chsw_no_prev */ + 0xc8130ef4, + 0x0bf41f23, + 0x0131f40d, + 0xf50232f4, +/* 0x0537: chsw_done */ + 0xf1082921, + 0xb60b0c17, + 0x27f00614, + 0x0012d001, + 0x085c87f1, + 0xbd0684b6, + 0x0499f094, + 0xf50089d0, +/* 0x0557: main_not_ctx_switch */ + 0xb0ff200e, + 0x1bf401e4, + 0x02f2b90d, + 0x07b521f5, +/* 0x0567: main_not_ctx_chan */ + 0xb0420ef4, + 0x1bf402e4, + 0x3c87f12e, + 0x0684b608, + 0x99f094bd, + 0x0089d007, + 0xf40132f4, + 0x21f50232, + 0x87f10829, + 0x84b6085c, + 0xf094bd06, + 0x89d00799, + 0x110ef400, +/* 0x0598: main_not_ctx_save */ + 0xf010ef94, + 0x21f501f5, + 0x0ef502ec, +/* 0x05a6: main_done */ + 0x17f1fed1, + 0x14b60820, + 0xf024bd06, + 0x12d01f29, + 0xbe0ef500, +/* 0x05b9: ih */ + 0xfe80f9fe, + 0x80f90188, + 0xa0f990f9, + 0xd0f9b0f9, + 0xf0f9e0f9, + 0xc4800acf, + 0x0bf404ab, + 0x00b7f11d, + 0x08d7f019, + 0xcf40becf, + 0x21f400bf, + 0x00b0b704, + 0x01e7f004, +/* 0x05ef: ih_no_fifo */ + 0xe400bed0, + 0xf40100ab, + 0xd7f00d0b, + 0x01e7f108, + 0x0421f440, +/* 0x0600: ih_no_ctxsw */ + 0x0104b7f1, + 0xabffb0bd, + 0x0d0bf4b4, + 0x0c1ca7f1, + 0xd006a4b6, +/* 0x0616: ih_no_other */ + 0x0ad000ab, + 0xfcf0fc40, + 0xfcd0fce0, + 0xfca0fcb0, + 0xfe80fc90, + 0x80fc0088, + 0xf80032f4, +/* 0x0631: ctx_4160s */ + 0x60e7f101, + 0x40e3f041, + 0xf401f7f0, +/* 0x063e: ctx_4160s_wait */ + 0x21f48d21, + 0x04ffc868, + 0xf8fa0bf4, +/* 0x0649: ctx_4160c */ + 0x60e7f100, + 0x40e3f041, + 0x21f4f4bd, +/* 0x0657: ctx_4170s */ + 0xf100f88d, + 0xf04170e7, + 0xf5f040e3, + 0x8d21f410, +/* 0x0666: ctx_4170w */ + 0xe7f100f8, + 0xe3f04170, + 0x6821f440, + 0xf410f4f0, + 0x00f8f31b, +/* 0x0678: ctx_redswitch */ + 0x0614e7f1, + 0xf106e4b6, + 0xd00270f7, + 0xf7f000ef, +/* 0x0689: ctx_redswitch_delay */ + 0x01f2b608, + 0xf1fd1bf4, + 0xd00770f7, + 0x00f800ef, +/* 0x0698: ctx_86c */ + 0x086ce7f1, + 0xd006e4b6, + 0xe7f100ef, + 0xe3f08a14, + 0x8d21f440, + 0xa86ce7f1, + 0xf441e3f0, + 0x00f88d21, +/* 0x06b8: ctx_load */ + 0x083c87f1, + 0xbd0684b6, + 0x0599f094, + 0xf00089d0, + 0x21f40ca7, + 0x2417f1c9, + 0x0614b60a, + 0xf10010d0, + 0xb60b0037, + 0x32d00634, + 0x0c17f140, + 0x0614b60a, + 0xd00747f0, + 0x14d00012, +/* 0x06f1: ctx_chan_wait_0 */ + 0x4014cf40, + 0xf41f44f0, + 0x32d0fa1b, + 0x000bfe00, + 0xb61f2af0, + 0x20b60424, + 0x3c87f102, + 0x0684b608, + 0x99f094bd, + 0x0089d008, + 0x0a0417f1, + 0xd00614b6, + 0x17f10012, + 0x14b60a20, + 0x0227f006, + 0x800023f1, + 0xf00012d0, + 0x27f11017, + 0x23f00300, + 0x0512fa02, + 0x87f103f8, + 0x84b6085c, + 0xf094bd06, + 0x89d00899, + 0xc1019800, + 0x981814b6, + 0x25b6c002, + 0x0512fd08, + 0xf1160180, + 0xb6083c87, + 0x94bd0684, + 0xd00999f0, + 0x27f10089, + 0x24b60a04, + 0x0021d006, + 0xf10127f0, + 0xb60a2017, + 0x12d00614, + 0x0017f100, + 0x0613f002, + 0xf80501fa, + 0x5c87f103, + 0x0684b608, + 0x99f094bd, + 0x0089d009, + 0x085c87f1, + 0xbd0684b6, + 0x0599f094, + 0xf80089d0, +/* 0x07b5: ctx_chan */ + 0x3121f500, + 0xb821f506, + 0x0ca7f006, + 0xf1c921f4, + 0xb60a1017, + 0x27f00614, + 0x0012d005, +/* 0x07d0: ctx_chan_wait */ + 0xfd0012cf, + 0x1bf40522, + 0x4921f5fa, +/* 0x07df: ctx_mmio_exec */ + 0x9800f806, + 0x27f18103, + 0x24b60a04, + 0x0023d006, +/* 0x07ee: ctx_mmio_loop */ + 0x34c434bd, + 0x0f1bf4ff, + 0x030057f1, + 0xfa0653f0, + 0x03f80535, +/* 0x0800: ctx_mmio_pull */ + 0x98c04e98, + 0x21f4c14f, + 0x0830b68d, + 0xf40112b6, +/* 0x0812: ctx_mmio_done */ + 0x0398df1b, + 0x0023d016, + 0xf1800080, + 0xf0020017, + 0x01fa0613, + 0xf803f806, +/* 0x0829: ctx_xfer */ + 0x0611f400, +/* 0x082f: ctx_xfer_pre */ + 0xf01102f4, + 0x21f510f7, + 0x21f50698, + 0x11f40631, +/* 0x083d: ctx_xfer_pre_load */ + 0x02f7f01c, + 0x065721f5, + 0x066621f5, + 0x067821f5, + 0x21f5f4bd, + 0x21f50657, +/* 0x0856: ctx_xfer_exec */ + 0x019806b8, + 0x1427f116, + 0x0624b604, + 0xf10020d0, + 0xf0a500e7, + 0x1fb941e3, + 0x8d21f402, + 0xf004e0b6, + 0x2cf001fc, + 0x0124b602, + 0xf405f2fd, + 0x17f18d21, + 0x13f04afc, + 0x0c27f002, + 0xf50012d0, + 0xf1020721, + 0xf047fc27, + 0x20d00223, + 0x012cf000, + 0xd00320b6, + 0xacf00012, + 0x06a5f001, + 0x9800b7f0, + 0x0d98140c, + 0x00e7f015, + 0x015c21f5, + 0xf508a7f0, + 0xf5010321, + 0xf4020721, + 0xa7f02201, + 0xc921f40c, + 0x0a1017f1, + 0xf00614b6, + 0x12d00527, +/* 0x08dd: ctx_xfer_post_save_wait */ + 0x0012cf00, + 0xf40522fd, + 0x02f4fa1b, +/* 0x08e9: ctx_xfer_post */ + 0x02f7f032, + 0x065721f5, + 0x21f5f4bd, + 0x21f50698, + 0x21f50226, + 0xf4bd0666, + 0x065721f5, + 0x981011f4, + 0x11fd8001, + 0x070bf405, + 0x07df21f5, +/* 0x0914: ctx_xfer_no_post_mmio */ + 0x064921f5, +/* 0x0918: ctx_xfer_done */ + 0x000000f8, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc new file mode 100644 index 00000000000..138eeaa2866 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc @@ -0,0 +1,780 @@ +/* fuc microcode for nve0 PGRAPH/HUB + * + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +/* To build: + * m4 nve0_grhub.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grhub.fuc.h + */ + +.section #nve0_grhub_data +include(`nve0.fuc') +gpc_count: .b32 0 +rop_count: .b32 0 +cmd_queue: queue_init +hub_mmio_list_head: .b32 0 +hub_mmio_list_tail: .b32 0 + +ctx_current: .b32 0 + +chipsets: +.b8 0xe4 0 0 0 +.b16 #nve4_hub_mmio_head +.b16 #nve4_hub_mmio_tail +.b8 0xe7 0 0 0 +.b16 #nve4_hub_mmio_head +.b16 #nve4_hub_mmio_tail +.b8 0 0 0 0 + +nve4_hub_mmio_head: +mmctx_data(0x17e91c, 2) +mmctx_data(0x400204, 2) +mmctx_data(0x404010, 7) +mmctx_data(0x4040a8, 9) +mmctx_data(0x4040d0, 7) +mmctx_data(0x4040f8, 1) +mmctx_data(0x404130, 3) +mmctx_data(0x404150, 3) +mmctx_data(0x404164, 1) +mmctx_data(0x4041a0, 4) +mmctx_data(0x404200, 4) +mmctx_data(0x404404, 14) +mmctx_data(0x404460, 4) +mmctx_data(0x404480, 1) +mmctx_data(0x404498, 1) +mmctx_data(0x404604, 4) +mmctx_data(0x404618, 4) +mmctx_data(0x40462c, 2) +mmctx_data(0x404640, 1) +mmctx_data(0x404654, 1) +mmctx_data(0x404660, 1) +mmctx_data(0x404678, 19) +mmctx_data(0x4046c8, 3) +mmctx_data(0x404700, 3) +mmctx_data(0x404718, 10) +mmctx_data(0x404744, 2) +mmctx_data(0x404754, 1) +mmctx_data(0x405800, 1) +mmctx_data(0x405830, 3) +mmctx_data(0x405854, 1) +mmctx_data(0x405870, 4) +mmctx_data(0x405a00, 2) +mmctx_data(0x405a18, 1) +mmctx_data(0x405b00, 1) +mmctx_data(0x405b10, 1) +mmctx_data(0x406020, 1) +mmctx_data(0x406028, 4) +mmctx_data(0x4064a8, 2) +mmctx_data(0x4064b4, 2) +mmctx_data(0x4064c0, 12) +mmctx_data(0x4064fc, 1) +mmctx_data(0x407040, 1) +mmctx_data(0x407804, 1) +mmctx_data(0x40780c, 6) +mmctx_data(0x4078bc, 1) +mmctx_data(0x408000, 7) +mmctx_data(0x408064, 1) +mmctx_data(0x408800, 3) +mmctx_data(0x408840, 1) +mmctx_data(0x408900, 3) +mmctx_data(0x408980, 1) +nve4_hub_mmio_tail: + +.align 256 +chan_data: +chan_mmio_count: .b32 0 +chan_mmio_address: .b32 0 + +.align 256 +xfer_data: .b32 0 + +.section #nve0_grhub_code +bra #init +define(`include_code') +include(`nve0.fuc') + +// reports an exception to the host +// +// In: $r15 error code (see nve0.fuc) +// +error: + push $r14 + mov $r14 0x814 + shl b32 $r14 6 + iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code + mov $r14 0xc1c + shl b32 $r14 6 + mov $r15 1 + iowr I[$r14 + 0x000] $r15 // INTR_UP_SET + pop $r14 + ret + +// HUB fuc initialisation, executed by triggering ucode start, will +// fall through to main loop after completion. +// +// Input: +// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh) +// +// Output: +// CC_SCRATCH[0]: +// 31:31: set to signal completion +// CC_SCRATCH[1]: +// 31:0: total PGRAPH context size +// +init: + clear b32 $r0 + mov $sp $r0 + mov $xdbase $r0 + + // enable fifo access + mov $r1 0x1200 + mov $r2 2 + iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE + + // setup i0 handler, and route all interrupts to it + mov $r1 #ih + mov $iv0 $r1 + mov $r1 0x400 + iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH + + // route HUB_CHANNEL_SWITCH to fuc interrupt 8 + mov $r3 0x404 + shl b32 $r3 6 + mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8 + iowr I[$r3 + 0x000] $r2 + + // not sure what these are, route them because NVIDIA does, and + // the IRQ handler will signal the host if we ever get one.. we + // may find out if/why we need to handle these if so.. + // + mov $r2 0x2004 + iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9 + mov $r2 0x200b + iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10 + mov $r2 0x200c + iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15 + + // enable all INTR_UP interrupts + mov $r2 0xc24 + shl b32 $r2 6 + not b32 $r3 $r0 + iowr I[$r2] $r3 + + // enable fifo, ctxsw, 9, 10, 15 interrupts + mov $r2 -0x78fc // 0x8704 + sethi $r2 0 + iowr I[$r1 + 0x000] $r2 // INTR_EN_SET + + // fifo level triggered, rest edge + sub b32 $r1 0x100 + mov $r2 4 + iowr I[$r1] $r2 + + // enable interrupts + bset $flags ie0 + + // fetch enabled GPC/ROP counts + mov $r14 -0x69fc // 0x409604 + sethi $r14 0x400000 + call #nv_rd32 + extr $r1 $r15 16:20 + st b32 D[$r0 + #rop_count] $r1 + and $r15 0x1f + st b32 D[$r0 + #gpc_count] $r15 + + // set BAR_REQMASK to GPC mask + mov $r1 1 + shl b32 $r1 $r15 + sub b32 $r1 1 + mov $r2 0x40c + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r1 + iowr I[$r2 + 0x100] $r1 + + // find context data for this chipset + mov $r2 0x800 + shl b32 $r2 6 + iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0] + mov $r15 #chipsets - 8 + init_find_chipset: + add b32 $r15 8 + ld b32 $r3 D[$r15 + 0x00] + cmpu b32 $r3 $r2 + bra e #init_context + cmpu b32 $r3 0 + bra ne #init_find_chipset + // unknown chipset + ret + + // context size calculation, reserve first 256 bytes for use by fuc + init_context: + mov $r1 256 + + // calculate size of mmio context data + ld b16 $r14 D[$r15 + 4] + ld b16 $r15 D[$r15 + 6] + sethi $r14 0 + st b32 D[$r0 + #hub_mmio_list_head] $r14 + st b32 D[$r0 + #hub_mmio_list_tail] $r15 + call #mmctx_size + + // set mmctx base addresses now so we don't have to do it later, + // they don't (currently) ever change + mov $r3 0x700 + shl b32 $r3 6 + shr b32 $r4 $r1 8 + iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE + iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE + add b32 $r3 0x1300 + add b32 $r1 $r15 + shr b32 $r15 2 + iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!? + + // strands, base offset needs to be aligned to 256 bytes + shr b32 $r1 8 + add b32 $r1 1 + shl b32 $r1 8 + mov b32 $r15 $r1 + call #strand_ctx_init + add b32 $r1 $r15 + + // initialise each GPC in sequence by passing in the offset of its + // context data in GPCn_CC_SCRATCH[1], and starting its FUC (which + // has previously been uploaded by the host) running. + // + // the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31 + // when it has completed, and return the size of its context data + // in GPCn_CC_SCRATCH[1] + // + ld b32 $r3 D[$r0 + #gpc_count] + mov $r4 0x2000 + sethi $r4 0x500000 + init_gpc: + // setup, and start GPC ucode running + add b32 $r14 $r4 0x804 + mov b32 $r15 $r1 + call #nv_wr32 // CC_SCRATCH[1] = ctx offset + add b32 $r14 $r4 0x800 + mov b32 $r15 $r2 + call #nv_wr32 // CC_SCRATCH[0] = chipset + add b32 $r14 $r4 0x10c + clear b32 $r15 + call #nv_wr32 + add b32 $r14 $r4 0x104 + call #nv_wr32 // ENTRY + add b32 $r14 $r4 0x100 + mov $r15 2 // CTRL_START_TRIGGER + call #nv_wr32 // CTRL + + // wait for it to complete, and adjust context size + add b32 $r14 $r4 0x800 + init_gpc_wait: + call #nv_rd32 + xbit $r15 $r15 31 + bra e #init_gpc_wait + add b32 $r14 $r4 0x804 + call #nv_rd32 + add b32 $r1 $r15 + + // next! + add b32 $r4 0x8000 + sub b32 $r3 1 + bra ne #init_gpc + + // save context size, and tell host we're ready + mov $r2 0x800 + shl b32 $r2 6 + iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size + add b32 $r2 0x800 + clear b32 $r1 + bset $r1 31 + iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000 + +// Main program loop, very simple, sleeps until woken up by the interrupt +// handler, pulls a command from the queue and executes its handler +// +main: + // sleep until we have something to do + bset $flags $p0 + sleep $p0 + mov $r13 #cmd_queue + call #queue_get + bra $p1 #main + + // context switch, requested by GPU? + cmpu b32 $r14 0x4001 + bra ne #main_not_ctx_switch + trace_set(T_AUTO) + mov $r1 0xb00 + shl b32 $r1 6 + iord $r2 I[$r1 + 0x100] // CHAN_NEXT + iord $r1 I[$r1 + 0x000] // CHAN_CUR + + xbit $r3 $r1 31 + bra e #chsw_no_prev + xbit $r3 $r2 31 + bra e #chsw_prev_no_next + push $r2 + mov b32 $r2 $r1 + trace_set(T_SAVE) + bclr $flags $p1 + bset $flags $p2 + call #ctx_xfer + trace_clr(T_SAVE); + pop $r2 + trace_set(T_LOAD); + bset $flags $p1 + call #ctx_xfer + trace_clr(T_LOAD); + bra #chsw_done + chsw_prev_no_next: + push $r2 + mov b32 $r2 $r1 + bclr $flags $p1 + bclr $flags $p2 + call #ctx_xfer + pop $r2 + mov $r1 0xb00 + shl b32 $r1 6 + iowr I[$r1] $r2 + bra #chsw_done + chsw_no_prev: + xbit $r3 $r2 31 + bra e #chsw_done + bset $flags $p1 + bclr $flags $p2 + call #ctx_xfer + + // ack the context switch request + chsw_done: + mov $r1 0xb0c + shl b32 $r1 6 + mov $r2 1 + iowr I[$r1 + 0x000] $r2 // 0x409b0c + trace_clr(T_AUTO) + bra #main + + // request to set current channel? (*not* a context switch) + main_not_ctx_switch: + cmpu b32 $r14 0x0001 + bra ne #main_not_ctx_chan + mov b32 $r2 $r15 + call #ctx_chan + bra #main_done + + // request to store current channel context? + main_not_ctx_chan: + cmpu b32 $r14 0x0002 + bra ne #main_not_ctx_save + trace_set(T_SAVE) + bclr $flags $p1 + bclr $flags $p2 + call #ctx_xfer + trace_clr(T_SAVE) + bra #main_done + + main_not_ctx_save: + shl b32 $r15 $r14 16 + or $r15 E_BAD_COMMAND + call #error + bra #main + + main_done: + mov $r1 0x820 + shl b32 $r1 6 + clear b32 $r2 + bset $r2 31 + iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000 + bra #main + +// interrupt handler +ih: + push $r8 + mov $r8 $flags + push $r8 + push $r9 + push $r10 + push $r11 + push $r13 + push $r14 + push $r15 + + // incoming fifo command? + iord $r10 I[$r0 + 0x200] // INTR + and $r11 $r10 0x00000004 + bra e #ih_no_fifo + // queue incoming fifo command for later processing + mov $r11 0x1900 + mov $r13 #cmd_queue + iord $r14 I[$r11 + 0x100] // FIFO_CMD + iord $r15 I[$r11 + 0x000] // FIFO_DATA + call #queue_put + add b32 $r11 0x400 + mov $r14 1 + iowr I[$r11 + 0x000] $r14 // FIFO_ACK + + // context switch request? + ih_no_fifo: + and $r11 $r10 0x00000100 + bra e #ih_no_ctxsw + // enqueue a context switch for later processing + mov $r13 #cmd_queue + mov $r14 0x4001 + call #queue_put + + // anything we didn't handle, bring it to the host's attention + ih_no_ctxsw: + mov $r11 0x104 + not b32 $r11 + and $r11 $r10 $r11 + bra e #ih_no_other + mov $r10 0xc1c + shl b32 $r10 6 + iowr I[$r10] $r11 // INTR_UP_SET + + // ack, and wake up main() + ih_no_other: + iowr I[$r0 + 0x100] $r10 // INTR_ACK + + pop $r15 + pop $r14 + pop $r13 + pop $r11 + pop $r10 + pop $r9 + pop $r8 + mov $flags $r8 + pop $r8 + bclr $flags $p0 + iret + +// Again, not real sure +// +// In: $r15 value to set 0x404170 to +// +ctx_4170s: + mov $r14 0x4170 + sethi $r14 0x400000 + or $r15 0x10 + call #nv_wr32 + ret + +// Waits for a ctx_4170s() call to complete +// +ctx_4170w: + mov $r14 0x4170 + sethi $r14 0x400000 + call #nv_rd32 + and $r15 0x10 + bra ne #ctx_4170w + ret + +// Disables various things, waits a bit, and re-enables them.. +// +// Not sure how exactly this helps, perhaps "ENABLE" is not such a +// good description for the bits we turn off? Anyways, without this, +// funny things happen. +// +ctx_redswitch: + mov $r14 0x614 + shl b32 $r14 6 + mov $r15 0x270 + iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL + mov $r15 8 + ctx_redswitch_delay: + sub b32 $r15 1 + bra ne #ctx_redswitch_delay + mov $r15 0x770 + iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL + ret + +// Not a clue what this is for, except that unless the value is 0x10, the +// strand context is saved (and presumably restored) incorrectly.. +// +// In: $r15 value to set to (0x00/0x10 are used) +// +ctx_86c: + mov $r14 0x86c + shl b32 $r14 6 + iowr I[$r14] $r15 // HUB(0x86c) = val + mov $r14 -0x75ec + sethi $r14 0x400000 + call #nv_wr32 // ROP(0xa14) = val + mov $r14 -0x5794 + sethi $r14 0x410000 + call #nv_wr32 // GPC(0x86c) = val + ret + +// ctx_load - load's a channel's ctxctl data, and selects its vm +// +// In: $r2 channel address +// +ctx_load: + trace_set(T_CHAN) + + // switch to channel, somewhat magic in parts.. + mov $r10 12 // DONE_UNK12 + call #wait_donez + mov $r1 0xa24 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r0 // 0x409a24 + mov $r3 0xb00 + shl b32 $r3 6 + iowr I[$r3 + 0x100] $r2 // CHAN_NEXT + mov $r1 0xa0c + shl b32 $r1 6 + mov $r4 7 + iowr I[$r1 + 0x000] $r2 // MEM_CHAN + iowr I[$r1 + 0x100] $r4 // MEM_CMD + ctx_chan_wait_0: + iord $r4 I[$r1 + 0x100] + and $r4 0x1f + bra ne #ctx_chan_wait_0 + iowr I[$r3 + 0x000] $r2 // CHAN_CUR + + // load channel header, fetch PGRAPH context pointer + mov $xtargets $r0 + bclr $r2 31 + shl b32 $r2 4 + add b32 $r2 2 + + trace_set(T_LCHAN) + mov $r1 0xa04 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r2 // MEM_BASE + mov $r1 0xa20 + shl b32 $r1 6 + mov $r2 0x0002 + sethi $r2 0x80000000 + iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram + mov $r1 0x10 // chan + 0x0210 + mov $r2 #xfer_data + sethi $r2 0x00020000 // 16 bytes + xdld $r1 $r2 + xdwait + trace_clr(T_LCHAN) + + // update current context + ld b32 $r1 D[$r0 + #xfer_data + 4] + shl b32 $r1 24 + ld b32 $r2 D[$r0 + #xfer_data + 0] + shr b32 $r2 8 + or $r1 $r2 + st b32 D[$r0 + #ctx_current] $r1 + + // set transfer base to start of context, and fetch context header + trace_set(T_LCTXH) + mov $r2 0xa04 + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r1 // MEM_BASE + mov $r2 1 + mov $r1 0xa20 + shl b32 $r1 6 + iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm + mov $r1 #chan_data + sethi $r1 0x00060000 // 256 bytes + xdld $r0 $r1 + xdwait + trace_clr(T_LCTXH) + + trace_clr(T_CHAN) + ret + +// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as +// the active channel for ctxctl, but not actually transfer +// any context data. intended for use only during initial +// context construction. +// +// In: $r2 channel address +// +ctx_chan: + call #ctx_load + mov $r10 12 // DONE_UNK12 + call #wait_donez + mov $r1 0xa10 + shl b32 $r1 6 + mov $r2 5 + iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???) + ctx_chan_wait: + iord $r2 I[$r1 + 0x000] + or $r2 $r2 + bra ne #ctx_chan_wait + ret + +// Execute per-context state overrides list +// +// Only executed on the first load of a channel. Might want to look into +// removing this and having the host directly modify the channel's context +// to change this state... The nouveau DRM already builds this list as +// it's definitely needed for NVIDIA's, so we may as well use it for now +// +// Input: $r1 mmio list length +// +ctx_mmio_exec: + // set transfer base to be the mmio list + ld b32 $r3 D[$r0 + #chan_mmio_address] + mov $r2 0xa04 + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r3 // MEM_BASE + + clear b32 $r3 + ctx_mmio_loop: + // fetch next 256 bytes of mmio list if necessary + and $r4 $r3 0xff + bra ne #ctx_mmio_pull + mov $r5 #xfer_data + sethi $r5 0x00060000 // 256 bytes + xdld $r3 $r5 + xdwait + + // execute a single list entry + ctx_mmio_pull: + ld b32 $r14 D[$r4 + #xfer_data + 0x00] + ld b32 $r15 D[$r4 + #xfer_data + 0x04] + call #nv_wr32 + + // next! + add b32 $r3 8 + sub b32 $r1 1 + bra ne #ctx_mmio_loop + + // set transfer base back to the current context + ctx_mmio_done: + ld b32 $r3 D[$r0 + #ctx_current] + iowr I[$r2 + 0x000] $r3 // MEM_BASE + + // disable the mmio list now, we don't need/want to execute it again + st b32 D[$r0 + #chan_mmio_count] $r0 + mov $r1 #chan_data + sethi $r1 0x00060000 // 256 bytes + xdst $r0 $r1 + xdwait + ret + +// Transfer HUB context data between GPU and storage area +// +// In: $r2 channel address +// $p1 clear on save, set on load +// $p2 set if opposite direction done/will be done, so: +// on save it means: "a load will follow this save" +// on load it means: "a save preceeded this load" +// +ctx_xfer: + bra not $p1 #ctx_xfer_pre + bra $p2 #ctx_xfer_pre_load + ctx_xfer_pre: + mov $r15 0x10 + call #ctx_86c + bra not $p1 #ctx_xfer_exec + + ctx_xfer_pre_load: + mov $r15 2 + call #ctx_4170s + call #ctx_4170w + call #ctx_redswitch + clear b32 $r15 + call #ctx_4170s + call #ctx_load + + // fetch context pointer, and initiate xfer on all GPCs + ctx_xfer_exec: + ld b32 $r1 D[$r0 + #ctx_current] + mov $r2 0x414 + shl b32 $r2 6 + iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset + mov $r14 -0x5b00 + sethi $r14 0x410000 + mov b32 $r15 $r1 + call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer + add b32 $r14 4 + xbit $r15 $flags $p1 + xbit $r2 $flags $p2 + shl b32 $r2 1 + or $r15 $r2 + call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type) + + // strands + mov $r1 0x4afc + sethi $r1 0x20000 + mov $r2 0xc + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c + call #strand_wait + mov $r2 0x47fc + sethi $r2 0x20000 + iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00 + xbit $r2 $flags $p1 + add b32 $r2 3 + iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD) + + // mmio context + xbit $r10 $flags $p1 // direction + or $r10 6 // first, last + mov $r11 0 // base = 0 + ld b32 $r12 D[$r0 + #hub_mmio_list_head] + ld b32 $r13 D[$r0 + #hub_mmio_list_tail] + mov $r14 0 // not multi + call #mmctx_xfer + + // wait for GPCs to all complete + mov $r10 8 // DONE_BAR + call #wait_doneo + + // wait for strand xfer to complete + call #strand_wait + + // post-op + bra $p1 #ctx_xfer_post + mov $r10 12 // DONE_UNK12 + call #wait_donez + mov $r1 0xa10 + shl b32 $r1 6 + mov $r2 5 + iowr I[$r1] $r2 // MEM_CMD + ctx_xfer_post_save_wait: + iord $r2 I[$r1] + or $r2 $r2 + bra ne #ctx_xfer_post_save_wait + + bra $p2 #ctx_xfer_done + ctx_xfer_post: + mov $r15 2 + call #ctx_4170s + clear b32 $r15 + call #ctx_86c + call #strand_post + call #ctx_4170w + clear b32 $r15 + call #ctx_4170s + + bra not $p1 #ctx_xfer_no_post_mmio + ld b32 $r1 D[$r0 + #chan_mmio_count] + or $r1 $r1 + bra e #ctx_xfer_no_post_mmio + call #ctx_mmio_exec + + ctx_xfer_no_post_mmio: + + ctx_xfer_done: + ret + +.align 256 diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h new file mode 100644 index 00000000000..decf0c60ca3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h @@ -0,0 +1,857 @@ +uint32_t nve0_grhub_data[] = { +/* 0x0000: gpc_count */ + 0x00000000, +/* 0x0004: rop_count */ + 0x00000000, +/* 0x0008: cmd_queue */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0050: hub_mmio_list_head */ + 0x00000000, +/* 0x0054: hub_mmio_list_tail */ + 0x00000000, +/* 0x0058: ctx_current */ + 0x00000000, +/* 0x005c: chipsets */ + 0x000000e4, + 0x013c0070, + 0x000000e7, + 0x013c0070, + 0x00000000, +/* 0x0070: nve4_hub_mmio_head */ + 0x0417e91c, + 0x04400204, + 0x18404010, + 0x204040a8, + 0x184040d0, + 0x004040f8, + 0x08404130, + 0x08404150, + 0x00404164, + 0x0c4041a0, + 0x0c404200, + 0x34404404, + 0x0c404460, + 0x00404480, + 0x00404498, + 0x0c404604, + 0x0c404618, + 0x0440462c, + 0x00404640, + 0x00404654, + 0x00404660, + 0x48404678, + 0x084046c8, + 0x08404700, + 0x24404718, + 0x04404744, + 0x00404754, + 0x00405800, + 0x08405830, + 0x00405854, + 0x0c405870, + 0x04405a00, + 0x00405a18, + 0x00405b00, + 0x00405b10, + 0x00406020, + 0x0c406028, + 0x044064a8, + 0x044064b4, + 0x2c4064c0, + 0x004064fc, + 0x00407040, + 0x00407804, + 0x1440780c, + 0x004078bc, + 0x18408000, + 0x00408064, + 0x08408800, + 0x00408840, + 0x08408900, + 0x00408980, +/* 0x013c: nve4_hub_mmio_tail */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0200: chan_data */ +/* 0x0200: chan_mmio_count */ + 0x00000000, +/* 0x0204: chan_mmio_address */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0300: xfer_data */ + 0x00000000, +}; + +uint32_t nve0_grhub_code[] = { + 0x03090ef5, +/* 0x0004: queue_put */ + 0x9800d898, + 0x86f001d9, + 0x0489b808, + 0xf00c1bf4, + 0x21f502f7, + 0x00f802ec, +/* 0x001c: queue_put_next */ + 0xb60798c4, + 0x8dbb0384, + 0x0880b600, + 0x80008e80, + 0x90b6018f, + 0x0f94f001, + 0xf801d980, +/* 0x0039: queue_get */ + 0x0131f400, + 0x9800d898, + 0x89b801d9, + 0x210bf404, + 0xb60789c4, + 0x9dbb0394, + 0x0890b600, + 0x98009e98, + 0x80b6019f, + 0x0f84f001, + 0xf400d880, +/* 0x0066: queue_get_done */ + 0x00f80132, +/* 0x0068: nv_rd32 */ + 0x0728b7f1, + 0xb906b4b6, + 0xc9f002ec, + 0x00bcd01f, +/* 0x0078: nv_rd32_wait */ + 0xc800bccf, + 0x1bf41fcc, + 0x06a7f0fa, + 0x010321f5, + 0xf840bfcf, +/* 0x008d: nv_wr32 */ + 0x28b7f100, + 0x06b4b607, + 0xb980bfd0, + 0xc9f002ec, + 0x1ec9f01f, +/* 0x00a3: nv_wr32_wait */ + 0xcf00bcd0, + 0xccc800bc, + 0xfa1bf41f, +/* 0x00ae: watchdog_reset */ + 0x87f100f8, + 0x84b60430, + 0x1ff9f006, + 0xf8008fd0, +/* 0x00bd: watchdog_clear */ + 0x3087f100, + 0x0684b604, + 0xf80080d0, +/* 0x00c9: wait_donez */ + 0x3c87f100, + 0x0684b608, + 0x99f094bd, + 0x0089d000, + 0x081887f1, + 0xd00684b6, +/* 0x00e2: wait_done_wait_donez */ + 0x87f1008a, + 0x84b60400, + 0x0088cf06, + 0xf4888aff, + 0x87f1f31b, + 0x84b6085c, + 0xf094bd06, + 0x89d00099, +/* 0x0103: wait_doneo */ + 0xf100f800, + 0xb6083c87, + 0x94bd0684, + 0xd00099f0, + 0x87f10089, + 0x84b60818, + 0x008ad006, +/* 0x011c: wait_done_wait_doneo */ + 0x040087f1, + 0xcf0684b6, + 0x8aff0088, + 0xf30bf488, + 0x085c87f1, + 0xbd0684b6, + 0x0099f094, + 0xf80089d0, +/* 0x013d: mmctx_size */ +/* 0x013f: nv_mmctx_size_loop */ + 0x9894bd00, + 0x85b600e8, + 0x0180b61a, + 0xbb0284b6, + 0xe0b60098, + 0x04efb804, + 0xb9eb1bf4, + 0x00f8029f, +/* 0x015c: mmctx_xfer */ + 0x083c87f1, + 0xbd0684b6, + 0x0199f094, + 0xf10089d0, + 0xb6071087, + 0x94bd0684, + 0xf405bbfd, + 0x8bd0090b, + 0x0099f000, +/* 0x0180: mmctx_base_disabled */ + 0xf405eefd, + 0x8ed00c0b, + 0xc08fd080, +/* 0x018f: mmctx_multi_disabled */ + 0xb70199f0, + 0xc8010080, + 0xb4b600ab, + 0x0cb9f010, + 0xb601aec8, + 0xbefd11e4, + 0x008bd005, +/* 0x01a8: mmctx_exec_loop */ +/* 0x01a8: mmctx_wait_free */ + 0xf0008ecf, + 0x0bf41fe4, + 0x00ce98fa, + 0xd005e9fd, + 0xc0b6c08e, + 0x04cdb804, + 0xc8e81bf4, + 0x1bf402ab, +/* 0x01c9: mmctx_fini_wait */ + 0x008bcf18, + 0xb01fb4f0, + 0x1bf410b4, + 0x02a7f0f7, + 0xf4c921f4, +/* 0x01de: mmctx_stop */ + 0xabc81b0e, + 0x10b4b600, + 0xf00cb9f0, + 0x8bd012b9, +/* 0x01ed: mmctx_stop_wait */ + 0x008bcf00, + 0xf412bbc8, +/* 0x01f6: mmctx_done */ + 0x87f1fa1b, + 0x84b6085c, + 0xf094bd06, + 0x89d00199, +/* 0x0207: strand_wait */ + 0xf900f800, + 0x02a7f0a0, + 0xfcc921f4, +/* 0x0213: strand_pre */ + 0xf100f8a0, + 0xf04afc87, + 0x97f00283, + 0x0089d00c, + 0x020721f5, +/* 0x0226: strand_post */ + 0x87f100f8, + 0x83f04afc, + 0x0d97f002, + 0xf50089d0, + 0xf8020721, +/* 0x0239: strand_set */ + 0xfca7f100, + 0x02a3f04f, + 0x0500aba2, + 0xd00fc7f0, + 0xc7f000ac, + 0x00bcd00b, + 0x020721f5, + 0xf000aed0, + 0xbcd00ac7, + 0x0721f500, +/* 0x0263: strand_ctx_init */ + 0xf100f802, + 0xb6083c87, + 0x94bd0684, + 0xd00399f0, + 0x21f50089, + 0xe7f00213, + 0x3921f503, + 0xfca7f102, + 0x02a3f046, + 0x0400aba0, + 0xf040a0d0, + 0xbcd001c7, + 0x0721f500, + 0x010c9202, + 0xf000acd0, + 0xbcd002c7, + 0x0721f500, + 0x2621f502, + 0x8087f102, + 0x0684b608, + 0xb70089cf, + 0x95220080, +/* 0x02ba: ctx_init_strand_loop */ + 0x8ed008fe, + 0x408ed000, + 0xb6808acf, + 0xa0b606a5, + 0x00eabb01, + 0xb60480b6, + 0x1bf40192, + 0x08e4b6e8, + 0xf1f2efbc, + 0xb6085c87, + 0x94bd0684, + 0xd00399f0, + 0x00f80089, +/* 0x02ec: error */ + 0xe7f1e0f9, + 0xe4b60814, + 0x00efd006, + 0x0c1ce7f1, + 0xf006e4b6, + 0xefd001f7, + 0xf8e0fc00, +/* 0x0309: init */ + 0xfe04bd00, + 0x07fe0004, + 0x0017f100, + 0x0227f012, + 0xf10012d0, + 0xfe05b917, + 0x17f10010, + 0x10d00400, + 0x0437f1c0, + 0x0634b604, + 0x200327f1, + 0xf10032d0, + 0xd0200427, + 0x27f10132, + 0x32d0200b, + 0x0c27f102, + 0x0732d020, + 0x0c2427f1, + 0xb90624b6, + 0x23d00003, + 0x0427f100, + 0x0023f087, + 0xb70012d0, + 0xf0010012, + 0x12d00427, + 0x1031f400, + 0x9604e7f1, + 0xf440e3f0, + 0xf1c76821, + 0x01018090, + 0x801ff4f0, + 0x17f0000f, + 0x041fbb01, + 0xf10112b6, + 0xb6040c27, + 0x21d00624, + 0x4021d000, + 0x080027f1, + 0xcf0624b6, + 0xf7f00022, +/* 0x03a9: init_find_chipset */ + 0x08f0b654, + 0xb800f398, + 0x0bf40432, + 0x0034b00b, + 0xf8f11bf4, +/* 0x03bd: init_context */ + 0x0017f100, + 0x02fe5801, + 0xf003ff58, + 0x0e8000e3, + 0x150f8014, + 0x013d21f5, + 0x070037f1, + 0x950634b6, + 0x34d00814, + 0x4034d000, + 0x130030b7, + 0xb6001fbb, + 0x3fd002f5, + 0x0815b600, + 0xb60110b6, + 0x1fb90814, + 0x6321f502, + 0x001fbb02, + 0xf1000398, + 0xf0200047, +/* 0x040e: init_gpc */ + 0x4ea05043, + 0x1fb90804, + 0x8d21f402, + 0x08004ea0, + 0xf4022fb9, + 0x4ea08d21, + 0xf4bd010c, + 0xa08d21f4, + 0xf401044e, + 0x4ea08d21, + 0xf7f00100, + 0x8d21f402, + 0x08004ea0, +/* 0x0440: init_gpc_wait */ + 0xc86821f4, + 0x0bf41fff, + 0x044ea0fa, + 0x6821f408, + 0xb7001fbb, + 0xb6800040, + 0x1bf40132, + 0x0027f1b4, + 0x0624b608, + 0xb74021d0, + 0xbd080020, + 0x1f19f014, +/* 0x0473: main */ + 0xf40021d0, + 0x28f40031, + 0x08d7f000, + 0xf43921f4, + 0xe4b1f401, + 0x1bf54001, + 0x87f100d1, + 0x84b6083c, + 0xf094bd06, + 0x89d00499, + 0x0017f100, + 0x0614b60b, + 0xcf4012cf, + 0x13c80011, + 0x7e0bf41f, + 0xf41f23c8, + 0x20f95a0b, + 0xf10212b9, + 0xb6083c87, + 0x94bd0684, + 0xd00799f0, + 0x32f40089, + 0x0231f401, + 0x07fb21f5, + 0x085c87f1, + 0xbd0684b6, + 0x0799f094, + 0xfc0089d0, + 0x3c87f120, + 0x0684b608, + 0x99f094bd, + 0x0089d006, + 0xf50131f4, + 0xf107fb21, + 0xb6085c87, + 0x94bd0684, + 0xd00699f0, + 0x0ef40089, +/* 0x0509: chsw_prev_no_next */ + 0xb920f931, + 0x32f40212, + 0x0232f401, + 0x07fb21f5, + 0x17f120fc, + 0x14b60b00, + 0x0012d006, +/* 0x0527: chsw_no_prev */ + 0xc8130ef4, + 0x0bf41f23, + 0x0131f40d, + 0xf50232f4, +/* 0x0537: chsw_done */ + 0xf107fb21, + 0xb60b0c17, + 0x27f00614, + 0x0012d001, + 0x085c87f1, + 0xbd0684b6, + 0x0499f094, + 0xf50089d0, +/* 0x0557: main_not_ctx_switch */ + 0xb0ff200e, + 0x1bf401e4, + 0x02f2b90d, + 0x078f21f5, +/* 0x0567: main_not_ctx_chan */ + 0xb0420ef4, + 0x1bf402e4, + 0x3c87f12e, + 0x0684b608, + 0x99f094bd, + 0x0089d007, + 0xf40132f4, + 0x21f50232, + 0x87f107fb, + 0x84b6085c, + 0xf094bd06, + 0x89d00799, + 0x110ef400, +/* 0x0598: main_not_ctx_save */ + 0xf010ef94, + 0x21f501f5, + 0x0ef502ec, +/* 0x05a6: main_done */ + 0x17f1fed1, + 0x14b60820, + 0xf024bd06, + 0x12d01f29, + 0xbe0ef500, +/* 0x05b9: ih */ + 0xfe80f9fe, + 0x80f90188, + 0xa0f990f9, + 0xd0f9b0f9, + 0xf0f9e0f9, + 0xc4800acf, + 0x0bf404ab, + 0x00b7f11d, + 0x08d7f019, + 0xcf40becf, + 0x21f400bf, + 0x00b0b704, + 0x01e7f004, +/* 0x05ef: ih_no_fifo */ + 0xe400bed0, + 0xf40100ab, + 0xd7f00d0b, + 0x01e7f108, + 0x0421f440, +/* 0x0600: ih_no_ctxsw */ + 0x0104b7f1, + 0xabffb0bd, + 0x0d0bf4b4, + 0x0c1ca7f1, + 0xd006a4b6, +/* 0x0616: ih_no_other */ + 0x0ad000ab, + 0xfcf0fc40, + 0xfcd0fce0, + 0xfca0fcb0, + 0xfe80fc90, + 0x80fc0088, + 0xf80032f4, +/* 0x0631: ctx_4170s */ + 0x70e7f101, + 0x40e3f041, + 0xf410f5f0, + 0x00f88d21, +/* 0x0640: ctx_4170w */ + 0x4170e7f1, + 0xf440e3f0, + 0xf4f06821, + 0xf31bf410, +/* 0x0652: ctx_redswitch */ + 0xe7f100f8, + 0xe4b60614, + 0x70f7f106, + 0x00efd002, +/* 0x0663: ctx_redswitch_delay */ + 0xb608f7f0, + 0x1bf401f2, + 0x70f7f1fd, + 0x00efd007, +/* 0x0672: ctx_86c */ + 0xe7f100f8, + 0xe4b6086c, + 0x00efd006, + 0x8a14e7f1, + 0xf440e3f0, + 0xe7f18d21, + 0xe3f0a86c, + 0x8d21f441, +/* 0x0692: ctx_load */ + 0x87f100f8, + 0x84b6083c, + 0xf094bd06, + 0x89d00599, + 0x0ca7f000, + 0xf1c921f4, + 0xb60a2417, + 0x10d00614, + 0x0037f100, + 0x0634b60b, + 0xf14032d0, + 0xb60a0c17, + 0x47f00614, + 0x0012d007, +/* 0x06cb: ctx_chan_wait_0 */ + 0xcf4014d0, + 0x44f04014, + 0xfa1bf41f, + 0xfe0032d0, + 0x2af0000b, + 0x0424b61f, + 0xf10220b6, + 0xb6083c87, + 0x94bd0684, + 0xd00899f0, + 0x17f10089, + 0x14b60a04, + 0x0012d006, + 0x0a2017f1, + 0xf00614b6, + 0x23f10227, + 0x12d08000, + 0x1017f000, + 0x030027f1, + 0xfa0223f0, + 0x03f80512, + 0x085c87f1, + 0xbd0684b6, + 0x0899f094, + 0x980089d0, + 0x14b6c101, + 0xc0029818, + 0xfd0825b6, + 0x01800512, + 0x3c87f116, + 0x0684b608, + 0x99f094bd, + 0x0089d009, + 0x0a0427f1, + 0xd00624b6, + 0x27f00021, + 0x2017f101, + 0x0614b60a, + 0xf10012d0, + 0xf0020017, + 0x01fa0613, + 0xf103f805, + 0xb6085c87, + 0x94bd0684, + 0xd00999f0, + 0x87f10089, + 0x84b6085c, + 0xf094bd06, + 0x89d00599, +/* 0x078f: ctx_chan */ + 0xf500f800, + 0xf0069221, + 0x21f40ca7, + 0x1017f1c9, + 0x0614b60a, + 0xd00527f0, +/* 0x07a6: ctx_chan_wait */ + 0x12cf0012, + 0x0522fd00, + 0xf8fa1bf4, +/* 0x07b1: ctx_mmio_exec */ + 0x81039800, + 0x0a0427f1, + 0xd00624b6, + 0x34bd0023, +/* 0x07c0: ctx_mmio_loop */ + 0xf4ff34c4, + 0x57f10f1b, + 0x53f00300, + 0x0535fa06, +/* 0x07d2: ctx_mmio_pull */ + 0x4e9803f8, + 0xc14f98c0, + 0xb68d21f4, + 0x12b60830, + 0xdf1bf401, +/* 0x07e4: ctx_mmio_done */ + 0xd0160398, + 0x00800023, + 0x0017f180, + 0x0613f002, + 0xf80601fa, +/* 0x07fb: ctx_xfer */ + 0xf400f803, + 0x02f40611, +/* 0x0801: ctx_xfer_pre */ + 0x10f7f00d, + 0x067221f5, +/* 0x080b: ctx_xfer_pre_load */ + 0xf01c11f4, + 0x21f502f7, + 0x21f50631, + 0x21f50640, + 0xf4bd0652, + 0x063121f5, + 0x069221f5, +/* 0x0824: ctx_xfer_exec */ + 0xf1160198, + 0xb6041427, + 0x20d00624, + 0x00e7f100, + 0x41e3f0a5, + 0xf4021fb9, + 0xe0b68d21, + 0x01fcf004, + 0xb6022cf0, + 0xf2fd0124, + 0x8d21f405, + 0x4afc17f1, + 0xf00213f0, + 0x12d00c27, + 0x0721f500, + 0xfc27f102, + 0x0223f047, + 0xf00020d0, + 0x20b6012c, + 0x0012d003, + 0xf001acf0, + 0xb7f006a5, + 0x140c9800, + 0xf0150d98, + 0x21f500e7, + 0xa7f0015c, + 0x0321f508, + 0x0721f501, + 0x2201f402, + 0xf40ca7f0, + 0x17f1c921, + 0x14b60a10, + 0x0527f006, +/* 0x08ab: ctx_xfer_post_save_wait */ + 0xcf0012d0, + 0x22fd0012, + 0xfa1bf405, +/* 0x08b7: ctx_xfer_post */ + 0xf02e02f4, + 0x21f502f7, + 0xf4bd0631, + 0x067221f5, + 0x022621f5, + 0x064021f5, + 0x21f5f4bd, + 0x11f40631, + 0x80019810, + 0xf40511fd, + 0x21f5070b, +/* 0x08e2: ctx_xfer_no_post_mmio */ +/* 0x08e2: ctx_xfer_done */ + 0x00f807b1, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc new file mode 100644 index 00000000000..e6b228844a3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc @@ -0,0 +1,400 @@ +/* fuc microcode util functions for nvc0 PGRAPH + * + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)') +define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))') + +ifdef(`include_code', ` +// Error codes +define(`E_BAD_COMMAND', 0x01) +define(`E_CMD_OVERFLOW', 0x02) + +// Util macros to help with debugging ucode hangs etc +define(`T_WAIT', 0) +define(`T_MMCTX', 1) +define(`T_STRWAIT', 2) +define(`T_STRINIT', 3) +define(`T_AUTO', 4) +define(`T_CHAN', 5) +define(`T_LOAD', 6) +define(`T_SAVE', 7) +define(`T_LCHAN', 8) +define(`T_LCTXH', 9) + +define(`trace_set', ` + mov $r8 0x83c + shl b32 $r8 6 + clear b32 $r9 + bset $r9 $1 + iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] +') + +define(`trace_clr', ` + mov $r8 0x85c + shl b32 $r8 6 + clear b32 $r9 + bset $r9 $1 + iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] +') + +// queue_put - add request to queue +// +// In : $r13 queue pointer +// $r14 command +// $r15 data +// +queue_put: + // make sure we have space.. + ld b32 $r8 D[$r13 + 0x0] // GET + ld b32 $r9 D[$r13 + 0x4] // PUT + xor $r8 8 + cmpu b32 $r8 $r9 + bra ne #queue_put_next + mov $r15 E_CMD_OVERFLOW + call #error + ret + + // store cmd/data on queue + queue_put_next: + and $r8 $r9 7 + shl b32 $r8 3 + add b32 $r8 $r13 + add b32 $r8 8 + st b32 D[$r8 + 0x0] $r14 + st b32 D[$r8 + 0x4] $r15 + + // update PUT + add b32 $r9 1 + and $r9 0xf + st b32 D[$r13 + 0x4] $r9 + ret + +// queue_get - fetch request from queue +// +// In : $r13 queue pointer +// +// Out: $p1 clear on success (data available) +// $r14 command +// $r15 data +// +queue_get: + bset $flags $p1 + ld b32 $r8 D[$r13 + 0x0] // GET + ld b32 $r9 D[$r13 + 0x4] // PUT + cmpu b32 $r8 $r9 + bra e #queue_get_done + // fetch first cmd/data pair + and $r9 $r8 7 + shl b32 $r9 3 + add b32 $r9 $r13 + add b32 $r9 8 + ld b32 $r14 D[$r9 + 0x0] + ld b32 $r15 D[$r9 + 0x4] + + // update GET + add b32 $r8 1 + and $r8 0xf + st b32 D[$r13 + 0x0] $r8 + bclr $flags $p1 +queue_get_done: + ret + +// nv_rd32 - read 32-bit value from nv register +// +// In : $r14 register +// Out: $r15 value +// +nv_rd32: + mov $r11 0x728 + shl b32 $r11 6 + mov b32 $r12 $r14 + bset $r12 31 // MMIO_CTRL_PENDING + iowr I[$r11 + 0x000] $r12 // MMIO_CTRL + nv_rd32_wait: + iord $r12 I[$r11 + 0x000] + xbit $r12 $r12 31 + bra ne #nv_rd32_wait + mov $r10 6 // DONE_MMIO_RD + call #wait_doneo + iord $r15 I[$r11 + 0x100] // MMIO_RDVAL + ret + +// nv_wr32 - write 32-bit value to nv register +// +// In : $r14 register +// $r15 value +// +nv_wr32: + mov $r11 0x728 + shl b32 $r11 6 + iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL + mov b32 $r12 $r14 + bset $r12 31 // MMIO_CTRL_PENDING + bset $r12 30 // MMIO_CTRL_WRITE + iowr I[$r11 + 0x000] $r12 // MMIO_CTRL + nv_wr32_wait: + iord $r12 I[$r11 + 0x000] + xbit $r12 $r12 31 + bra ne #nv_wr32_wait + ret + +// (re)set watchdog timer +// +// In : $r15 timeout +// +watchdog_reset: + mov $r8 0x430 + shl b32 $r8 6 + bset $r15 31 + iowr I[$r8 + 0x000] $r15 + ret + +// clear watchdog timer +watchdog_clear: + mov $r8 0x430 + shl b32 $r8 6 + iowr I[$r8 + 0x000] $r0 + ret + +// wait_done{z,o} - wait on FUC_DONE bit to become clear/set +// +// In : $r10 bit to wait on +// +define(`wait_done', ` +$1: + trace_set(T_WAIT); + mov $r8 0x818 + shl b32 $r8 6 + iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit + wait_done_$1: + mov $r8 0x400 + shl b32 $r8 6 + iord $r8 I[$r8 + 0x000] // DONE + xbit $r8 $r8 $r10 + bra $2 #wait_done_$1 + trace_clr(T_WAIT) + ret +') +wait_done(wait_donez, ne) +wait_done(wait_doneo, e) + +// mmctx_size - determine size of a mmio list transfer +// +// In : $r14 mmio list head +// $r15 mmio list tail +// Out: $r15 transfer size (in bytes) +// +mmctx_size: + clear b32 $r9 + nv_mmctx_size_loop: + ld b32 $r8 D[$r14] + shr b32 $r8 26 + add b32 $r8 1 + shl b32 $r8 2 + add b32 $r9 $r8 + add b32 $r14 4 + cmpu b32 $r14 $r15 + bra ne #nv_mmctx_size_loop + mov b32 $r15 $r9 + ret + +// mmctx_xfer - execute a list of mmio transfers +// +// In : $r10 flags +// bit 0: direction (0 = save, 1 = load) +// bit 1: set if first transfer +// bit 2: set if last transfer +// $r11 base +// $r12 mmio list head +// $r13 mmio list tail +// $r14 multi_stride +// $r15 multi_mask +// +mmctx_xfer: + trace_set(T_MMCTX) + mov $r8 0x710 + shl b32 $r8 6 + clear b32 $r9 + or $r11 $r11 + bra e #mmctx_base_disabled + iowr I[$r8 + 0x000] $r11 // MMCTX_BASE + bset $r9 0 // BASE_EN + mmctx_base_disabled: + or $r14 $r14 + bra e #mmctx_multi_disabled + iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE + iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK + bset $r9 1 // MULTI_EN + mmctx_multi_disabled: + add b32 $r8 0x100 + + xbit $r11 $r10 0 + shl b32 $r11 16 // DIR + bset $r11 12 // QLIMIT = 0x10 + xbit $r14 $r10 1 + shl b32 $r14 17 + or $r11 $r14 // START_TRIGGER + iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL + + // loop over the mmio list, and send requests to the hw + mmctx_exec_loop: + // wait for space in mmctx queue + mmctx_wait_free: + iord $r14 I[$r8 + 0x000] // MMCTX_CTRL + and $r14 0x1f + bra e #mmctx_wait_free + + // queue up an entry + ld b32 $r14 D[$r12] + or $r14 $r9 + iowr I[$r8 + 0x300] $r14 + add b32 $r12 4 + cmpu b32 $r12 $r13 + bra ne #mmctx_exec_loop + + xbit $r11 $r10 2 + bra ne #mmctx_stop + // wait for queue to empty + mmctx_fini_wait: + iord $r11 I[$r8 + 0x000] // MMCTX_CTRL + and $r11 0x1f + cmpu b32 $r11 0x10 + bra ne #mmctx_fini_wait + mov $r10 2 // DONE_MMCTX + call #wait_donez + bra #mmctx_done + mmctx_stop: + xbit $r11 $r10 0 + shl b32 $r11 16 // DIR + bset $r11 12 // QLIMIT = 0x10 + bset $r11 18 // STOP_TRIGGER + iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL + mmctx_stop_wait: + // wait for STOP_TRIGGER to clear + iord $r11 I[$r8 + 0x000] // MMCTX_CTRL + xbit $r11 $r11 18 + bra ne #mmctx_stop_wait + mmctx_done: + trace_clr(T_MMCTX) + ret + +// Wait for DONE_STRAND +// +strand_wait: + push $r10 + mov $r10 2 + call #wait_donez + pop $r10 + ret + +// unknown - call before issuing strand commands +// +strand_pre: + mov $r8 0x4afc + sethi $r8 0x20000 + mov $r9 0xc + iowr I[$r8] $r9 + call #strand_wait + ret + +// unknown - call after issuing strand commands +// +strand_post: + mov $r8 0x4afc + sethi $r8 0x20000 + mov $r9 0xd + iowr I[$r8] $r9 + call #strand_wait + ret + +// Selects strand set?! +// +// In: $r14 id +// +strand_set: + mov $r10 0x4ffc + sethi $r10 0x20000 + sub b32 $r11 $r10 0x500 + mov $r12 0xf + iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf + mov $r12 0xb + iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb + call #strand_wait + iowr I[$r10 + 0x000] $r14 // 0x93c = <id> + mov $r12 0xa + iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa + call #strand_wait + ret + +// Initialise strand context data +// +// In : $r15 context base +// Out: $r15 context size (in bytes) +// +// Strandset(?) 3 hardcoded currently +// +strand_ctx_init: + trace_set(T_STRINIT) + call #strand_pre + mov $r14 3 + call #strand_set + mov $r10 0x46fc + sethi $r10 0x20000 + add b32 $r11 $r10 0x400 + iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0 + mov $r12 1 + iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE + call #strand_wait + sub b32 $r12 $r0 1 + iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff + mov $r12 2 + iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT + call #strand_wait + call #strand_post + + // read the size of each strand, poke the context offset of + // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry + // about it later then. + mov $r8 0x880 + shl b32 $r8 6 + iord $r9 I[$r8 + 0x000] // STRANDS + add b32 $r8 0x2200 + shr b32 $r14 $r15 8 + ctx_init_strand_loop: + iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE + iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE + iord $r10 I[$r8 + 0x200] // STRAND_SIZE + shr b32 $r10 6 + add b32 $r10 1 + add b32 $r14 $r10 + add b32 $r8 4 + sub b32 $r9 1 + bra ne #ctx_init_strand_loop + + shl b32 $r14 8 + sub b32 $r15 $r14 $r15 + trace_clr(T_STRINIT) + ret +') diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc new file mode 100644 index 00000000000..f16a5d53319 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc @@ -0,0 +1,400 @@ +/* fuc microcode util functions for nve0 PGRAPH + * + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)') +define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))') + +ifdef(`include_code', ` +// Error codes +define(`E_BAD_COMMAND', 0x01) +define(`E_CMD_OVERFLOW', 0x02) + +// Util macros to help with debugging ucode hangs etc +define(`T_WAIT', 0) +define(`T_MMCTX', 1) +define(`T_STRWAIT', 2) +define(`T_STRINIT', 3) +define(`T_AUTO', 4) +define(`T_CHAN', 5) +define(`T_LOAD', 6) +define(`T_SAVE', 7) +define(`T_LCHAN', 8) +define(`T_LCTXH', 9) + +define(`trace_set', ` + mov $r8 0x83c + shl b32 $r8 6 + clear b32 $r9 + bset $r9 $1 + iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] +') + +define(`trace_clr', ` + mov $r8 0x85c + shl b32 $r8 6 + clear b32 $r9 + bset $r9 $1 + iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] +') + +// queue_put - add request to queue +// +// In : $r13 queue pointer +// $r14 command +// $r15 data +// +queue_put: + // make sure we have space.. + ld b32 $r8 D[$r13 + 0x0] // GET + ld b32 $r9 D[$r13 + 0x4] // PUT + xor $r8 8 + cmpu b32 $r8 $r9 + bra ne #queue_put_next + mov $r15 E_CMD_OVERFLOW + call #error + ret + + // store cmd/data on queue + queue_put_next: + and $r8 $r9 7 + shl b32 $r8 3 + add b32 $r8 $r13 + add b32 $r8 8 + st b32 D[$r8 + 0x0] $r14 + st b32 D[$r8 + 0x4] $r15 + + // update PUT + add b32 $r9 1 + and $r9 0xf + st b32 D[$r13 + 0x4] $r9 + ret + +// queue_get - fetch request from queue +// +// In : $r13 queue pointer +// +// Out: $p1 clear on success (data available) +// $r14 command +// $r15 data +// +queue_get: + bset $flags $p1 + ld b32 $r8 D[$r13 + 0x0] // GET + ld b32 $r9 D[$r13 + 0x4] // PUT + cmpu b32 $r8 $r9 + bra e #queue_get_done + // fetch first cmd/data pair + and $r9 $r8 7 + shl b32 $r9 3 + add b32 $r9 $r13 + add b32 $r9 8 + ld b32 $r14 D[$r9 + 0x0] + ld b32 $r15 D[$r9 + 0x4] + + // update GET + add b32 $r8 1 + and $r8 0xf + st b32 D[$r13 + 0x0] $r8 + bclr $flags $p1 +queue_get_done: + ret + +// nv_rd32 - read 32-bit value from nv register +// +// In : $r14 register +// Out: $r15 value +// +nv_rd32: + mov $r11 0x728 + shl b32 $r11 6 + mov b32 $r12 $r14 + bset $r12 31 // MMIO_CTRL_PENDING + iowr I[$r11 + 0x000] $r12 // MMIO_CTRL + nv_rd32_wait: + iord $r12 I[$r11 + 0x000] + xbit $r12 $r12 31 + bra ne #nv_rd32_wait + mov $r10 6 // DONE_MMIO_RD + call #wait_doneo + iord $r15 I[$r11 + 0x100] // MMIO_RDVAL + ret + +// nv_wr32 - write 32-bit value to nv register +// +// In : $r14 register +// $r15 value +// +nv_wr32: + mov $r11 0x728 + shl b32 $r11 6 + iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL + mov b32 $r12 $r14 + bset $r12 31 // MMIO_CTRL_PENDING + bset $r12 30 // MMIO_CTRL_WRITE + iowr I[$r11 + 0x000] $r12 // MMIO_CTRL + nv_wr32_wait: + iord $r12 I[$r11 + 0x000] + xbit $r12 $r12 31 + bra ne #nv_wr32_wait + ret + +// (re)set watchdog timer +// +// In : $r15 timeout +// +watchdog_reset: + mov $r8 0x430 + shl b32 $r8 6 + bset $r15 31 + iowr I[$r8 + 0x000] $r15 + ret + +// clear watchdog timer +watchdog_clear: + mov $r8 0x430 + shl b32 $r8 6 + iowr I[$r8 + 0x000] $r0 + ret + +// wait_done{z,o} - wait on FUC_DONE bit to become clear/set +// +// In : $r10 bit to wait on +// +define(`wait_done', ` +$1: + trace_set(T_WAIT); + mov $r8 0x818 + shl b32 $r8 6 + iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit + wait_done_$1: + mov $r8 0x400 + shl b32 $r8 6 + iord $r8 I[$r8 + 0x000] // DONE + xbit $r8 $r8 $r10 + bra $2 #wait_done_$1 + trace_clr(T_WAIT) + ret +') +wait_done(wait_donez, ne) +wait_done(wait_doneo, e) + +// mmctx_size - determine size of a mmio list transfer +// +// In : $r14 mmio list head +// $r15 mmio list tail +// Out: $r15 transfer size (in bytes) +// +mmctx_size: + clear b32 $r9 + nv_mmctx_size_loop: + ld b32 $r8 D[$r14] + shr b32 $r8 26 + add b32 $r8 1 + shl b32 $r8 2 + add b32 $r9 $r8 + add b32 $r14 4 + cmpu b32 $r14 $r15 + bra ne #nv_mmctx_size_loop + mov b32 $r15 $r9 + ret + +// mmctx_xfer - execute a list of mmio transfers +// +// In : $r10 flags +// bit 0: direction (0 = save, 1 = load) +// bit 1: set if first transfer +// bit 2: set if last transfer +// $r11 base +// $r12 mmio list head +// $r13 mmio list tail +// $r14 multi_stride +// $r15 multi_mask +// +mmctx_xfer: + trace_set(T_MMCTX) + mov $r8 0x710 + shl b32 $r8 6 + clear b32 $r9 + or $r11 $r11 + bra e #mmctx_base_disabled + iowr I[$r8 + 0x000] $r11 // MMCTX_BASE + bset $r9 0 // BASE_EN + mmctx_base_disabled: + or $r14 $r14 + bra e #mmctx_multi_disabled + iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE + iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK + bset $r9 1 // MULTI_EN + mmctx_multi_disabled: + add b32 $r8 0x100 + + xbit $r11 $r10 0 + shl b32 $r11 16 // DIR + bset $r11 12 // QLIMIT = 0x10 + xbit $r14 $r10 1 + shl b32 $r14 17 + or $r11 $r14 // START_TRIGGER + iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL + + // loop over the mmio list, and send requests to the hw + mmctx_exec_loop: + // wait for space in mmctx queue + mmctx_wait_free: + iord $r14 I[$r8 + 0x000] // MMCTX_CTRL + and $r14 0x1f + bra e #mmctx_wait_free + + // queue up an entry + ld b32 $r14 D[$r12] + or $r14 $r9 + iowr I[$r8 + 0x300] $r14 + add b32 $r12 4 + cmpu b32 $r12 $r13 + bra ne #mmctx_exec_loop + + xbit $r11 $r10 2 + bra ne #mmctx_stop + // wait for queue to empty + mmctx_fini_wait: + iord $r11 I[$r8 + 0x000] // MMCTX_CTRL + and $r11 0x1f + cmpu b32 $r11 0x10 + bra ne #mmctx_fini_wait + mov $r10 2 // DONE_MMCTX + call #wait_donez + bra #mmctx_done + mmctx_stop: + xbit $r11 $r10 0 + shl b32 $r11 16 // DIR + bset $r11 12 // QLIMIT = 0x10 + bset $r11 18 // STOP_TRIGGER + iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL + mmctx_stop_wait: + // wait for STOP_TRIGGER to clear + iord $r11 I[$r8 + 0x000] // MMCTX_CTRL + xbit $r11 $r11 18 + bra ne #mmctx_stop_wait + mmctx_done: + trace_clr(T_MMCTX) + ret + +// Wait for DONE_STRAND +// +strand_wait: + push $r10 + mov $r10 2 + call #wait_donez + pop $r10 + ret + +// unknown - call before issuing strand commands +// +strand_pre: + mov $r8 0x4afc + sethi $r8 0x20000 + mov $r9 0xc + iowr I[$r8] $r9 + call #strand_wait + ret + +// unknown - call after issuing strand commands +// +strand_post: + mov $r8 0x4afc + sethi $r8 0x20000 + mov $r9 0xd + iowr I[$r8] $r9 + call #strand_wait + ret + +// Selects strand set?! +// +// In: $r14 id +// +strand_set: + mov $r10 0x4ffc + sethi $r10 0x20000 + sub b32 $r11 $r10 0x500 + mov $r12 0xf + iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf + mov $r12 0xb + iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb + call #strand_wait + iowr I[$r10 + 0x000] $r14 // 0x93c = <id> + mov $r12 0xa + iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa + call #strand_wait + ret + +// Initialise strand context data +// +// In : $r15 context base +// Out: $r15 context size (in bytes) +// +// Strandset(?) 3 hardcoded currently +// +strand_ctx_init: + trace_set(T_STRINIT) + call #strand_pre + mov $r14 3 + call #strand_set + mov $r10 0x46fc + sethi $r10 0x20000 + add b32 $r11 $r10 0x400 + iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0 + mov $r12 1 + iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE + call #strand_wait + sub b32 $r12 $r0 1 + iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff + mov $r12 2 + iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT + call #strand_wait + call #strand_post + + // read the size of each strand, poke the context offset of + // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry + // about it later then. + mov $r8 0x880 + shl b32 $r8 6 + iord $r9 I[$r8 + 0x000] // STRANDS + add b32 $r8 0x2200 + shr b32 $r14 $r15 8 + ctx_init_strand_loop: + iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE + iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE + iord $r10 I[$r8 + 0x200] // STRAND_SIZE + shr b32 $r10 6 + add b32 $r10 1 + add b32 $r14 $r10 + add b32 $r8 4 + sub b32 $r9 1 + bra ne #ctx_init_strand_loop + + shl b32 $r14 8 + sub b32 $r15 $r14 $r15 + trace_clr(T_STRINIT) + ret +') diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c new file mode 100644 index 00000000000..61852824845 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c @@ -0,0 +1,1387 @@ +/* + * Copyright 2007 Stephane Marchesin + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <core/os.h> +#include <core/class.h> +#include <core/handle.h> +#include <core/namedb.h> + +#include <subdev/fb.h> +#include <subdev/instmem.h> +#include <subdev/timer.h> + +#include <engine/fifo.h> +#include <engine/graph.h> + +#include "regs.h" + +static u32 +nv04_graph_ctx_regs[] = { + 0x0040053c, + 0x00400544, + 0x00400540, + 0x00400548, + NV04_PGRAPH_CTX_SWITCH1, + NV04_PGRAPH_CTX_SWITCH2, + NV04_PGRAPH_CTX_SWITCH3, + NV04_PGRAPH_CTX_SWITCH4, + NV04_PGRAPH_CTX_CACHE1, + NV04_PGRAPH_CTX_CACHE2, + NV04_PGRAPH_CTX_CACHE3, + NV04_PGRAPH_CTX_CACHE4, + 0x00400184, + 0x004001a4, + 0x004001c4, + 0x004001e4, + 0x00400188, + 0x004001a8, + 0x004001c8, + 0x004001e8, + 0x0040018c, + 0x004001ac, + 0x004001cc, + 0x004001ec, + 0x00400190, + 0x004001b0, + 0x004001d0, + 0x004001f0, + 0x00400194, + 0x004001b4, + 0x004001d4, + 0x004001f4, + 0x00400198, + 0x004001b8, + 0x004001d8, + 0x004001f8, + 0x0040019c, + 0x004001bc, + 0x004001dc, + 0x004001fc, + 0x00400174, + NV04_PGRAPH_DMA_START_0, + NV04_PGRAPH_DMA_START_1, + NV04_PGRAPH_DMA_LENGTH, + NV04_PGRAPH_DMA_MISC, + NV04_PGRAPH_DMA_PITCH, + NV04_PGRAPH_BOFFSET0, + NV04_PGRAPH_BBASE0, + NV04_PGRAPH_BLIMIT0, + NV04_PGRAPH_BOFFSET1, + NV04_PGRAPH_BBASE1, + NV04_PGRAPH_BLIMIT1, + NV04_PGRAPH_BOFFSET2, + NV04_PGRAPH_BBASE2, + NV04_PGRAPH_BLIMIT2, + NV04_PGRAPH_BOFFSET3, + NV04_PGRAPH_BBASE3, + NV04_PGRAPH_BLIMIT3, + NV04_PGRAPH_BOFFSET4, + NV04_PGRAPH_BBASE4, + NV04_PGRAPH_BLIMIT4, + NV04_PGRAPH_BOFFSET5, + NV04_PGRAPH_BBASE5, + NV04_PGRAPH_BLIMIT5, + NV04_PGRAPH_BPITCH0, + NV04_PGRAPH_BPITCH1, + NV04_PGRAPH_BPITCH2, + NV04_PGRAPH_BPITCH3, + NV04_PGRAPH_BPITCH4, + NV04_PGRAPH_SURFACE, + NV04_PGRAPH_STATE, + NV04_PGRAPH_BSWIZZLE2, + NV04_PGRAPH_BSWIZZLE5, + NV04_PGRAPH_BPIXEL, + NV04_PGRAPH_NOTIFY, + NV04_PGRAPH_PATT_COLOR0, + NV04_PGRAPH_PATT_COLOR1, + NV04_PGRAPH_PATT_COLORRAM+0x00, + NV04_PGRAPH_PATT_COLORRAM+0x04, + NV04_PGRAPH_PATT_COLORRAM+0x08, + NV04_PGRAPH_PATT_COLORRAM+0x0c, + NV04_PGRAPH_PATT_COLORRAM+0x10, + NV04_PGRAPH_PATT_COLORRAM+0x14, + NV04_PGRAPH_PATT_COLORRAM+0x18, + NV04_PGRAPH_PATT_COLORRAM+0x1c, + NV04_PGRAPH_PATT_COLORRAM+0x20, + NV04_PGRAPH_PATT_COLORRAM+0x24, + NV04_PGRAPH_PATT_COLORRAM+0x28, + NV04_PGRAPH_PATT_COLORRAM+0x2c, + NV04_PGRAPH_PATT_COLORRAM+0x30, + NV04_PGRAPH_PATT_COLORRAM+0x34, + NV04_PGRAPH_PATT_COLORRAM+0x38, + NV04_PGRAPH_PATT_COLORRAM+0x3c, + NV04_PGRAPH_PATT_COLORRAM+0x40, + NV04_PGRAPH_PATT_COLORRAM+0x44, + NV04_PGRAPH_PATT_COLORRAM+0x48, + NV04_PGRAPH_PATT_COLORRAM+0x4c, + NV04_PGRAPH_PATT_COLORRAM+0x50, + NV04_PGRAPH_PATT_COLORRAM+0x54, + NV04_PGRAPH_PATT_COLORRAM+0x58, + NV04_PGRAPH_PATT_COLORRAM+0x5c, + NV04_PGRAPH_PATT_COLORRAM+0x60, + NV04_PGRAPH_PATT_COLORRAM+0x64, + NV04_PGRAPH_PATT_COLORRAM+0x68, + NV04_PGRAPH_PATT_COLORRAM+0x6c, + NV04_PGRAPH_PATT_COLORRAM+0x70, + NV04_PGRAPH_PATT_COLORRAM+0x74, + NV04_PGRAPH_PATT_COLORRAM+0x78, + NV04_PGRAPH_PATT_COLORRAM+0x7c, + NV04_PGRAPH_PATT_COLORRAM+0x80, + NV04_PGRAPH_PATT_COLORRAM+0x84, + NV04_PGRAPH_PATT_COLORRAM+0x88, + NV04_PGRAPH_PATT_COLORRAM+0x8c, + NV04_PGRAPH_PATT_COLORRAM+0x90, + NV04_PGRAPH_PATT_COLORRAM+0x94, + NV04_PGRAPH_PATT_COLORRAM+0x98, + NV04_PGRAPH_PATT_COLORRAM+0x9c, + NV04_PGRAPH_PATT_COLORRAM+0xa0, + NV04_PGRAPH_PATT_COLORRAM+0xa4, + NV04_PGRAPH_PATT_COLORRAM+0xa8, + NV04_PGRAPH_PATT_COLORRAM+0xac, + NV04_PGRAPH_PATT_COLORRAM+0xb0, + NV04_PGRAPH_PATT_COLORRAM+0xb4, + NV04_PGRAPH_PATT_COLORRAM+0xb8, + NV04_PGRAPH_PATT_COLORRAM+0xbc, + NV04_PGRAPH_PATT_COLORRAM+0xc0, + NV04_PGRAPH_PATT_COLORRAM+0xc4, + NV04_PGRAPH_PATT_COLORRAM+0xc8, + NV04_PGRAPH_PATT_COLORRAM+0xcc, + NV04_PGRAPH_PATT_COLORRAM+0xd0, + NV04_PGRAPH_PATT_COLORRAM+0xd4, + NV04_PGRAPH_PATT_COLORRAM+0xd8, + NV04_PGRAPH_PATT_COLORRAM+0xdc, + NV04_PGRAPH_PATT_COLORRAM+0xe0, + NV04_PGRAPH_PATT_COLORRAM+0xe4, + NV04_PGRAPH_PATT_COLORRAM+0xe8, + NV04_PGRAPH_PATT_COLORRAM+0xec, + NV04_PGRAPH_PATT_COLORRAM+0xf0, + NV04_PGRAPH_PATT_COLORRAM+0xf4, + NV04_PGRAPH_PATT_COLORRAM+0xf8, + NV04_PGRAPH_PATT_COLORRAM+0xfc, + NV04_PGRAPH_PATTERN, + 0x0040080c, + NV04_PGRAPH_PATTERN_SHAPE, + 0x00400600, + NV04_PGRAPH_ROP3, + NV04_PGRAPH_CHROMA, + NV04_PGRAPH_BETA_AND, + NV04_PGRAPH_BETA_PREMULT, + NV04_PGRAPH_CONTROL0, + NV04_PGRAPH_CONTROL1, + NV04_PGRAPH_CONTROL2, + NV04_PGRAPH_BLEND, + NV04_PGRAPH_STORED_FMT, + NV04_PGRAPH_SOURCE_COLOR, + 0x00400560, + 0x00400568, + 0x00400564, + 0x0040056c, + 0x00400400, + 0x00400480, + 0x00400404, + 0x00400484, + 0x00400408, + 0x00400488, + 0x0040040c, + 0x0040048c, + 0x00400410, + 0x00400490, + 0x00400414, + 0x00400494, + 0x00400418, + 0x00400498, + 0x0040041c, + 0x0040049c, + 0x00400420, + 0x004004a0, + 0x00400424, + 0x004004a4, + 0x00400428, + 0x004004a8, + 0x0040042c, + 0x004004ac, + 0x00400430, + 0x004004b0, + 0x00400434, + 0x004004b4, + 0x00400438, + 0x004004b8, + 0x0040043c, + 0x004004bc, + 0x00400440, + 0x004004c0, + 0x00400444, + 0x004004c4, + 0x00400448, + 0x004004c8, + 0x0040044c, + 0x004004cc, + 0x00400450, + 0x004004d0, + 0x00400454, + 0x004004d4, + 0x00400458, + 0x004004d8, + 0x0040045c, + 0x004004dc, + 0x00400460, + 0x004004e0, + 0x00400464, + 0x004004e4, + 0x00400468, + 0x004004e8, + 0x0040046c, + 0x004004ec, + 0x00400470, + 0x004004f0, + 0x00400474, + 0x004004f4, + 0x00400478, + 0x004004f8, + 0x0040047c, + 0x004004fc, + 0x00400534, + 0x00400538, + 0x00400514, + 0x00400518, + 0x0040051c, + 0x00400520, + 0x00400524, + 0x00400528, + 0x0040052c, + 0x00400530, + 0x00400d00, + 0x00400d40, + 0x00400d80, + 0x00400d04, + 0x00400d44, + 0x00400d84, + 0x00400d08, + 0x00400d48, + 0x00400d88, + 0x00400d0c, + 0x00400d4c, + 0x00400d8c, + 0x00400d10, + 0x00400d50, + 0x00400d90, + 0x00400d14, + 0x00400d54, + 0x00400d94, + 0x00400d18, + 0x00400d58, + 0x00400d98, + 0x00400d1c, + 0x00400d5c, + 0x00400d9c, + 0x00400d20, + 0x00400d60, + 0x00400da0, + 0x00400d24, + 0x00400d64, + 0x00400da4, + 0x00400d28, + 0x00400d68, + 0x00400da8, + 0x00400d2c, + 0x00400d6c, + 0x00400dac, + 0x00400d30, + 0x00400d70, + 0x00400db0, + 0x00400d34, + 0x00400d74, + 0x00400db4, + 0x00400d38, + 0x00400d78, + 0x00400db8, + 0x00400d3c, + 0x00400d7c, + 0x00400dbc, + 0x00400590, + 0x00400594, + 0x00400598, + 0x0040059c, + 0x004005a8, + 0x004005ac, + 0x004005b0, + 0x004005b4, + 0x004005c0, + 0x004005c4, + 0x004005c8, + 0x004005cc, + 0x004005d0, + 0x004005d4, + 0x004005d8, + 0x004005dc, + 0x004005e0, + NV04_PGRAPH_PASSTHRU_0, + NV04_PGRAPH_PASSTHRU_1, + NV04_PGRAPH_PASSTHRU_2, + NV04_PGRAPH_DVD_COLORFMT, + NV04_PGRAPH_SCALED_FORMAT, + NV04_PGRAPH_MISC24_0, + NV04_PGRAPH_MISC24_1, + NV04_PGRAPH_MISC24_2, + 0x00400500, + 0x00400504, + NV04_PGRAPH_VALID1, + NV04_PGRAPH_VALID2, + NV04_PGRAPH_DEBUG_3 +}; + +struct nv04_graph_priv { + struct nouveau_graph base; + struct nv04_graph_chan *chan[16]; + spinlock_t lock; +}; + +struct nv04_graph_chan { + struct nouveau_object base; + int chid; + u32 nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; +}; + + +static inline struct nv04_graph_priv * +nv04_graph_priv(struct nv04_graph_chan *chan) +{ + return (void *)nv_object(chan)->engine; +} + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +/* + * Software methods, why they are needed, and how they all work: + * + * NV04 and NV05 keep most of the state in PGRAPH context itself, but some + * 2d engine settings are kept inside the grobjs themselves. The grobjs are + * 3 words long on both. grobj format on NV04 is: + * + * word 0: + * - bits 0-7: class + * - bit 12: color key active + * - bit 13: clip rect active + * - bit 14: if set, destination surface is swizzled and taken from buffer 5 + * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken + * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or + * NV03_CONTEXT_SURFACE_DST]. + * - bits 15-17: 2d operation [aka patch config] + * - bit 24: patch valid [enables rendering using this object] + * - bit 25: surf3d valid [for tex_tri and multitex_tri only] + * word 1: + * - bits 0-1: mono format + * - bits 8-13: color format + * - bits 16-31: DMA_NOTIFY instance + * word 2: + * - bits 0-15: DMA_A instance + * - bits 16-31: DMA_B instance + * + * On NV05 it's: + * + * word 0: + * - bits 0-7: class + * - bit 12: color key active + * - bit 13: clip rect active + * - bit 14: if set, destination surface is swizzled and taken from buffer 5 + * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken + * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or + * NV03_CONTEXT_SURFACE_DST]. + * - bits 15-17: 2d operation [aka patch config] + * - bits 20-22: dither mode + * - bit 24: patch valid [enables rendering using this object] + * - bit 25: surface_dst/surface_color/surf2d/surf3d valid + * - bit 26: surface_src/surface_zeta valid + * - bit 27: pattern valid + * - bit 28: rop valid + * - bit 29: beta1 valid + * - bit 30: beta4 valid + * word 1: + * - bits 0-1: mono format + * - bits 8-13: color format + * - bits 16-31: DMA_NOTIFY instance + * word 2: + * - bits 0-15: DMA_A instance + * - bits 16-31: DMA_B instance + * + * NV05 will set/unset the relevant valid bits when you poke the relevant + * object-binding methods with object of the proper type, or with the NULL + * type. It'll only allow rendering using the grobj if all needed objects + * are bound. The needed set of objects depends on selected operation: for + * example rop object is needed by ROP_AND, but not by SRCCOPY_AND. + * + * NV04 doesn't have these methods implemented at all, and doesn't have the + * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24 + * is set. So we have to emulate them in software, internally keeping the + * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04, + * but the last word isn't actually used for anything, we abuse it for this + * purpose. + * + * Actually, NV05 can optionally check bit 24 too, but we disable this since + * there's no use for it. + * + * For unknown reasons, NV04 implements surf3d binding in hardware as an + * exception. Also for unknown reasons, NV04 doesn't implement the clipping + * methods on the surf3d object, so we have to emulate them too. + */ + +static void +nv04_graph_set_ctx1(struct nouveau_object *object, u32 mask, u32 value) +{ + struct nv04_graph_priv *priv = (void *)object->engine; + int subc = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; + u32 tmp; + + tmp = nv_ro32(object, 0x00); + tmp &= ~mask; + tmp |= value; + nv_wo32(object, 0x00, tmp); + + nv_wr32(priv, NV04_PGRAPH_CTX_SWITCH1, tmp); + nv_wr32(priv, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp); +} + +static void +nv04_graph_set_ctx_val(struct nouveau_object *object, u32 mask, u32 value) +{ + int class, op, valid = 1; + u32 tmp, ctx1; + + ctx1 = nv_ro32(object, 0x00); + class = ctx1 & 0xff; + op = (ctx1 >> 15) & 7; + + tmp = nv_ro32(object, 0x0c); + tmp &= ~mask; + tmp |= value; + nv_wo32(object, 0x0c, tmp); + + /* check for valid surf2d/surf_dst/surf_color */ + if (!(tmp & 0x02000000)) + valid = 0; + /* check for valid surf_src/surf_zeta */ + if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000)) + valid = 0; + + switch (op) { + /* SRCCOPY_AND, SRCCOPY: no extra objects required */ + case 0: + case 3: + break; + /* ROP_AND: requires pattern and rop */ + case 1: + if (!(tmp & 0x18000000)) + valid = 0; + break; + /* BLEND_AND: requires beta1 */ + case 2: + if (!(tmp & 0x20000000)) + valid = 0; + break; + /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */ + case 4: + case 5: + if (!(tmp & 0x40000000)) + valid = 0; + break; + } + + nv04_graph_set_ctx1(object, 0x01000000, valid << 24); +} + +static int +nv04_graph_mthd_set_operation(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + u32 class = nv_ro32(object, 0) & 0xff; + u32 data = *(u32 *)args; + if (data > 5) + return 1; + /* Old versions of the objects only accept first three operations. */ + if (data > 2 && class < 0x40) + return 1; + nv04_graph_set_ctx1(object, 0x00038000, data << 15); + /* changing operation changes set of objects needed for validation */ + nv04_graph_set_ctx_val(object, 0, 0); + return 0; +} + +static int +nv04_graph_mthd_surf3d_clip_h(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + struct nv04_graph_priv *priv = (void *)object->engine; + u32 data = *(u32 *)args; + u32 min = data & 0xffff, max; + u32 w = data >> 16; + if (min & 0x8000) + /* too large */ + return 1; + if (w & 0x8000) + /* yes, it accepts negative for some reason. */ + w |= 0xffff0000; + max = min + w; + max &= 0x3ffff; + nv_wr32(priv, 0x40053c, min); + nv_wr32(priv, 0x400544, max); + return 0; +} + +static int +nv04_graph_mthd_surf3d_clip_v(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + struct nv04_graph_priv *priv = (void *)object->engine; + u32 data = *(u32 *)args; + u32 min = data & 0xffff, max; + u32 w = data >> 16; + if (min & 0x8000) + /* too large */ + return 1; + if (w & 0x8000) + /* yes, it accepts negative for some reason. */ + w |= 0xffff0000; + max = min + w; + max &= 0x3ffff; + nv_wr32(priv, 0x400540, min); + nv_wr32(priv, 0x400548, max); + return 0; +} + +static u16 +nv04_graph_mthd_bind_class(struct nouveau_object *object, u32 *args, u32 size) +{ + struct nouveau_instmem *imem = nouveau_instmem(object); + u32 inst = *(u32 *)args << 4; + return nv_ro32(imem, inst); +} + +static int +nv04_graph_mthd_bind_surf2d(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx1(object, 0x00004000, 0); + nv04_graph_set_ctx_val(object, 0x02000000, 0); + return 0; + case 0x42: + nv04_graph_set_ctx1(object, 0x00004000, 0); + nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx1(object, 0x00004000, 0); + nv04_graph_set_ctx_val(object, 0x02000000, 0); + return 0; + case 0x42: + nv04_graph_set_ctx1(object, 0x00004000, 0); + nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000); + return 0; + case 0x52: + nv04_graph_set_ctx1(object, 0x00004000, 0x00004000); + nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000); + return 0; + } + return 1; +} + +static int +nv01_graph_mthd_bind_patt(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x08000000, 0); + return 0; + case 0x18: + nv04_graph_set_ctx_val(object, 0x08000000, 0x08000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_patt(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x08000000, 0); + return 0; + case 0x44: + nv04_graph_set_ctx_val(object, 0x08000000, 0x08000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_rop(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x10000000, 0); + return 0; + case 0x43: + nv04_graph_set_ctx_val(object, 0x10000000, 0x10000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_beta1(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x20000000, 0); + return 0; + case 0x12: + nv04_graph_set_ctx_val(object, 0x20000000, 0x20000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_beta4(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x40000000, 0); + return 0; + case 0x72: + nv04_graph_set_ctx_val(object, 0x40000000, 0x40000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_surf_dst(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x02000000, 0); + return 0; + case 0x58: + nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_surf_src(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x04000000, 0); + return 0; + case 0x59: + nv04_graph_set_ctx_val(object, 0x04000000, 0x04000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_surf_color(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x02000000, 0); + return 0; + case 0x5a: + nv04_graph_set_ctx_val(object, 0x02000000, 0x02000000); + return 0; + } + return 1; +} + +static int +nv04_graph_mthd_bind_surf_zeta(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx_val(object, 0x04000000, 0); + return 0; + case 0x5b: + nv04_graph_set_ctx_val(object, 0x04000000, 0x04000000); + return 0; + } + return 1; +} + +static int +nv01_graph_mthd_bind_clip(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx1(object, 0x2000, 0); + return 0; + case 0x19: + nv04_graph_set_ctx1(object, 0x2000, 0x2000); + return 0; + } + return 1; +} + +static int +nv01_graph_mthd_bind_chroma(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + switch (nv04_graph_mthd_bind_class(object, args, size)) { + case 0x30: + nv04_graph_set_ctx1(object, 0x1000, 0); + return 0; + /* Yes, for some reason even the old versions of objects + * accept 0x57 and not 0x17. Consistency be damned. + */ + case 0x57: + nv04_graph_set_ctx1(object, 0x1000, 0x1000); + return 0; + } + return 1; +} + +static struct nouveau_omthds +nv03_graph_gdi_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_patt }, + { 0x0188, nv04_graph_mthd_bind_rop }, + { 0x018c, nv04_graph_mthd_bind_beta1 }, + { 0x0190, nv04_graph_mthd_bind_surf_dst }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_gdi_omthds[] = { + { 0x0188, nv04_graph_mthd_bind_patt }, + { 0x018c, nv04_graph_mthd_bind_rop }, + { 0x0190, nv04_graph_mthd_bind_beta1 }, + { 0x0194, nv04_graph_mthd_bind_beta4 }, + { 0x0198, nv04_graph_mthd_bind_surf2d }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv01_graph_blit_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_chroma }, + { 0x0188, nv01_graph_mthd_bind_clip }, + { 0x018c, nv01_graph_mthd_bind_patt }, + { 0x0190, nv04_graph_mthd_bind_rop }, + { 0x0194, nv04_graph_mthd_bind_beta1 }, + { 0x0198, nv04_graph_mthd_bind_surf_dst }, + { 0x019c, nv04_graph_mthd_bind_surf_src }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_blit_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_chroma }, + { 0x0188, nv01_graph_mthd_bind_clip }, + { 0x018c, nv04_graph_mthd_bind_patt }, + { 0x0190, nv04_graph_mthd_bind_rop }, + { 0x0194, nv04_graph_mthd_bind_beta1 }, + { 0x0198, nv04_graph_mthd_bind_beta4 }, + { 0x019c, nv04_graph_mthd_bind_surf2d }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_iifc_omthds[] = { + { 0x0188, nv01_graph_mthd_bind_chroma }, + { 0x018c, nv01_graph_mthd_bind_clip }, + { 0x0190, nv04_graph_mthd_bind_patt }, + { 0x0194, nv04_graph_mthd_bind_rop }, + { 0x0198, nv04_graph_mthd_bind_beta1 }, + { 0x019c, nv04_graph_mthd_bind_beta4 }, + { 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf }, + { 0x03e4, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv01_graph_ifc_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_chroma }, + { 0x0188, nv01_graph_mthd_bind_clip }, + { 0x018c, nv01_graph_mthd_bind_patt }, + { 0x0190, nv04_graph_mthd_bind_rop }, + { 0x0194, nv04_graph_mthd_bind_beta1 }, + { 0x0198, nv04_graph_mthd_bind_surf_dst }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_ifc_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_chroma }, + { 0x0188, nv01_graph_mthd_bind_clip }, + { 0x018c, nv04_graph_mthd_bind_patt }, + { 0x0190, nv04_graph_mthd_bind_rop }, + { 0x0194, nv04_graph_mthd_bind_beta1 }, + { 0x0198, nv04_graph_mthd_bind_beta4 }, + { 0x019c, nv04_graph_mthd_bind_surf2d }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv03_graph_sifc_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_chroma }, + { 0x0188, nv01_graph_mthd_bind_patt }, + { 0x018c, nv04_graph_mthd_bind_rop }, + { 0x0190, nv04_graph_mthd_bind_beta1 }, + { 0x0194, nv04_graph_mthd_bind_surf_dst }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_sifc_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_chroma }, + { 0x0188, nv04_graph_mthd_bind_patt }, + { 0x018c, nv04_graph_mthd_bind_rop }, + { 0x0190, nv04_graph_mthd_bind_beta1 }, + { 0x0194, nv04_graph_mthd_bind_beta4 }, + { 0x0198, nv04_graph_mthd_bind_surf2d }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv03_graph_sifm_omthds[] = { + { 0x0188, nv01_graph_mthd_bind_patt }, + { 0x018c, nv04_graph_mthd_bind_rop }, + { 0x0190, nv04_graph_mthd_bind_beta1 }, + { 0x0194, nv04_graph_mthd_bind_surf_dst }, + { 0x0304, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_sifm_omthds[] = { + { 0x0188, nv04_graph_mthd_bind_patt }, + { 0x018c, nv04_graph_mthd_bind_rop }, + { 0x0190, nv04_graph_mthd_bind_beta1 }, + { 0x0194, nv04_graph_mthd_bind_beta4 }, + { 0x0198, nv04_graph_mthd_bind_surf2d }, + { 0x0304, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_surf3d_omthds[] = { + { 0x02f8, nv04_graph_mthd_surf3d_clip_h }, + { 0x02fc, nv04_graph_mthd_surf3d_clip_v }, + {} +}; + +static struct nouveau_omthds +nv03_graph_ttri_omthds[] = { + { 0x0188, nv01_graph_mthd_bind_clip }, + { 0x018c, nv04_graph_mthd_bind_surf_color }, + { 0x0190, nv04_graph_mthd_bind_surf_zeta }, + {} +}; + +static struct nouveau_omthds +nv01_graph_prim_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_clip }, + { 0x0188, nv01_graph_mthd_bind_patt }, + { 0x018c, nv04_graph_mthd_bind_rop }, + { 0x0190, nv04_graph_mthd_bind_beta1 }, + { 0x0194, nv04_graph_mthd_bind_surf_dst }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static struct nouveau_omthds +nv04_graph_prim_omthds[] = { + { 0x0184, nv01_graph_mthd_bind_clip }, + { 0x0188, nv04_graph_mthd_bind_patt }, + { 0x018c, nv04_graph_mthd_bind_rop }, + { 0x0190, nv04_graph_mthd_bind_beta1 }, + { 0x0194, nv04_graph_mthd_bind_beta4 }, + { 0x0198, nv04_graph_mthd_bind_surf2d }, + { 0x02fc, nv04_graph_mthd_set_operation }, + {} +}; + +static int +nv04_graph_object_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_gpuobj *obj; + int ret; + + ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent, + 16, 16, 0, &obj); + *pobject = nv_object(obj); + if (ret) + return ret; + + nv_wo32(obj, 0x00, nv_mclass(obj)); +#ifdef __BIG_ENDIAN + nv_mo32(obj, 0x00, 0x00080000, 0x00080000); +#endif + nv_wo32(obj, 0x04, 0x00000000); + nv_wo32(obj, 0x08, 0x00000000); + nv_wo32(obj, 0x0c, 0x00000000); + return 0; +} + +struct nouveau_ofuncs +nv04_graph_ofuncs = { + .ctor = nv04_graph_object_ctor, + .dtor = _nouveau_gpuobj_dtor, + .init = _nouveau_gpuobj_init, + .fini = _nouveau_gpuobj_fini, + .rd32 = _nouveau_gpuobj_rd32, + .wr32 = _nouveau_gpuobj_wr32, +}; + +static struct nouveau_oclass +nv04_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs }, /* beta1 */ + { 0x0017, &nv04_graph_ofuncs }, /* chroma */ + { 0x0018, &nv04_graph_ofuncs }, /* pattern (nv01) */ + { 0x0019, &nv04_graph_ofuncs }, /* clip */ + { 0x001c, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* line */ + { 0x001d, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* tri */ + { 0x001e, &nv04_graph_ofuncs, nv01_graph_prim_omthds }, /* rect */ + { 0x001f, &nv04_graph_ofuncs, nv01_graph_blit_omthds }, + { 0x0021, &nv04_graph_ofuncs, nv01_graph_ifc_omthds }, + { 0x0030, &nv04_graph_ofuncs }, /* null */ + { 0x0036, &nv04_graph_ofuncs, nv03_graph_sifc_omthds }, + { 0x0037, &nv04_graph_ofuncs, nv03_graph_sifm_omthds }, + { 0x0038, &nv04_graph_ofuncs }, /* dvd subpicture */ + { 0x0039, &nv04_graph_ofuncs }, /* m2mf */ + { 0x0042, &nv04_graph_ofuncs }, /* surf2d */ + { 0x0043, &nv04_graph_ofuncs }, /* rop */ + { 0x0044, &nv04_graph_ofuncs }, /* pattern */ + { 0x0048, &nv04_graph_ofuncs, nv03_graph_ttri_omthds }, + { 0x004a, &nv04_graph_ofuncs, nv04_graph_gdi_omthds }, + { 0x004b, &nv04_graph_ofuncs, nv03_graph_gdi_omthds }, + { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */ + { 0x0053, &nv04_graph_ofuncs, nv04_graph_surf3d_omthds }, + { 0x0054, &nv04_graph_ofuncs }, /* ttri */ + { 0x0055, &nv04_graph_ofuncs }, /* mtri */ + { 0x0057, &nv04_graph_ofuncs }, /* chroma */ + { 0x0058, &nv04_graph_ofuncs }, /* surf_dst */ + { 0x0059, &nv04_graph_ofuncs }, /* surf_src */ + { 0x005a, &nv04_graph_ofuncs }, /* surf_color */ + { 0x005b, &nv04_graph_ofuncs }, /* surf_zeta */ + { 0x005c, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* line */ + { 0x005d, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* tri */ + { 0x005e, &nv04_graph_ofuncs, nv04_graph_prim_omthds }, /* rect */ + { 0x005f, &nv04_graph_ofuncs, nv04_graph_blit_omthds }, + { 0x0060, &nv04_graph_ofuncs, nv04_graph_iifc_omthds }, + { 0x0061, &nv04_graph_ofuncs, nv04_graph_ifc_omthds }, + { 0x0064, &nv04_graph_ofuncs }, /* iifc (nv05) */ + { 0x0065, &nv04_graph_ofuncs }, /* ifc (nv05) */ + { 0x0066, &nv04_graph_ofuncs }, /* sifc (nv05) */ + { 0x0072, &nv04_graph_ofuncs }, /* beta4 */ + { 0x0076, &nv04_graph_ofuncs, nv04_graph_sifc_omthds }, + { 0x0077, &nv04_graph_ofuncs, nv04_graph_sifm_omthds }, + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static struct nv04_graph_chan * +nv04_graph_channel(struct nv04_graph_priv *priv) +{ + struct nv04_graph_chan *chan = NULL; + if (nv_rd32(priv, NV04_PGRAPH_CTX_CONTROL) & 0x00010000) { + int chid = nv_rd32(priv, NV04_PGRAPH_CTX_USER) >> 24; + if (chid < ARRAY_SIZE(priv->chan)) + chan = priv->chan[chid]; + } + return chan; +} + +static int +nv04_graph_load_context(struct nv04_graph_chan *chan, int chid) +{ + struct nv04_graph_priv *priv = nv04_graph_priv(chan); + int i; + + for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) + nv_wr32(priv, nv04_graph_ctx_regs[i], chan->nv04[i]); + + nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10010100); + nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, chid << 24); + nv_mask(priv, NV04_PGRAPH_FFINTFC_ST2, 0xfff00000, 0x00000000); + return 0; +} + +static int +nv04_graph_unload_context(struct nv04_graph_chan *chan) +{ + struct nv04_graph_priv *priv = nv04_graph_priv(chan); + int i; + + for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) + chan->nv04[i] = nv_rd32(priv, nv04_graph_ctx_regs[i]); + + nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL, 0x10000000); + nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000); + return 0; +} + +static void +nv04_graph_context_switch(struct nv04_graph_priv *priv) +{ + struct nv04_graph_chan *prev = NULL; + struct nv04_graph_chan *next = NULL; + unsigned long flags; + int chid; + + spin_lock_irqsave(&priv->lock, flags); + nv04_graph_idle(priv); + + /* If previous context is valid, we need to save it */ + prev = nv04_graph_channel(priv); + if (prev) + nv04_graph_unload_context(prev); + + /* load context for next channel */ + chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0x0f; + next = priv->chan[chid]; + if (next) + nv04_graph_load_context(next, chid); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +static u32 *ctx_reg(struct nv04_graph_chan *chan, u32 reg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) { + if (nv04_graph_ctx_regs[i] == reg) + return &chan->nv04[i]; + } + + return NULL; +} + +static int +nv04_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_fifo_chan *fifo = (void *)parent; + struct nv04_graph_priv *priv = (void *)engine; + struct nv04_graph_chan *chan; + unsigned long flags; + int ret; + + ret = nouveau_object_create(parent, engine, oclass, 0, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->chan[fifo->chid]) { + *pobject = nv_object(priv->chan[fifo->chid]); + atomic_inc(&(*pobject)->refcount); + spin_unlock_irqrestore(&priv->lock, flags); + nouveau_object_destroy(&chan->base); + return 1; + } + + *ctx_reg(chan, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31; + + priv->chan[fifo->chid] = chan; + chan->chid = fifo->chid; + spin_unlock_irqrestore(&priv->lock, flags); + return 0; +} + +static void +nv04_graph_context_dtor(struct nouveau_object *object) +{ + struct nv04_graph_priv *priv = (void *)object->engine; + struct nv04_graph_chan *chan = (void *)object; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + priv->chan[chan->chid] = NULL; + spin_unlock_irqrestore(&priv->lock, flags); + + nouveau_object_destroy(&chan->base); +} + +static int +nv04_graph_context_fini(struct nouveau_object *object, bool suspend) +{ + struct nv04_graph_priv *priv = (void *)object->engine; + struct nv04_graph_chan *chan = (void *)object; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); + if (nv04_graph_channel(priv) == chan) + nv04_graph_unload_context(chan); + nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); + spin_unlock_irqrestore(&priv->lock, flags); + + return nouveau_object_fini(&chan->base, suspend); +} + +static struct nouveau_oclass +nv04_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x04), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv04_graph_context_ctor, + .dtor = nv04_graph_context_dtor, + .init = nouveau_object_init, + .fini = nv04_graph_context_fini, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +bool +nv04_graph_idle(void *obj) +{ + struct nouveau_graph *graph = nouveau_graph(obj); + u32 mask = 0xffffffff; + + if (nv_device(obj)->card_type == NV_40) + mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL; + + if (!nv_wait(graph, NV04_PGRAPH_STATUS, mask, 0)) { + nv_error(graph, "idle timed out with status 0x%08x\n", + nv_rd32(graph, NV04_PGRAPH_STATUS)); + return false; + } + + return true; +} + +static const struct nouveau_bitfield +nv04_graph_intr_name[] = { + { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, + {} +}; + +static const struct nouveau_bitfield +nv04_graph_nstatus[] = { + { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, + { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, + { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, + {} +}; + +const struct nouveau_bitfield +nv04_graph_nsource[] = { + { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, + { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, + { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, + { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, + { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, + { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, + { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, + { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, + { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, + { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, + { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, + { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, + { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, + {} +}; + +static void +nv04_graph_intr(struct nouveau_subdev *subdev) +{ + struct nv04_graph_priv *priv = (void *)subdev; + struct nv04_graph_chan *chan = NULL; + struct nouveau_namedb *namedb = NULL; + struct nouveau_handle *handle = NULL; + u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); + u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); + u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR); + u32 chid = (addr & 0x0f000000) >> 24; + u32 subc = (addr & 0x0000e000) >> 13; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(priv, 0x400180 + subc * 4) & 0xff; + u32 inst = (nv_rd32(priv, 0x40016c) & 0xffff) << 4; + u32 show = stat; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + chan = priv->chan[chid]; + if (chan) + namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS); + spin_unlock_irqrestore(&priv->lock, flags); + + if (stat & NV_PGRAPH_INTR_NOTIFY) { + if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { + handle = nouveau_namedb_get_vinst(namedb, inst); + if (handle && !nv_call(handle->object, mthd, data)) + show &= ~NV_PGRAPH_INTR_NOTIFY; + } + } + + if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { + nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); + stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + nv04_graph_context_switch(priv); + } + + nv_wr32(priv, NV03_PGRAPH_INTR, stat); + nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); + + if (show) { + nv_error(priv, ""); + nouveau_bitfield_print(nv04_graph_intr_name, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv04_graph_nstatus, nstatus); + printk("\n"); + nv_error(priv, "ch %d/%d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); + } + + nouveau_namedb_put(handle); +} + +static int +nv04_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv04_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv04_graph_intr; + nv_engine(priv)->cclass = &nv04_graph_cclass; + nv_engine(priv)->sclass = nv04_graph_sclass; + spin_lock_init(&priv->lock); + return 0; +} + +static int +nv04_graph_init(struct nouveau_object *object) +{ + struct nouveau_engine *engine = nv_engine(object); + struct nv04_graph_priv *priv = (void *)engine; + int ret; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + /* Enable PGRAPH interrupts */ + nv_wr32(priv, NV03_PGRAPH_INTR, 0xFFFFFFFF); + nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); + + nv_wr32(priv, NV04_PGRAPH_VALID1, 0); + nv_wr32(priv, NV04_PGRAPH_VALID2, 0); + /*nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x000001FF); + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/ + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x1231c000); + /*1231C000 blob, 001 haiku*/ + /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ + nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x72111100); + /*0x72111100 blob , 01 haiku*/ + /*nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/ + nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x11d5f071); + /*haiku same*/ + + /*nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/ + nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31); + /*haiku and blob 10d4*/ + + nv_wr32(priv, NV04_PGRAPH_STATE , 0xFFFFFFFF); + nv_wr32(priv, NV04_PGRAPH_CTX_CONTROL , 0x10000100); + nv_mask(priv, NV04_PGRAPH_CTX_USER, 0xff000000, 0x0f000000); + + /* These don't belong here, they're part of a per-channel context */ + nv_wr32(priv, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); + nv_wr32(priv, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); + return 0; +} + +struct nouveau_oclass +nv04_graph_oclass = { + .handle = NV_ENGINE(GR, 0x04), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv04_graph_ctor, + .dtor = _nouveau_graph_dtor, + .init = nv04_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c new file mode 100644 index 00000000000..92521c89e77 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c @@ -0,0 +1,1314 @@ +/* + * Copyright 2007 Matthieu CASTET <castet.matthieu@free.fr> + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <core/os.h> +#include <core/class.h> +#include <core/handle.h> + +#include <subdev/fb.h> + +#include <engine/fifo.h> +#include <engine/graph.h> + +#include "regs.h" + +struct pipe_state { + u32 pipe_0x0000[0x040/4]; + u32 pipe_0x0040[0x010/4]; + u32 pipe_0x0200[0x0c0/4]; + u32 pipe_0x4400[0x080/4]; + u32 pipe_0x6400[0x3b0/4]; + u32 pipe_0x6800[0x2f0/4]; + u32 pipe_0x6c00[0x030/4]; + u32 pipe_0x7000[0x130/4]; + u32 pipe_0x7400[0x0c0/4]; + u32 pipe_0x7800[0x0c0/4]; +}; + +static int nv10_graph_ctx_regs[] = { + NV10_PGRAPH_CTX_SWITCH(0), + NV10_PGRAPH_CTX_SWITCH(1), + NV10_PGRAPH_CTX_SWITCH(2), + NV10_PGRAPH_CTX_SWITCH(3), + NV10_PGRAPH_CTX_SWITCH(4), + NV10_PGRAPH_CTX_CACHE(0, 0), + NV10_PGRAPH_CTX_CACHE(0, 1), + NV10_PGRAPH_CTX_CACHE(0, 2), + NV10_PGRAPH_CTX_CACHE(0, 3), + NV10_PGRAPH_CTX_CACHE(0, 4), + NV10_PGRAPH_CTX_CACHE(1, 0), + NV10_PGRAPH_CTX_CACHE(1, 1), + NV10_PGRAPH_CTX_CACHE(1, 2), + NV10_PGRAPH_CTX_CACHE(1, 3), + NV10_PGRAPH_CTX_CACHE(1, 4), + NV10_PGRAPH_CTX_CACHE(2, 0), + NV10_PGRAPH_CTX_CACHE(2, 1), + NV10_PGRAPH_CTX_CACHE(2, 2), + NV10_PGRAPH_CTX_CACHE(2, 3), + NV10_PGRAPH_CTX_CACHE(2, 4), + NV10_PGRAPH_CTX_CACHE(3, 0), + NV10_PGRAPH_CTX_CACHE(3, 1), + NV10_PGRAPH_CTX_CACHE(3, 2), + NV10_PGRAPH_CTX_CACHE(3, 3), + NV10_PGRAPH_CTX_CACHE(3, 4), + NV10_PGRAPH_CTX_CACHE(4, 0), + NV10_PGRAPH_CTX_CACHE(4, 1), + NV10_PGRAPH_CTX_CACHE(4, 2), + NV10_PGRAPH_CTX_CACHE(4, 3), + NV10_PGRAPH_CTX_CACHE(4, 4), + NV10_PGRAPH_CTX_CACHE(5, 0), + NV10_PGRAPH_CTX_CACHE(5, 1), + NV10_PGRAPH_CTX_CACHE(5, 2), + NV10_PGRAPH_CTX_CACHE(5, 3), + NV10_PGRAPH_CTX_CACHE(5, 4), + NV10_PGRAPH_CTX_CACHE(6, 0), + NV10_PGRAPH_CTX_CACHE(6, 1), + NV10_PGRAPH_CTX_CACHE(6, 2), + NV10_PGRAPH_CTX_CACHE(6, 3), + NV10_PGRAPH_CTX_CACHE(6, 4), + NV10_PGRAPH_CTX_CACHE(7, 0), + NV10_PGRAPH_CTX_CACHE(7, 1), + NV10_PGRAPH_CTX_CACHE(7, 2), + NV10_PGRAPH_CTX_CACHE(7, 3), + NV10_PGRAPH_CTX_CACHE(7, 4), + NV10_PGRAPH_CTX_USER, + NV04_PGRAPH_DMA_START_0, + NV04_PGRAPH_DMA_START_1, + NV04_PGRAPH_DMA_LENGTH, + NV04_PGRAPH_DMA_MISC, + NV10_PGRAPH_DMA_PITCH, + NV04_PGRAPH_BOFFSET0, + NV04_PGRAPH_BBASE0, + NV04_PGRAPH_BLIMIT0, + NV04_PGRAPH_BOFFSET1, + NV04_PGRAPH_BBASE1, + NV04_PGRAPH_BLIMIT1, + NV04_PGRAPH_BOFFSET2, + NV04_PGRAPH_BBASE2, + NV04_PGRAPH_BLIMIT2, + NV04_PGRAPH_BOFFSET3, + NV04_PGRAPH_BBASE3, + NV04_PGRAPH_BLIMIT3, + NV04_PGRAPH_BOFFSET4, + NV04_PGRAPH_BBASE4, + NV04_PGRAPH_BLIMIT4, + NV04_PGRAPH_BOFFSET5, + NV04_PGRAPH_BBASE5, + NV04_PGRAPH_BLIMIT5, + NV04_PGRAPH_BPITCH0, + NV04_PGRAPH_BPITCH1, + NV04_PGRAPH_BPITCH2, + NV04_PGRAPH_BPITCH3, + NV04_PGRAPH_BPITCH4, + NV10_PGRAPH_SURFACE, + NV10_PGRAPH_STATE, + NV04_PGRAPH_BSWIZZLE2, + NV04_PGRAPH_BSWIZZLE5, + NV04_PGRAPH_BPIXEL, + NV10_PGRAPH_NOTIFY, + NV04_PGRAPH_PATT_COLOR0, + NV04_PGRAPH_PATT_COLOR1, + NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */ + 0x00400904, + 0x00400908, + 0x0040090c, + 0x00400910, + 0x00400914, + 0x00400918, + 0x0040091c, + 0x00400920, + 0x00400924, + 0x00400928, + 0x0040092c, + 0x00400930, + 0x00400934, + 0x00400938, + 0x0040093c, + 0x00400940, + 0x00400944, + 0x00400948, + 0x0040094c, + 0x00400950, + 0x00400954, + 0x00400958, + 0x0040095c, + 0x00400960, + 0x00400964, + 0x00400968, + 0x0040096c, + 0x00400970, + 0x00400974, + 0x00400978, + 0x0040097c, + 0x00400980, + 0x00400984, + 0x00400988, + 0x0040098c, + 0x00400990, + 0x00400994, + 0x00400998, + 0x0040099c, + 0x004009a0, + 0x004009a4, + 0x004009a8, + 0x004009ac, + 0x004009b0, + 0x004009b4, + 0x004009b8, + 0x004009bc, + 0x004009c0, + 0x004009c4, + 0x004009c8, + 0x004009cc, + 0x004009d0, + 0x004009d4, + 0x004009d8, + 0x004009dc, + 0x004009e0, + 0x004009e4, + 0x004009e8, + 0x004009ec, + 0x004009f0, + 0x004009f4, + 0x004009f8, + 0x004009fc, + NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */ + 0x0040080c, + NV04_PGRAPH_PATTERN_SHAPE, + NV03_PGRAPH_MONO_COLOR0, + NV04_PGRAPH_ROP3, + NV04_PGRAPH_CHROMA, + NV04_PGRAPH_BETA_AND, + NV04_PGRAPH_BETA_PREMULT, + 0x00400e70, + 0x00400e74, + 0x00400e78, + 0x00400e7c, + 0x00400e80, + 0x00400e84, + 0x00400e88, + 0x00400e8c, + 0x00400ea0, + 0x00400ea4, + 0x00400ea8, + 0x00400e90, + 0x00400e94, + 0x00400e98, + 0x00400e9c, + NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */ + NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20-0x400f3c */ + 0x00400f04, + 0x00400f24, + 0x00400f08, + 0x00400f28, + 0x00400f0c, + 0x00400f2c, + 0x00400f10, + 0x00400f30, + 0x00400f14, + 0x00400f34, + 0x00400f18, + 0x00400f38, + 0x00400f1c, + 0x00400f3c, + NV10_PGRAPH_XFMODE0, + NV10_PGRAPH_XFMODE1, + NV10_PGRAPH_GLOBALSTATE0, + NV10_PGRAPH_GLOBALSTATE1, + NV04_PGRAPH_STORED_FMT, + NV04_PGRAPH_SOURCE_COLOR, + NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */ + NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */ + 0x00400404, + 0x00400484, + 0x00400408, + 0x00400488, + 0x0040040c, + 0x0040048c, + 0x00400410, + 0x00400490, + 0x00400414, + 0x00400494, + 0x00400418, + 0x00400498, + 0x0040041c, + 0x0040049c, + 0x00400420, + 0x004004a0, + 0x00400424, + 0x004004a4, + 0x00400428, + 0x004004a8, + 0x0040042c, + 0x004004ac, + 0x00400430, + 0x004004b0, + 0x00400434, + 0x004004b4, + 0x00400438, + 0x004004b8, + 0x0040043c, + 0x004004bc, + 0x00400440, + 0x004004c0, + 0x00400444, + 0x004004c4, + 0x00400448, + 0x004004c8, + 0x0040044c, + 0x004004cc, + 0x00400450, + 0x004004d0, + 0x00400454, + 0x004004d4, + 0x00400458, + 0x004004d8, + 0x0040045c, + 0x004004dc, + 0x00400460, + 0x004004e0, + 0x00400464, + 0x004004e4, + 0x00400468, + 0x004004e8, + 0x0040046c, + 0x004004ec, + 0x00400470, + 0x004004f0, + 0x00400474, + 0x004004f4, + 0x00400478, + 0x004004f8, + 0x0040047c, + 0x004004fc, + NV03_PGRAPH_ABS_UCLIP_XMIN, + NV03_PGRAPH_ABS_UCLIP_XMAX, + NV03_PGRAPH_ABS_UCLIP_YMIN, + NV03_PGRAPH_ABS_UCLIP_YMAX, + 0x00400550, + 0x00400558, + 0x00400554, + 0x0040055c, + NV03_PGRAPH_ABS_UCLIPA_XMIN, + NV03_PGRAPH_ABS_UCLIPA_XMAX, + NV03_PGRAPH_ABS_UCLIPA_YMIN, + NV03_PGRAPH_ABS_UCLIPA_YMAX, + NV03_PGRAPH_ABS_ICLIP_XMAX, + NV03_PGRAPH_ABS_ICLIP_YMAX, + NV03_PGRAPH_XY_LOGIC_MISC0, + NV03_PGRAPH_XY_LOGIC_MISC1, + NV03_PGRAPH_XY_LOGIC_MISC2, + NV03_PGRAPH_XY_LOGIC_MISC3, + NV03_PGRAPH_CLIPX_0, + NV03_PGRAPH_CLIPX_1, + NV03_PGRAPH_CLIPY_0, + NV03_PGRAPH_CLIPY_1, + NV10_PGRAPH_COMBINER0_IN_ALPHA, + NV10_PGRAPH_COMBINER1_IN_ALPHA, + NV10_PGRAPH_COMBINER0_IN_RGB, + NV10_PGRAPH_COMBINER1_IN_RGB, + NV10_PGRAPH_COMBINER_COLOR0, + NV10_PGRAPH_COMBINER_COLOR1, + NV10_PGRAPH_COMBINER0_OUT_ALPHA, + NV10_PGRAPH_COMBINER1_OUT_ALPHA, + NV10_PGRAPH_COMBINER0_OUT_RGB, + NV10_PGRAPH_COMBINER1_OUT_RGB, + NV10_PGRAPH_COMBINER_FINAL0, + NV10_PGRAPH_COMBINER_FINAL1, + 0x00400e00, + 0x00400e04, + 0x00400e08, + 0x00400e0c, + 0x00400e10, + 0x00400e14, + 0x00400e18, + 0x00400e1c, + 0x00400e20, + 0x00400e24, + 0x00400e28, + 0x00400e2c, + 0x00400e30, + 0x00400e34, + 0x00400e38, + 0x00400e3c, + NV04_PGRAPH_PASSTHRU_0, + NV04_PGRAPH_PASSTHRU_1, + NV04_PGRAPH_PASSTHRU_2, + NV10_PGRAPH_DIMX_TEXTURE, + NV10_PGRAPH_WDIMX_TEXTURE, + NV10_PGRAPH_DVD_COLORFMT, + NV10_PGRAPH_SCALED_FORMAT, + NV04_PGRAPH_MISC24_0, + NV04_PGRAPH_MISC24_1, + NV04_PGRAPH_MISC24_2, + NV03_PGRAPH_X_MISC, + NV03_PGRAPH_Y_MISC, + NV04_PGRAPH_VALID1, + NV04_PGRAPH_VALID2, +}; + +static int nv17_graph_ctx_regs[] = { + NV10_PGRAPH_DEBUG_4, + 0x004006b0, + 0x00400eac, + 0x00400eb0, + 0x00400eb4, + 0x00400eb8, + 0x00400ebc, + 0x00400ec0, + 0x00400ec4, + 0x00400ec8, + 0x00400ecc, + 0x00400ed0, + 0x00400ed4, + 0x00400ed8, + 0x00400edc, + 0x00400ee0, + 0x00400a00, + 0x00400a04, +}; + +struct nv10_graph_priv { + struct nouveau_graph base; + struct nv10_graph_chan *chan[32]; + spinlock_t lock; +}; + +struct nv10_graph_chan { + struct nouveau_object base; + int chid; + int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)]; + int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)]; + struct pipe_state pipe_state; + u32 lma_window[4]; +}; + + +static inline struct nv10_graph_priv * +nv10_graph_priv(struct nv10_graph_chan *chan) +{ + return (void *)nv_object(chan)->engine; +} + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +#define PIPE_SAVE(priv, state, addr) \ + do { \ + int __i; \ + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \ + for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ + state[__i] = nv_rd32(priv, NV10_PGRAPH_PIPE_DATA); \ + } while (0) + +#define PIPE_RESTORE(priv, state, addr) \ + do { \ + int __i; \ + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, addr); \ + for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, state[__i]); \ + } while (0) + +static struct nouveau_oclass +nv10_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs }, /* clip */ + { 0x0030, &nv04_graph_ofuncs }, /* null */ + { 0x0039, &nv04_graph_ofuncs }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs }, /* rop */ + { 0x0044, &nv04_graph_ofuncs }, /* pattern */ + { 0x004a, &nv04_graph_ofuncs }, /* gdi */ + { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */ + { 0x005f, &nv04_graph_ofuncs }, /* blit */ + { 0x0062, &nv04_graph_ofuncs }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs }, /* ifc */ + { 0x009f, &nv04_graph_ofuncs }, /* blit */ + { 0x0093, &nv04_graph_ofuncs }, /* surf3d */ + { 0x0094, &nv04_graph_ofuncs }, /* ttri */ + { 0x0095, &nv04_graph_ofuncs }, /* mtri */ + { 0x0056, &nv04_graph_ofuncs }, /* celcius */ + {}, +}; + +static struct nouveau_oclass +nv15_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs }, /* clip */ + { 0x0030, &nv04_graph_ofuncs }, /* null */ + { 0x0039, &nv04_graph_ofuncs }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs }, /* rop */ + { 0x0044, &nv04_graph_ofuncs }, /* pattern */ + { 0x004a, &nv04_graph_ofuncs }, /* gdi */ + { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */ + { 0x005f, &nv04_graph_ofuncs }, /* blit */ + { 0x0062, &nv04_graph_ofuncs }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs }, /* ifc */ + { 0x009f, &nv04_graph_ofuncs }, /* blit */ + { 0x0093, &nv04_graph_ofuncs }, /* surf3d */ + { 0x0094, &nv04_graph_ofuncs }, /* ttri */ + { 0x0095, &nv04_graph_ofuncs }, /* mtri */ + { 0x0096, &nv04_graph_ofuncs }, /* celcius */ + {}, +}; + +static int +nv17_graph_mthd_lma_window(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + struct nv10_graph_chan *chan = (void *)object->parent; + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + struct pipe_state *pipe = &chan->pipe_state; + u32 pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; + u32 xfmode0, xfmode1; + u32 data = *(u32 *)args; + int i; + + chan->lma_window[(mthd - 0x1638) / 4] = data; + + if (mthd != 0x1644) + return 0; + + nv04_graph_idle(priv); + + PIPE_SAVE(priv, pipe_0x0040, 0x0040); + PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200); + + PIPE_RESTORE(priv, chan->lma_window, 0x6790); + + nv04_graph_idle(priv); + + xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0); + xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1); + + PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400); + PIPE_SAVE(priv, pipe_0x64c0, 0x64c0); + PIPE_SAVE(priv, pipe_0x6ab0, 0x6ab0); + PIPE_SAVE(priv, pipe_0x6a80, 0x6a80); + + nv04_graph_idle(priv); + + nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000); + nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000); + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); + for (i = 0; i < 4; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); + for (i = 0; i < 4; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); + for (i = 0; i < 3; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); + + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); + for (i = 0; i < 3; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008); + + PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200); + + nv04_graph_idle(priv); + + PIPE_RESTORE(priv, pipe_0x0040, 0x0040); + + nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0); + nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1); + + PIPE_RESTORE(priv, pipe_0x64c0, 0x64c0); + PIPE_RESTORE(priv, pipe_0x6ab0, 0x6ab0); + PIPE_RESTORE(priv, pipe_0x6a80, 0x6a80); + PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400); + + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0); + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nv04_graph_idle(priv); + + return 0; +} + +static int +nv17_graph_mthd_lma_enable(struct nouveau_object *object, u32 mthd, + void *args, u32 size) +{ + struct nv10_graph_chan *chan = (void *)object->parent; + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + + nv04_graph_idle(priv); + + nv_mask(priv, NV10_PGRAPH_DEBUG_4, 0x00000100, 0x00000100); + nv_mask(priv, 0x4006b0, 0x08000000, 0x08000000); + return 0; +} + +static struct nouveau_omthds +nv17_celcius_omthds[] = { + { 0x1638, nv17_graph_mthd_lma_window }, + { 0x163c, nv17_graph_mthd_lma_window }, + { 0x1640, nv17_graph_mthd_lma_window }, + { 0x1644, nv17_graph_mthd_lma_window }, + { 0x1658, nv17_graph_mthd_lma_enable }, + {} +}; + +static struct nouveau_oclass +nv17_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs }, /* clip */ + { 0x0030, &nv04_graph_ofuncs }, /* null */ + { 0x0039, &nv04_graph_ofuncs }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs }, /* rop */ + { 0x0044, &nv04_graph_ofuncs }, /* pattern */ + { 0x004a, &nv04_graph_ofuncs }, /* gdi */ + { 0x0052, &nv04_graph_ofuncs }, /* swzsurf */ + { 0x005f, &nv04_graph_ofuncs }, /* blit */ + { 0x0062, &nv04_graph_ofuncs }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs }, /* ifc */ + { 0x009f, &nv04_graph_ofuncs }, /* blit */ + { 0x0093, &nv04_graph_ofuncs }, /* surf3d */ + { 0x0094, &nv04_graph_ofuncs }, /* ttri */ + { 0x0095, &nv04_graph_ofuncs }, /* mtri */ + { 0x0099, &nv04_graph_ofuncs, nv17_celcius_omthds }, + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static struct nv10_graph_chan * +nv10_graph_channel(struct nv10_graph_priv *priv) +{ + struct nv10_graph_chan *chan = NULL; + if (nv_rd32(priv, 0x400144) & 0x00010000) { + int chid = nv_rd32(priv, 0x400148) >> 24; + if (chid < ARRAY_SIZE(priv->chan)) + chan = priv->chan[chid]; + } + return chan; +} + +static void +nv10_graph_save_pipe(struct nv10_graph_chan *chan) +{ + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + struct pipe_state *pipe = &chan->pipe_state; + + PIPE_SAVE(priv, pipe->pipe_0x4400, 0x4400); + PIPE_SAVE(priv, pipe->pipe_0x0200, 0x0200); + PIPE_SAVE(priv, pipe->pipe_0x6400, 0x6400); + PIPE_SAVE(priv, pipe->pipe_0x6800, 0x6800); + PIPE_SAVE(priv, pipe->pipe_0x6c00, 0x6c00); + PIPE_SAVE(priv, pipe->pipe_0x7000, 0x7000); + PIPE_SAVE(priv, pipe->pipe_0x7400, 0x7400); + PIPE_SAVE(priv, pipe->pipe_0x7800, 0x7800); + PIPE_SAVE(priv, pipe->pipe_0x0040, 0x0040); + PIPE_SAVE(priv, pipe->pipe_0x0000, 0x0000); +} + +static void +nv10_graph_load_pipe(struct nv10_graph_chan *chan) +{ + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + struct pipe_state *pipe = &chan->pipe_state; + u32 xfmode0, xfmode1; + int i; + + nv04_graph_idle(priv); + /* XXX check haiku comments */ + xfmode0 = nv_rd32(priv, NV10_PGRAPH_XFMODE0); + xfmode1 = nv_rd32(priv, NV10_PGRAPH_XFMODE1); + nv_wr32(priv, NV10_PGRAPH_XFMODE0, 0x10000000); + nv_wr32(priv, NV10_PGRAPH_XFMODE1, 0x00000000); + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); + for (i = 0; i < 4; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); + for (i = 0; i < 4; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); + for (i = 0; i < 3; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x3f800000); + + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); + for (i = 0; i < 3; i++) + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000000); + + nv_wr32(priv, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); + nv_wr32(priv, NV10_PGRAPH_PIPE_DATA, 0x00000008); + + + PIPE_RESTORE(priv, pipe->pipe_0x0200, 0x0200); + nv04_graph_idle(priv); + + /* restore XFMODE */ + nv_wr32(priv, NV10_PGRAPH_XFMODE0, xfmode0); + nv_wr32(priv, NV10_PGRAPH_XFMODE1, xfmode1); + PIPE_RESTORE(priv, pipe->pipe_0x6400, 0x6400); + PIPE_RESTORE(priv, pipe->pipe_0x6800, 0x6800); + PIPE_RESTORE(priv, pipe->pipe_0x6c00, 0x6c00); + PIPE_RESTORE(priv, pipe->pipe_0x7000, 0x7000); + PIPE_RESTORE(priv, pipe->pipe_0x7400, 0x7400); + PIPE_RESTORE(priv, pipe->pipe_0x7800, 0x7800); + PIPE_RESTORE(priv, pipe->pipe_0x4400, 0x4400); + PIPE_RESTORE(priv, pipe->pipe_0x0000, 0x0000); + PIPE_RESTORE(priv, pipe->pipe_0x0040, 0x0040); + nv04_graph_idle(priv); +} + +static void +nv10_graph_create_pipe(struct nv10_graph_chan *chan) +{ + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + struct pipe_state *pipe_state = &chan->pipe_state; + u32 *pipe_state_addr; + int i; +#define PIPE_INIT(addr) \ + do { \ + pipe_state_addr = pipe_state->pipe_##addr; \ + } while (0) +#define PIPE_INIT_END(addr) \ + do { \ + u32 *__end_addr = pipe_state->pipe_##addr + \ + ARRAY_SIZE(pipe_state->pipe_##addr); \ + if (pipe_state_addr != __end_addr) \ + nv_error(priv, "incomplete pipe init for 0x%x : %p/%p\n", \ + addr, pipe_state_addr, __end_addr); \ + } while (0) +#define NV_WRITE_PIPE_INIT(value) *(pipe_state_addr++) = value + + PIPE_INIT(0x0200); + for (i = 0; i < 48; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x0200); + + PIPE_INIT(0x6400); + for (i = 0; i < 211; i++) + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x40000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f000000); + NV_WRITE_PIPE_INIT(0x3f000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x3f800000); + NV_WRITE_PIPE_INIT(0x3f800000); + PIPE_INIT_END(0x6400); + + PIPE_INIT(0x6800); + for (i = 0; i < 162; i++) + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x3f800000); + for (i = 0; i < 25; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x6800); + + PIPE_INIT(0x6c00); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0xbf800000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x6c00); + + PIPE_INIT(0x7000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x00000000); + NV_WRITE_PIPE_INIT(0x7149f2ca); + for (i = 0; i < 35; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x7000); + + PIPE_INIT(0x7400); + for (i = 0; i < 48; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x7400); + + PIPE_INIT(0x7800); + for (i = 0; i < 48; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x7800); + + PIPE_INIT(0x4400); + for (i = 0; i < 32; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x4400); + + PIPE_INIT(0x0000); + for (i = 0; i < 16; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x0000); + + PIPE_INIT(0x0040); + for (i = 0; i < 4; i++) + NV_WRITE_PIPE_INIT(0x00000000); + PIPE_INIT_END(0x0040); + +#undef PIPE_INIT +#undef PIPE_INIT_END +#undef NV_WRITE_PIPE_INIT +} + +static int +nv10_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg) +{ + int i; + for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) { + if (nv10_graph_ctx_regs[i] == reg) + return i; + } + nv_error(priv, "unknow offset nv10_ctx_regs %d\n", reg); + return -1; +} + +static int +nv17_graph_ctx_regs_find_offset(struct nv10_graph_priv *priv, int reg) +{ + int i; + for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) { + if (nv17_graph_ctx_regs[i] == reg) + return i; + } + nv_error(priv, "unknow offset nv17_ctx_regs %d\n", reg); + return -1; +} + +static void +nv10_graph_load_dma_vtxbuf(struct nv10_graph_chan *chan, int chid, u32 inst) +{ + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + u32 st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4]; + u32 ctx_user, ctx_switch[5]; + int i, subchan = -1; + + /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state + * that cannot be restored via MMIO. Do it through the FIFO + * instead. + */ + + /* Look for a celsius object */ + for (i = 0; i < 8; i++) { + int class = nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff; + + if (class == 0x56 || class == 0x96 || class == 0x99) { + subchan = i; + break; + } + } + + if (subchan < 0 || !inst) + return; + + /* Save the current ctx object */ + ctx_user = nv_rd32(priv, NV10_PGRAPH_CTX_USER); + for (i = 0; i < 5; i++) + ctx_switch[i] = nv_rd32(priv, NV10_PGRAPH_CTX_SWITCH(i)); + + /* Save the FIFO state */ + st2 = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2); + st2_dl = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DL); + st2_dh = nv_rd32(priv, NV10_PGRAPH_FFINTFC_ST2_DH); + fifo_ptr = nv_rd32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR); + + for (i = 0; i < ARRAY_SIZE(fifo); i++) + fifo[i] = nv_rd32(priv, 0x4007a0 + 4 * i); + + /* Switch to the celsius subchannel */ + for (i = 0; i < 5; i++) + nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i), + nv_rd32(priv, NV10_PGRAPH_CTX_CACHE(subchan, i))); + nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13); + + /* Inject NV10TCL_DMA_VTXBUF */ + nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0); + nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, + 0x2c000000 | chid << 20 | subchan << 16 | 0x18c); + nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, inst); + nv_mask(priv, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); + nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); + nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); + + /* Restore the FIFO state */ + for (i = 0; i < ARRAY_SIZE(fifo); i++) + nv_wr32(priv, 0x4007a0 + 4 * i, fifo[i]); + + nv_wr32(priv, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr); + nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, st2); + nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl); + nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh); + + /* Restore the current ctx object */ + for (i = 0; i < 5; i++) + nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]); + nv_wr32(priv, NV10_PGRAPH_CTX_USER, ctx_user); +} + +static int +nv10_graph_load_context(struct nv10_graph_chan *chan, int chid) +{ + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + u32 inst; + int i; + + for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) + nv_wr32(priv, nv10_graph_ctx_regs[i], chan->nv10[i]); + + if (nv_device(priv)->chipset >= 0x17) { + for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) + nv_wr32(priv, nv17_graph_ctx_regs[i], chan->nv17[i]); + } + + nv10_graph_load_pipe(chan); + + inst = nv_rd32(priv, NV10_PGRAPH_GLOBALSTATE1) & 0xffff; + nv10_graph_load_dma_vtxbuf(chan, chid, inst); + + nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10010100); + nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, chid << 24); + nv_mask(priv, NV10_PGRAPH_FFINTFC_ST2, 0x30000000, 0x00000000); + return 0; +} + +static int +nv10_graph_unload_context(struct nv10_graph_chan *chan) +{ + struct nv10_graph_priv *priv = nv10_graph_priv(chan); + int i; + + for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) + chan->nv10[i] = nv_rd32(priv, nv10_graph_ctx_regs[i]); + + if (nv_device(priv)->chipset >= 0x17) { + for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) + chan->nv17[i] = nv_rd32(priv, nv17_graph_ctx_regs[i]); + } + + nv10_graph_save_pipe(chan); + + nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000000); + nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000); + return 0; +} + +static void +nv10_graph_context_switch(struct nv10_graph_priv *priv) +{ + struct nv10_graph_chan *prev = NULL; + struct nv10_graph_chan *next = NULL; + unsigned long flags; + int chid; + + spin_lock_irqsave(&priv->lock, flags); + nv04_graph_idle(priv); + + /* If previous context is valid, we need to save it */ + prev = nv10_graph_channel(priv); + if (prev) + nv10_graph_unload_context(prev); + + /* load context for next channel */ + chid = (nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; + next = priv->chan[chid]; + if (next) + nv10_graph_load_context(next, chid); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +#define NV_WRITE_CTX(reg, val) do { \ + int offset = nv10_graph_ctx_regs_find_offset(priv, reg); \ + if (offset > 0) \ + chan->nv10[offset] = val; \ + } while (0) + +#define NV17_WRITE_CTX(reg, val) do { \ + int offset = nv17_graph_ctx_regs_find_offset(priv, reg); \ + if (offset > 0) \ + chan->nv17[offset] = val; \ + } while (0) + +static int +nv10_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_fifo_chan *fifo = (void *)parent; + struct nv10_graph_priv *priv = (void *)engine; + struct nv10_graph_chan *chan; + unsigned long flags; + int ret; + + ret = nouveau_object_create(parent, engine, oclass, 0, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->chan[fifo->chid]) { + *pobject = nv_object(priv->chan[fifo->chid]); + atomic_inc(&(*pobject)->refcount); + spin_unlock_irqrestore(&priv->lock, flags); + nouveau_object_destroy(&chan->base); + return 1; + } + + NV_WRITE_CTX(0x00400e88, 0x08000000); + NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); + NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); + NV_WRITE_CTX(0x00400e10, 0x00001000); + NV_WRITE_CTX(0x00400e14, 0x00001000); + NV_WRITE_CTX(0x00400e30, 0x00080008); + NV_WRITE_CTX(0x00400e34, 0x00080008); + if (nv_device(priv)->chipset >= 0x17) { + /* is it really needed ??? */ + NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, + nv_rd32(priv, NV10_PGRAPH_DEBUG_4)); + NV17_WRITE_CTX(0x004006b0, nv_rd32(priv, 0x004006b0)); + NV17_WRITE_CTX(0x00400eac, 0x0fff0000); + NV17_WRITE_CTX(0x00400eb0, 0x0fff0000); + NV17_WRITE_CTX(0x00400ec0, 0x00000080); + NV17_WRITE_CTX(0x00400ed0, 0x00000080); + } + NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->chid << 24); + + nv10_graph_create_pipe(chan); + + priv->chan[fifo->chid] = chan; + chan->chid = fifo->chid; + spin_unlock_irqrestore(&priv->lock, flags); + return 0; +} + +static void +nv10_graph_context_dtor(struct nouveau_object *object) +{ + struct nv10_graph_priv *priv = (void *)object->engine; + struct nv10_graph_chan *chan = (void *)object; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + priv->chan[chan->chid] = NULL; + spin_unlock_irqrestore(&priv->lock, flags); + + nouveau_object_destroy(&chan->base); +} + +static int +nv10_graph_context_fini(struct nouveau_object *object, bool suspend) +{ + struct nv10_graph_priv *priv = (void *)object->engine; + struct nv10_graph_chan *chan = (void *)object; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); + if (nv10_graph_channel(priv) == chan) + nv10_graph_unload_context(chan); + nv_mask(priv, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); + spin_unlock_irqrestore(&priv->lock, flags); + + return nouveau_object_fini(&chan->base, suspend); +} + +static struct nouveau_oclass +nv10_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x10), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv10_graph_context_ctor, + .dtor = nv10_graph_context_dtor, + .init = nouveau_object_init, + .fini = nv10_graph_context_fini, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static void +nv10_graph_tile_prog(struct nouveau_engine *engine, int i) +{ + struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i]; + struct nouveau_fifo *pfifo = nouveau_fifo(engine); + struct nv10_graph_priv *priv = (void *)engine; + unsigned long flags; + + pfifo->pause(pfifo, &flags); + nv04_graph_idle(priv); + + nv_wr32(priv, NV10_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(priv, NV10_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(priv, NV10_PGRAPH_TILE(i), tile->addr); + + pfifo->start(pfifo, &flags); +} + +const struct nouveau_bitfield nv10_graph_intr_name[] = { + { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, + { NV_PGRAPH_INTR_ERROR, "ERROR" }, + {} +}; + +const struct nouveau_bitfield nv10_graph_nstatus[] = { + { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, + { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, + { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, + {} +}; + +static void +nv10_graph_intr(struct nouveau_subdev *subdev) +{ + struct nv10_graph_priv *priv = (void *)subdev; + struct nv10_graph_chan *chan = NULL; + struct nouveau_namedb *namedb = NULL; + struct nouveau_handle *handle = NULL; + u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); + u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); + u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR); + u32 chid = (addr & 0x01f00000) >> 20; + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff; + u32 show = stat; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + chan = priv->chan[chid]; + if (chan) + namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS); + spin_unlock_irqrestore(&priv->lock, flags); + + if (stat & NV_PGRAPH_INTR_ERROR) { + if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) { + handle = nouveau_namedb_get_class(namedb, class); + if (handle && !nv_call(handle->object, mthd, data)) + show &= ~NV_PGRAPH_INTR_ERROR; + } + } + + if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { + nv_wr32(priv, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); + stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + nv10_graph_context_switch(priv); + } + + nv_wr32(priv, NV03_PGRAPH_INTR, stat); + nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); + + if (show) { + nv_error(priv, ""); + nouveau_bitfield_print(nv10_graph_intr_name, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv10_graph_nstatus, nstatus); + printk("\n"); + nv_error(priv, "ch %d/%d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); + } + + nouveau_namedb_put(handle); +} + +static int +nv10_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv10_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv10_graph_intr; + nv_engine(priv)->cclass = &nv10_graph_cclass; + + if (nv_device(priv)->chipset <= 0x10) + nv_engine(priv)->sclass = nv10_graph_sclass; + else + if (nv_device(priv)->chipset < 0x17 || + nv_device(priv)->chipset == 0x1a) + nv_engine(priv)->sclass = nv15_graph_sclass; + else + nv_engine(priv)->sclass = nv17_graph_sclass; + + nv_engine(priv)->tile_prog = nv10_graph_tile_prog; + spin_lock_init(&priv->lock); + return 0; +} + +static void +nv10_graph_dtor(struct nouveau_object *object) +{ + struct nv10_graph_priv *priv = (void *)object; + nouveau_graph_destroy(&priv->base); +} + +static int +nv10_graph_init(struct nouveau_object *object) +{ + struct nouveau_engine *engine = nv_engine(object); + struct nouveau_fb *pfb = nouveau_fb(object); + struct nv10_graph_priv *priv = (void *)engine; + int ret, i; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF); + nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); + + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000); + nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x00118700); + /* nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */ + nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x25f92ad9); + nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31)); + + if (nv_device(priv)->chipset >= 0x17) { + nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x1f000000); + nv_wr32(priv, 0x400a10, 0x03ff3fb6); + nv_wr32(priv, 0x400838, 0x002f8684); + nv_wr32(priv, 0x40083c, 0x00115f3f); + nv_wr32(priv, 0x4006b0, 0x40000020); + } else { + nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00000000); + } + + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->tile.regions; i++) + engine->tile_prog(engine, i); + + nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000); + nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000); + nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000); + nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000); + nv_wr32(priv, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000); + nv_wr32(priv, NV10_PGRAPH_STATE, 0xFFFFFFFF); + + nv_mask(priv, NV10_PGRAPH_CTX_USER, 0xff000000, 0x1f000000); + nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100); + nv_wr32(priv, NV10_PGRAPH_FFINTFC_ST2, 0x08000000); + return 0; +} + +static int +nv10_graph_fini(struct nouveau_object *object, bool suspend) +{ + struct nv10_graph_priv *priv = (void *)object; + return nouveau_graph_fini(&priv->base, suspend); +} + +struct nouveau_oclass +nv10_graph_oclass = { + .handle = NV_ENGINE(GR, 0x10), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv10_graph_ctor, + .dtor = nv10_graph_dtor, + .init = nv10_graph_init, + .fini = nv10_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c new file mode 100644 index 00000000000..8f3f619c4a7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c @@ -0,0 +1,381 @@ +#include <core/os.h> +#include <core/class.h> +#include <core/engctx.h> +#include <core/handle.h> +#include <core/enum.h> + +#include <subdev/timer.h> +#include <subdev/fb.h> + +#include <engine/graph.h> +#include <engine/fifo.h> + +#include "nv20.h" +#include "regs.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static struct nouveau_oclass +nv20_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */ + { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */ + { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */ + { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */ + { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */ + { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */ + { 0x0096, &nv04_graph_ofuncs, NULL }, /* celcius */ + { 0x0097, &nv04_graph_ofuncs, NULL }, /* kelvin */ + { 0x009e, &nv04_graph_ofuncs, NULL }, /* swzsurf */ + { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */ + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv20_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_chan *chan; + int ret, i; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, + 0x37f0, 16, NVOBJ_FLAG_ZERO_ALLOC, + &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + chan->chid = nouveau_fifo_chan(parent)->chid; + + nv_wo32(chan, 0x0000, 0x00000001 | (chan->chid << 24)); + nv_wo32(chan, 0x033c, 0xffff0000); + nv_wo32(chan, 0x03a0, 0x0fff0000); + nv_wo32(chan, 0x03a4, 0x0fff0000); + nv_wo32(chan, 0x047c, 0x00000101); + nv_wo32(chan, 0x0490, 0x00000111); + nv_wo32(chan, 0x04a8, 0x44400000); + for (i = 0x04d4; i <= 0x04e0; i += 4) + nv_wo32(chan, i, 0x00030303); + for (i = 0x04f4; i <= 0x0500; i += 4) + nv_wo32(chan, i, 0x00080000); + for (i = 0x050c; i <= 0x0518; i += 4) + nv_wo32(chan, i, 0x01012000); + for (i = 0x051c; i <= 0x0528; i += 4) + nv_wo32(chan, i, 0x000105b8); + for (i = 0x052c; i <= 0x0538; i += 4) + nv_wo32(chan, i, 0x00080008); + for (i = 0x055c; i <= 0x0598; i += 4) + nv_wo32(chan, i, 0x07ff0000); + nv_wo32(chan, 0x05a4, 0x4b7fffff); + nv_wo32(chan, 0x05fc, 0x00000001); + nv_wo32(chan, 0x0604, 0x00004000); + nv_wo32(chan, 0x0610, 0x00000001); + nv_wo32(chan, 0x0618, 0x00040000); + nv_wo32(chan, 0x061c, 0x00010000); + for (i = 0x1c1c; i <= 0x248c; i += 16) { + nv_wo32(chan, (i + 0), 0x10700ff9); + nv_wo32(chan, (i + 4), 0x0436086c); + nv_wo32(chan, (i + 8), 0x000c001b); + } + nv_wo32(chan, 0x281c, 0x3f800000); + nv_wo32(chan, 0x2830, 0x3f800000); + nv_wo32(chan, 0x285c, 0x40000000); + nv_wo32(chan, 0x2860, 0x3f800000); + nv_wo32(chan, 0x2864, 0x3f000000); + nv_wo32(chan, 0x286c, 0x40000000); + nv_wo32(chan, 0x2870, 0x3f800000); + nv_wo32(chan, 0x2878, 0xbf800000); + nv_wo32(chan, 0x2880, 0xbf800000); + nv_wo32(chan, 0x34a4, 0x000fe000); + nv_wo32(chan, 0x3530, 0x000003f8); + nv_wo32(chan, 0x3540, 0x002fe000); + for (i = 0x355c; i <= 0x3578; i += 4) + nv_wo32(chan, i, 0x001c527c); + return 0; +} + +int +nv20_graph_context_init(struct nouveau_object *object) +{ + struct nv20_graph_priv *priv = (void *)object->engine; + struct nv20_graph_chan *chan = (void *)object; + int ret; + + ret = nouveau_graph_context_init(&chan->base); + if (ret) + return ret; + + nv_wo32(priv->ctxtab, chan->chid * 4, nv_gpuobj(chan)->addr >> 4); + return 0; +} + +int +nv20_graph_context_fini(struct nouveau_object *object, bool suspend) +{ + struct nv20_graph_priv *priv = (void *)object->engine; + struct nv20_graph_chan *chan = (void *)object; + int chid = -1; + + nv_mask(priv, 0x400720, 0x00000001, 0x00000000); + if (nv_rd32(priv, 0x400144) & 0x00010000) + chid = (nv_rd32(priv, 0x400148) & 0x1f000000) >> 24; + if (chan->chid == chid) { + nv_wr32(priv, 0x400784, nv_gpuobj(chan)->addr >> 4); + nv_wr32(priv, 0x400788, 0x00000002); + nv_wait(priv, 0x400700, 0xffffffff, 0x00000000); + nv_wr32(priv, 0x400144, 0x10000000); + nv_mask(priv, 0x400148, 0xff000000, 0x1f000000); + } + nv_mask(priv, 0x400720, 0x00000001, 0x00000001); + + nv_wo32(priv->ctxtab, chan->chid * 4, 0x00000000); + return nouveau_graph_context_fini(&chan->base, suspend); +} + +static struct nouveau_oclass +nv20_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x20), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv20_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = nv20_graph_context_init, + .fini = nv20_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +void +nv20_graph_tile_prog(struct nouveau_engine *engine, int i) +{ + struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i]; + struct nouveau_fifo *pfifo = nouveau_fifo(engine); + struct nv20_graph_priv *priv = (void *)engine; + unsigned long flags; + + pfifo->pause(pfifo, &flags); + nv04_graph_idle(priv); + + nv_wr32(priv, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(priv, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(priv, NV20_PGRAPH_TILE(i), tile->addr); + + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->limit); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->pitch); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->addr); + + if (nv_device(engine)->card_type == NV_20) { + nv_wr32(priv, NV20_PGRAPH_ZCOMP(i), tile->zcomp); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA, tile->zcomp); + } + + pfifo->start(pfifo, &flags); +} + +void +nv20_graph_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_engine *engine = nv_engine(subdev); + struct nouveau_object *engctx; + struct nouveau_handle *handle; + struct nv20_graph_priv *priv = (void *)subdev; + u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); + u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); + u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR); + u32 chid = (addr & 0x01f00000) >> 20; + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xfff; + u32 show = stat; + + engctx = nouveau_engctx_get(engine, chid); + if (stat & NV_PGRAPH_INTR_ERROR) { + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { + handle = nouveau_handle_get_class(engctx, class); + if (handle && !nv_call(handle->object, mthd, data)) + show &= ~NV_PGRAPH_INTR_ERROR; + nouveau_handle_put(handle); + } + } + + nv_wr32(priv, NV03_PGRAPH_INTR, stat); + nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); + + if (show) { + nv_info(priv, ""); + nouveau_bitfield_print(nv10_graph_intr_name, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv10_graph_nstatus, nstatus); + printk("\n"); + nv_info(priv, "ch %d/%d class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); + } + + nouveau_engctx_put(engctx); +} + +static int +nv20_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, + NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv20_graph_intr; + nv_engine(priv)->cclass = &nv20_graph_cclass; + nv_engine(priv)->sclass = nv20_graph_sclass; + nv_engine(priv)->tile_prog = nv20_graph_tile_prog; + return 0; +} + +void +nv20_graph_dtor(struct nouveau_object *object) +{ + struct nv20_graph_priv *priv = (void *)object; + nouveau_gpuobj_ref(NULL, &priv->ctxtab); + nouveau_graph_destroy(&priv->base); +} + +int +nv20_graph_init(struct nouveau_object *object) +{ + struct nouveau_engine *engine = nv_engine(object); + struct nv20_graph_priv *priv = (void *)engine; + struct nouveau_fb *pfb = nouveau_fb(object); + u32 tmp, vramsz; + int ret, i; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + nv_wr32(priv, NV20_PGRAPH_CHANNEL_CTX_TABLE, priv->ctxtab->addr >> 4); + + if (nv_device(priv)->chipset == 0x20) { + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x003d0000); + for (i = 0; i < 15; i++) + nv_wr32(priv, NV10_PGRAPH_RDI_DATA, 0x00000000); + nv_wait(priv, 0x400700, 0xffffffff, 0x00000000); + } else { + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x02c80000); + for (i = 0; i < 32; i++) + nv_wr32(priv, NV10_PGRAPH_RDI_DATA, 0x00000000); + nv_wait(priv, 0x400700, 0xffffffff, 0x00000000); + } + + nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF); + nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); + + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000); + nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x00118700); + nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */ + nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00000000); + nv_wr32(priv, 0x40009C , 0x00000040); + + if (nv_device(priv)->chipset >= 0x25) { + nv_wr32(priv, 0x400890, 0x00a8cfff); + nv_wr32(priv, 0x400610, 0x304B1FB6); + nv_wr32(priv, 0x400B80, 0x1cbd3883); + nv_wr32(priv, 0x400B84, 0x44000000); + nv_wr32(priv, 0x400098, 0x40000080); + nv_wr32(priv, 0x400B88, 0x000000ff); + + } else { + nv_wr32(priv, 0x400880, 0x0008c7df); + nv_wr32(priv, 0x400094, 0x00000005); + nv_wr32(priv, 0x400B80, 0x45eae20e); + nv_wr32(priv, 0x400B84, 0x24000000); + nv_wr32(priv, 0x400098, 0x00000040); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00E00038); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000030); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00E10038); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000030); + } + + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->tile.regions; i++) + engine->tile_prog(engine, i); + + nv_wr32(priv, 0x4009a0, nv_rd32(priv, 0x100324)); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA000C); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA, nv_rd32(priv, 0x100324)); + + nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100); + nv_wr32(priv, NV10_PGRAPH_STATE , 0xFFFFFFFF); + + tmp = nv_rd32(priv, NV10_PGRAPH_SURFACE) & 0x0007ff00; + nv_wr32(priv, NV10_PGRAPH_SURFACE, tmp); + tmp = nv_rd32(priv, NV10_PGRAPH_SURFACE) | 0x00020100; + nv_wr32(priv, NV10_PGRAPH_SURFACE, tmp); + + /* begin RAM config */ + vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1; + nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204)); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , nv_rd32(priv, 0x100200)); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0004); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , nv_rd32(priv, 0x100204)); + nv_wr32(priv, 0x400820, 0); + nv_wr32(priv, 0x400824, 0); + nv_wr32(priv, 0x400864, vramsz - 1); + nv_wr32(priv, 0x400868, vramsz - 1); + + /* interesting.. the below overwrites some of the tile setup above.. */ + nv_wr32(priv, 0x400B20, 0x00000000); + nv_wr32(priv, 0x400B04, 0xFFFFFFFF); + + nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_XMIN, 0); + nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_YMIN, 0); + nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); + nv_wr32(priv, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); + return 0; +} + +struct nouveau_oclass +nv20_graph_oclass = { + .handle = NV_ENGINE(GR, 0x20), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv20_graph_ctor, + .dtor = nv20_graph_dtor, + .init = nv20_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h new file mode 100644 index 00000000000..2bea7313e03 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.h @@ -0,0 +1,31 @@ +#ifndef __NV20_GRAPH_H__ +#define __NV20_GRAPH_H__ + +#include <core/enum.h> + +#include <engine/graph.h> +#include <engine/fifo.h> + +struct nv20_graph_priv { + struct nouveau_graph base; + struct nouveau_gpuobj *ctxtab; +}; + +struct nv20_graph_chan { + struct nouveau_graph_chan base; + int chid; +}; + +extern struct nouveau_oclass nv25_graph_sclass[]; +int nv20_graph_context_init(struct nouveau_object *); +int nv20_graph_context_fini(struct nouveau_object *, bool); + +void nv20_graph_tile_prog(struct nouveau_engine *, int); +void nv20_graph_intr(struct nouveau_subdev *); + +void nv20_graph_dtor(struct nouveau_object *); +int nv20_graph_init(struct nouveau_object *); + +int nv30_graph_init(struct nouveau_object *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c new file mode 100644 index 00000000000..b2b650dd8b2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c @@ -0,0 +1,167 @@ +#include <core/os.h> +#include <core/class.h> +#include <core/engctx.h> +#include <core/enum.h> + +#include <subdev/timer.h> +#include <subdev/fb.h> + +#include <engine/graph.h> + +#include "nv20.h" +#include "regs.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +struct nouveau_oclass +nv25_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */ + { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */ + { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */ + { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */ + { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */ + { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */ + { 0x0096, &nv04_graph_ofuncs, NULL }, /* celcius */ + { 0x009e, &nv04_graph_ofuncs, NULL }, /* swzsurf */ + { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */ + { 0x0597, &nv04_graph_ofuncs, NULL }, /* kelvin */ + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv25_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_chan *chan; + int ret, i; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x3724, + 16, NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + chan->chid = nouveau_fifo_chan(parent)->chid; + + nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24)); + nv_wo32(chan, 0x035c, 0xffff0000); + nv_wo32(chan, 0x03c0, 0x0fff0000); + nv_wo32(chan, 0x03c4, 0x0fff0000); + nv_wo32(chan, 0x049c, 0x00000101); + nv_wo32(chan, 0x04b0, 0x00000111); + nv_wo32(chan, 0x04c8, 0x00000080); + nv_wo32(chan, 0x04cc, 0xffff0000); + nv_wo32(chan, 0x04d0, 0x00000001); + nv_wo32(chan, 0x04e4, 0x44400000); + nv_wo32(chan, 0x04fc, 0x4b800000); + for (i = 0x0510; i <= 0x051c; i += 4) + nv_wo32(chan, i, 0x00030303); + for (i = 0x0530; i <= 0x053c; i += 4) + nv_wo32(chan, i, 0x00080000); + for (i = 0x0548; i <= 0x0554; i += 4) + nv_wo32(chan, i, 0x01012000); + for (i = 0x0558; i <= 0x0564; i += 4) + nv_wo32(chan, i, 0x000105b8); + for (i = 0x0568; i <= 0x0574; i += 4) + nv_wo32(chan, i, 0x00080008); + for (i = 0x0598; i <= 0x05d4; i += 4) + nv_wo32(chan, i, 0x07ff0000); + nv_wo32(chan, 0x05e0, 0x4b7fffff); + nv_wo32(chan, 0x0620, 0x00000080); + nv_wo32(chan, 0x0624, 0x30201000); + nv_wo32(chan, 0x0628, 0x70605040); + nv_wo32(chan, 0x062c, 0xb0a09080); + nv_wo32(chan, 0x0630, 0xf0e0d0c0); + nv_wo32(chan, 0x0664, 0x00000001); + nv_wo32(chan, 0x066c, 0x00004000); + nv_wo32(chan, 0x0678, 0x00000001); + nv_wo32(chan, 0x0680, 0x00040000); + nv_wo32(chan, 0x0684, 0x00010000); + for (i = 0x1b04; i <= 0x2374; i += 16) { + nv_wo32(chan, (i + 0), 0x10700ff9); + nv_wo32(chan, (i + 4), 0x0436086c); + nv_wo32(chan, (i + 8), 0x000c001b); + } + nv_wo32(chan, 0x2704, 0x3f800000); + nv_wo32(chan, 0x2718, 0x3f800000); + nv_wo32(chan, 0x2744, 0x40000000); + nv_wo32(chan, 0x2748, 0x3f800000); + nv_wo32(chan, 0x274c, 0x3f000000); + nv_wo32(chan, 0x2754, 0x40000000); + nv_wo32(chan, 0x2758, 0x3f800000); + nv_wo32(chan, 0x2760, 0xbf800000); + nv_wo32(chan, 0x2768, 0xbf800000); + nv_wo32(chan, 0x308c, 0x000fe000); + nv_wo32(chan, 0x3108, 0x000003f8); + nv_wo32(chan, 0x3468, 0x002fe000); + for (i = 0x3484; i <= 0x34a0; i += 4) + nv_wo32(chan, i, 0x001c527c); + return 0; +} + +static struct nouveau_oclass +nv25_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x25), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv25_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = nv20_graph_context_init, + .fini = nv20_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static int +nv25_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, + NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv20_graph_intr; + nv_engine(priv)->cclass = &nv25_graph_cclass; + nv_engine(priv)->sclass = nv25_graph_sclass; + nv_engine(priv)->tile_prog = nv20_graph_tile_prog; + return 0; +} + +struct nouveau_oclass +nv25_graph_oclass = { + .handle = NV_ENGINE(GR, 0x25), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv25_graph_ctor, + .dtor = nv20_graph_dtor, + .init = nv20_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c new file mode 100644 index 00000000000..700462fa0ae --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c @@ -0,0 +1,134 @@ +#include <core/os.h> +#include <core/class.h> +#include <core/engctx.h> +#include <core/enum.h> + +#include <subdev/timer.h> +#include <subdev/fb.h> + +#include <engine/graph.h> + +#include "nv20.h" +#include "regs.h" + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv2a_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_chan *chan; + int ret, i; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x36b0, + 16, NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + chan->chid = nouveau_fifo_chan(parent)->chid; + + nv_wo32(chan, 0x0000, 0x00000001 | (chan->chid << 24)); + nv_wo32(chan, 0x033c, 0xffff0000); + nv_wo32(chan, 0x03a0, 0x0fff0000); + nv_wo32(chan, 0x03a4, 0x0fff0000); + nv_wo32(chan, 0x047c, 0x00000101); + nv_wo32(chan, 0x0490, 0x00000111); + nv_wo32(chan, 0x04a8, 0x44400000); + for (i = 0x04d4; i <= 0x04e0; i += 4) + nv_wo32(chan, i, 0x00030303); + for (i = 0x04f4; i <= 0x0500; i += 4) + nv_wo32(chan, i, 0x00080000); + for (i = 0x050c; i <= 0x0518; i += 4) + nv_wo32(chan, i, 0x01012000); + for (i = 0x051c; i <= 0x0528; i += 4) + nv_wo32(chan, i, 0x000105b8); + for (i = 0x052c; i <= 0x0538; i += 4) + nv_wo32(chan, i, 0x00080008); + for (i = 0x055c; i <= 0x0598; i += 4) + nv_wo32(chan, i, 0x07ff0000); + nv_wo32(chan, 0x05a4, 0x4b7fffff); + nv_wo32(chan, 0x05fc, 0x00000001); + nv_wo32(chan, 0x0604, 0x00004000); + nv_wo32(chan, 0x0610, 0x00000001); + nv_wo32(chan, 0x0618, 0x00040000); + nv_wo32(chan, 0x061c, 0x00010000); + for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */ + nv_wo32(chan, (i + 0), 0x10700ff9); + nv_wo32(chan, (i + 4), 0x0436086c); + nv_wo32(chan, (i + 8), 0x000c001b); + } + nv_wo32(chan, 0x269c, 0x3f800000); + nv_wo32(chan, 0x26b0, 0x3f800000); + nv_wo32(chan, 0x26dc, 0x40000000); + nv_wo32(chan, 0x26e0, 0x3f800000); + nv_wo32(chan, 0x26e4, 0x3f000000); + nv_wo32(chan, 0x26ec, 0x40000000); + nv_wo32(chan, 0x26f0, 0x3f800000); + nv_wo32(chan, 0x26f8, 0xbf800000); + nv_wo32(chan, 0x2700, 0xbf800000); + nv_wo32(chan, 0x3024, 0x000fe000); + nv_wo32(chan, 0x30a0, 0x000003f8); + nv_wo32(chan, 0x33fc, 0x002fe000); + for (i = 0x341c; i <= 0x3438; i += 4) + nv_wo32(chan, i, 0x001c527c); + return 0; +} + +static struct nouveau_oclass +nv2a_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x2a), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv2a_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = nv20_graph_context_init, + .fini = nv20_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static int +nv2a_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, + NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv20_graph_intr; + nv_engine(priv)->cclass = &nv2a_graph_cclass; + nv_engine(priv)->sclass = nv25_graph_sclass; + nv_engine(priv)->tile_prog = nv20_graph_tile_prog; + return 0; +} + +struct nouveau_oclass +nv2a_graph_oclass = { + .handle = NV_ENGINE(GR, 0x2a), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv2a_graph_ctor, + .dtor = nv20_graph_dtor, + .init = nv20_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c new file mode 100644 index 00000000000..cedadaa92d3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c @@ -0,0 +1,238 @@ +#include <core/os.h> +#include <core/class.h> +#include <core/engctx.h> +#include <core/enum.h> + +#include <subdev/timer.h> +#include <subdev/fb.h> + +#include <engine/graph.h> + +#include "nv20.h" +#include "regs.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static struct nouveau_oclass +nv30_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */ + { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */ + { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */ + { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */ + { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */ + { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */ + { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */ + { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */ + { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */ + { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */ + { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */ + { 0x0397, &nv04_graph_ofuncs, NULL }, /* rankine */ + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv30_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_chan *chan; + int ret, i; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x5f48, + 16, NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + chan->chid = nouveau_fifo_chan(parent)->chid; + + nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24)); + nv_wo32(chan, 0x0410, 0x00000101); + nv_wo32(chan, 0x0424, 0x00000111); + nv_wo32(chan, 0x0428, 0x00000060); + nv_wo32(chan, 0x0444, 0x00000080); + nv_wo32(chan, 0x0448, 0xffff0000); + nv_wo32(chan, 0x044c, 0x00000001); + nv_wo32(chan, 0x0460, 0x44400000); + nv_wo32(chan, 0x048c, 0xffff0000); + for (i = 0x04e0; i < 0x04e8; i += 4) + nv_wo32(chan, i, 0x0fff0000); + nv_wo32(chan, 0x04ec, 0x00011100); + for (i = 0x0508; i < 0x0548; i += 4) + nv_wo32(chan, i, 0x07ff0000); + nv_wo32(chan, 0x0550, 0x4b7fffff); + nv_wo32(chan, 0x058c, 0x00000080); + nv_wo32(chan, 0x0590, 0x30201000); + nv_wo32(chan, 0x0594, 0x70605040); + nv_wo32(chan, 0x0598, 0xb8a89888); + nv_wo32(chan, 0x059c, 0xf8e8d8c8); + nv_wo32(chan, 0x05b0, 0xb0000000); + for (i = 0x0600; i < 0x0640; i += 4) + nv_wo32(chan, i, 0x00010588); + for (i = 0x0640; i < 0x0680; i += 4) + nv_wo32(chan, i, 0x00030303); + for (i = 0x06c0; i < 0x0700; i += 4) + nv_wo32(chan, i, 0x0008aae4); + for (i = 0x0700; i < 0x0740; i += 4) + nv_wo32(chan, i, 0x01012000); + for (i = 0x0740; i < 0x0780; i += 4) + nv_wo32(chan, i, 0x00080008); + nv_wo32(chan, 0x085c, 0x00040000); + nv_wo32(chan, 0x0860, 0x00010000); + for (i = 0x0864; i < 0x0874; i += 4) + nv_wo32(chan, i, 0x00040004); + for (i = 0x1f18; i <= 0x3088 ; i += 16) { + nv_wo32(chan, i + 0, 0x10700ff9); + nv_wo32(chan, i + 1, 0x0436086c); + nv_wo32(chan, i + 2, 0x000c001b); + } + for (i = 0x30b8; i < 0x30c8; i += 4) + nv_wo32(chan, i, 0x0000ffff); + nv_wo32(chan, 0x344c, 0x3f800000); + nv_wo32(chan, 0x3808, 0x3f800000); + nv_wo32(chan, 0x381c, 0x3f800000); + nv_wo32(chan, 0x3848, 0x40000000); + nv_wo32(chan, 0x384c, 0x3f800000); + nv_wo32(chan, 0x3850, 0x3f000000); + nv_wo32(chan, 0x3858, 0x40000000); + nv_wo32(chan, 0x385c, 0x3f800000); + nv_wo32(chan, 0x3864, 0xbf800000); + nv_wo32(chan, 0x386c, 0xbf800000); + return 0; +} + +static struct nouveau_oclass +nv30_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x30), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv30_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = nv20_graph_context_init, + .fini = nv20_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static int +nv30_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, + NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv20_graph_intr; + nv_engine(priv)->cclass = &nv30_graph_cclass; + nv_engine(priv)->sclass = nv30_graph_sclass; + nv_engine(priv)->tile_prog = nv20_graph_tile_prog; + return 0; +} + +int +nv30_graph_init(struct nouveau_object *object) +{ + struct nouveau_engine *engine = nv_engine(object); + struct nv20_graph_priv *priv = (void *)engine; + struct nouveau_fb *pfb = nouveau_fb(object); + int ret, i; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + nv_wr32(priv, NV20_PGRAPH_CHANNEL_CTX_TABLE, priv->ctxtab->addr >> 4); + + nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF); + nv_wr32(priv, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); + + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000); + nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x401287c0); + nv_wr32(priv, 0x400890, 0x01b463ff); + nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xf2de0475); + nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00008000); + nv_wr32(priv, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6); + nv_wr32(priv, 0x400B80, 0x1003d888); + nv_wr32(priv, 0x400B84, 0x0c000000); + nv_wr32(priv, 0x400098, 0x00000000); + nv_wr32(priv, 0x40009C, 0x0005ad00); + nv_wr32(priv, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */ + nv_wr32(priv, 0x4000a0, 0x00000000); + nv_wr32(priv, 0x4000a4, 0x00000008); + nv_wr32(priv, 0x4008a8, 0xb784a400); + nv_wr32(priv, 0x400ba0, 0x002f8685); + nv_wr32(priv, 0x400ba4, 0x00231f3f); + nv_wr32(priv, 0x4008a4, 0x40000020); + + if (nv_device(priv)->chipset == 0x34) { + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0004); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00200201); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0008); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000008); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000032); + nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00E00004); + nv_wr32(priv, NV10_PGRAPH_RDI_DATA , 0x00000002); + } + + nv_wr32(priv, 0x4000c0, 0x00000016); + + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->tile.regions; i++) + engine->tile_prog(engine, i); + + nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10000100); + nv_wr32(priv, NV10_PGRAPH_STATE , 0xFFFFFFFF); + nv_wr32(priv, 0x0040075c , 0x00000001); + + /* begin RAM config */ + /* vramsz = pci_resource_len(priv->dev->pdev, 0) - 1; */ + nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204)); + if (nv_device(priv)->chipset != 0x34) { + nv_wr32(priv, 0x400750, 0x00EA0000); + nv_wr32(priv, 0x400754, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x400750, 0x00EA0004); + nv_wr32(priv, 0x400754, nv_rd32(priv, 0x100204)); + } + return 0; +} + +struct nouveau_oclass +nv30_graph_oclass = { + .handle = NV_ENGINE(GR, 0x30), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv30_graph_ctor, + .dtor = nv20_graph_dtor, + .init = nv30_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c new file mode 100644 index 00000000000..273f6320027 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c @@ -0,0 +1,168 @@ +#include <core/os.h> +#include <core/class.h> +#include <core/engctx.h> +#include <core/enum.h> + +#include <subdev/timer.h> +#include <subdev/fb.h> + +#include <engine/graph.h> + +#include "nv20.h" +#include "regs.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static struct nouveau_oclass +nv34_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */ + { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */ + { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */ + { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */ + { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */ + { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */ + { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */ + { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */ + { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */ + { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */ + { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */ + { 0x0697, &nv04_graph_ofuncs, NULL }, /* rankine */ + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv34_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_chan *chan; + int ret, i; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x46dc, + 16, NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + chan->chid = nouveau_fifo_chan(parent)->chid; + + nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24)); + nv_wo32(chan, 0x040c, 0x01000101); + nv_wo32(chan, 0x0420, 0x00000111); + nv_wo32(chan, 0x0424, 0x00000060); + nv_wo32(chan, 0x0440, 0x00000080); + nv_wo32(chan, 0x0444, 0xffff0000); + nv_wo32(chan, 0x0448, 0x00000001); + nv_wo32(chan, 0x045c, 0x44400000); + nv_wo32(chan, 0x0480, 0xffff0000); + for (i = 0x04d4; i < 0x04dc; i += 4) + nv_wo32(chan, i, 0x0fff0000); + nv_wo32(chan, 0x04e0, 0x00011100); + for (i = 0x04fc; i < 0x053c; i += 4) + nv_wo32(chan, i, 0x07ff0000); + nv_wo32(chan, 0x0544, 0x4b7fffff); + nv_wo32(chan, 0x057c, 0x00000080); + nv_wo32(chan, 0x0580, 0x30201000); + nv_wo32(chan, 0x0584, 0x70605040); + nv_wo32(chan, 0x0588, 0xb8a89888); + nv_wo32(chan, 0x058c, 0xf8e8d8c8); + nv_wo32(chan, 0x05a0, 0xb0000000); + for (i = 0x05f0; i < 0x0630; i += 4) + nv_wo32(chan, i, 0x00010588); + for (i = 0x0630; i < 0x0670; i += 4) + nv_wo32(chan, i, 0x00030303); + for (i = 0x06b0; i < 0x06f0; i += 4) + nv_wo32(chan, i, 0x0008aae4); + for (i = 0x06f0; i < 0x0730; i += 4) + nv_wo32(chan, i, 0x01012000); + for (i = 0x0730; i < 0x0770; i += 4) + nv_wo32(chan, i, 0x00080008); + nv_wo32(chan, 0x0850, 0x00040000); + nv_wo32(chan, 0x0854, 0x00010000); + for (i = 0x0858; i < 0x0868; i += 4) + nv_wo32(chan, i, 0x00040004); + for (i = 0x15ac; i <= 0x271c ; i += 16) { + nv_wo32(chan, i + 0, 0x10700ff9); + nv_wo32(chan, i + 1, 0x0436086c); + nv_wo32(chan, i + 2, 0x000c001b); + } + for (i = 0x274c; i < 0x275c; i += 4) + nv_wo32(chan, i, 0x0000ffff); + nv_wo32(chan, 0x2ae0, 0x3f800000); + nv_wo32(chan, 0x2e9c, 0x3f800000); + nv_wo32(chan, 0x2eb0, 0x3f800000); + nv_wo32(chan, 0x2edc, 0x40000000); + nv_wo32(chan, 0x2ee0, 0x3f800000); + nv_wo32(chan, 0x2ee4, 0x3f000000); + nv_wo32(chan, 0x2eec, 0x40000000); + nv_wo32(chan, 0x2ef0, 0x3f800000); + nv_wo32(chan, 0x2ef8, 0xbf800000); + nv_wo32(chan, 0x2f00, 0xbf800000); + return 0; +} + +static struct nouveau_oclass +nv34_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x34), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv34_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = nv20_graph_context_init, + .fini = nv20_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static int +nv34_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, + NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv20_graph_intr; + nv_engine(priv)->cclass = &nv34_graph_cclass; + nv_engine(priv)->sclass = nv34_graph_sclass; + nv_engine(priv)->tile_prog = nv20_graph_tile_prog; + return 0; +} + +struct nouveau_oclass +nv34_graph_oclass = { + .handle = NV_ENGINE(GR, 0x34), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv34_graph_ctor, + .dtor = nv20_graph_dtor, + .init = nv30_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c new file mode 100644 index 00000000000..f40ee2116ee --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c @@ -0,0 +1,166 @@ +#include <core/os.h> +#include <core/class.h> +#include <core/engctx.h> +#include <core/enum.h> + +#include <subdev/timer.h> +#include <subdev/fb.h> + +#include "nv20.h" +#include "regs.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static struct nouveau_oclass +nv35_graph_sclass[] = { + { 0x0012, &nv04_graph_ofuncs, NULL }, /* beta1 */ + { 0x0019, &nv04_graph_ofuncs, NULL }, /* clip */ + { 0x0030, &nv04_graph_ofuncs, NULL }, /* null */ + { 0x0039, &nv04_graph_ofuncs, NULL }, /* m2mf */ + { 0x0043, &nv04_graph_ofuncs, NULL }, /* rop */ + { 0x0044, &nv04_graph_ofuncs, NULL }, /* patt */ + { 0x004a, &nv04_graph_ofuncs, NULL }, /* gdi */ + { 0x0062, &nv04_graph_ofuncs, NULL }, /* surf2d */ + { 0x0072, &nv04_graph_ofuncs, NULL }, /* beta4 */ + { 0x0089, &nv04_graph_ofuncs, NULL }, /* sifm */ + { 0x008a, &nv04_graph_ofuncs, NULL }, /* ifc */ + { 0x009f, &nv04_graph_ofuncs, NULL }, /* imageblit */ + { 0x0362, &nv04_graph_ofuncs, NULL }, /* surf2d (nv30) */ + { 0x0389, &nv04_graph_ofuncs, NULL }, /* sifm (nv30) */ + { 0x038a, &nv04_graph_ofuncs, NULL }, /* ifc (nv30) */ + { 0x039e, &nv04_graph_ofuncs, NULL }, /* swzsurf (nv30) */ + { 0x0497, &nv04_graph_ofuncs, NULL }, /* rankine */ + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv35_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_chan *chan; + int ret, i; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, 0x577c, + 16, NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + chan->chid = nouveau_fifo_chan(parent)->chid; + + nv_wo32(chan, 0x0028, 0x00000001 | (chan->chid << 24)); + nv_wo32(chan, 0x040c, 0x00000101); + nv_wo32(chan, 0x0420, 0x00000111); + nv_wo32(chan, 0x0424, 0x00000060); + nv_wo32(chan, 0x0440, 0x00000080); + nv_wo32(chan, 0x0444, 0xffff0000); + nv_wo32(chan, 0x0448, 0x00000001); + nv_wo32(chan, 0x045c, 0x44400000); + nv_wo32(chan, 0x0488, 0xffff0000); + for (i = 0x04dc; i < 0x04e4; i += 4) + nv_wo32(chan, i, 0x0fff0000); + nv_wo32(chan, 0x04e8, 0x00011100); + for (i = 0x0504; i < 0x0544; i += 4) + nv_wo32(chan, i, 0x07ff0000); + nv_wo32(chan, 0x054c, 0x4b7fffff); + nv_wo32(chan, 0x0588, 0x00000080); + nv_wo32(chan, 0x058c, 0x30201000); + nv_wo32(chan, 0x0590, 0x70605040); + nv_wo32(chan, 0x0594, 0xb8a89888); + nv_wo32(chan, 0x0598, 0xf8e8d8c8); + nv_wo32(chan, 0x05ac, 0xb0000000); + for (i = 0x0604; i < 0x0644; i += 4) + nv_wo32(chan, i, 0x00010588); + for (i = 0x0644; i < 0x0684; i += 4) + nv_wo32(chan, i, 0x00030303); + for (i = 0x06c4; i < 0x0704; i += 4) + nv_wo32(chan, i, 0x0008aae4); + for (i = 0x0704; i < 0x0744; i += 4) + nv_wo32(chan, i, 0x01012000); + for (i = 0x0744; i < 0x0784; i += 4) + nv_wo32(chan, i, 0x00080008); + nv_wo32(chan, 0x0860, 0x00040000); + nv_wo32(chan, 0x0864, 0x00010000); + for (i = 0x0868; i < 0x0878; i += 4) + nv_wo32(chan, i, 0x00040004); + for (i = 0x1f1c; i <= 0x308c ; i += 16) { + nv_wo32(chan, i + 0, 0x10700ff9); + nv_wo32(chan, i + 4, 0x0436086c); + nv_wo32(chan, i + 8, 0x000c001b); + } + for (i = 0x30bc; i < 0x30cc; i += 4) + nv_wo32(chan, i, 0x0000ffff); + nv_wo32(chan, 0x3450, 0x3f800000); + nv_wo32(chan, 0x380c, 0x3f800000); + nv_wo32(chan, 0x3820, 0x3f800000); + nv_wo32(chan, 0x384c, 0x40000000); + nv_wo32(chan, 0x3850, 0x3f800000); + nv_wo32(chan, 0x3854, 0x3f000000); + nv_wo32(chan, 0x385c, 0x40000000); + nv_wo32(chan, 0x3860, 0x3f800000); + nv_wo32(chan, 0x3868, 0xbf800000); + nv_wo32(chan, 0x3870, 0xbf800000); + return 0; +} + +static struct nouveau_oclass +nv35_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x35), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv35_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = nv20_graph_context_init, + .fini = nv20_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static int +nv35_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, + NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv20_graph_intr; + nv_engine(priv)->cclass = &nv35_graph_cclass; + nv_engine(priv)->sclass = nv35_graph_sclass; + nv_engine(priv)->tile_prog = nv20_graph_tile_prog; + return 0; +} + +struct nouveau_oclass +nv35_graph_oclass = { + .handle = NV_ENGINE(GR, 0x35), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv35_graph_ctor, + .dtor = nv20_graph_dtor, + .init = nv30_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c new file mode 100644 index 00000000000..8d0021049ec --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -0,0 +1,495 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include <core/os.h> +#include <core/class.h> +#include <core/handle.h> +#include <core/engctx.h> + +#include <subdev/fb.h> +#include <subdev/timer.h> + +#include <engine/graph.h> +#include <engine/fifo.h> + +#include "nv40.h" +#include "regs.h" + +struct nv40_graph_priv { + struct nouveau_graph base; + u32 size; +}; + +struct nv40_graph_chan { + struct nouveau_graph_chan base; +}; + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static int +nv40_graph_object_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_gpuobj *obj; + int ret; + + ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent, + 20, 16, 0, &obj); + *pobject = nv_object(obj); + if (ret) + return ret; + + nv_wo32(obj, 0x00, nv_mclass(obj)); + nv_wo32(obj, 0x04, 0x00000000); + nv_wo32(obj, 0x08, 0x00000000); +#ifdef __BIG_ENDIAN + nv_mo32(obj, 0x08, 0x01000000, 0x01000000); +#endif + nv_wo32(obj, 0x0c, 0x00000000); + nv_wo32(obj, 0x10, 0x00000000); + return 0; +} + +static struct nouveau_ofuncs +nv40_graph_ofuncs = { + .ctor = nv40_graph_object_ctor, + .dtor = _nouveau_gpuobj_dtor, + .init = _nouveau_gpuobj_init, + .fini = _nouveau_gpuobj_fini, + .rd32 = _nouveau_gpuobj_rd32, + .wr32 = _nouveau_gpuobj_wr32, +}; + +static struct nouveau_oclass +nv40_graph_sclass[] = { + { 0x0012, &nv40_graph_ofuncs, NULL }, /* beta1 */ + { 0x0019, &nv40_graph_ofuncs, NULL }, /* clip */ + { 0x0030, &nv40_graph_ofuncs, NULL }, /* null */ + { 0x0039, &nv40_graph_ofuncs, NULL }, /* m2mf */ + { 0x0043, &nv40_graph_ofuncs, NULL }, /* rop */ + { 0x0044, &nv40_graph_ofuncs, NULL }, /* patt */ + { 0x004a, &nv40_graph_ofuncs, NULL }, /* gdi */ + { 0x0062, &nv40_graph_ofuncs, NULL }, /* surf2d */ + { 0x0072, &nv40_graph_ofuncs, NULL }, /* beta4 */ + { 0x0089, &nv40_graph_ofuncs, NULL }, /* sifm */ + { 0x008a, &nv40_graph_ofuncs, NULL }, /* ifc */ + { 0x009f, &nv40_graph_ofuncs, NULL }, /* imageblit */ + { 0x3062, &nv40_graph_ofuncs, NULL }, /* surf2d (nv40) */ + { 0x3089, &nv40_graph_ofuncs, NULL }, /* sifm (nv40) */ + { 0x309e, &nv40_graph_ofuncs, NULL }, /* swzsurf (nv40) */ + { 0x4097, &nv40_graph_ofuncs, NULL }, /* curie */ + {}, +}; + +static struct nouveau_oclass +nv44_graph_sclass[] = { + { 0x0012, &nv40_graph_ofuncs, NULL }, /* beta1 */ + { 0x0019, &nv40_graph_ofuncs, NULL }, /* clip */ + { 0x0030, &nv40_graph_ofuncs, NULL }, /* null */ + { 0x0039, &nv40_graph_ofuncs, NULL }, /* m2mf */ + { 0x0043, &nv40_graph_ofuncs, NULL }, /* rop */ + { 0x0044, &nv40_graph_ofuncs, NULL }, /* patt */ + { 0x004a, &nv40_graph_ofuncs, NULL }, /* gdi */ + { 0x0062, &nv40_graph_ofuncs, NULL }, /* surf2d */ + { 0x0072, &nv40_graph_ofuncs, NULL }, /* beta4 */ + { 0x0089, &nv40_graph_ofuncs, NULL }, /* sifm */ + { 0x008a, &nv40_graph_ofuncs, NULL }, /* ifc */ + { 0x009f, &nv40_graph_ofuncs, NULL }, /* imageblit */ + { 0x3062, &nv40_graph_ofuncs, NULL }, /* surf2d (nv40) */ + { 0x3089, &nv40_graph_ofuncs, NULL }, /* sifm (nv40) */ + { 0x309e, &nv40_graph_ofuncs, NULL }, /* swzsurf (nv40) */ + { 0x4497, &nv40_graph_ofuncs, NULL }, /* curie */ + {}, +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv40_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv40_graph_priv *priv = (void *)engine; + struct nv40_graph_chan *chan; + int ret; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, + priv->size, 16, + NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + nv40_grctx_fill(nv_device(priv), nv_gpuobj(chan)); + nv_wo32(chan, 0x00000, nv_gpuobj(chan)->addr >> 4); + return 0; +} + +static int +nv40_graph_context_fini(struct nouveau_object *object, bool suspend) +{ + struct nv04_graph_priv *priv = (void *)object->engine; + struct nv04_graph_chan *chan = (void *)object; + u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; + int ret = 0; + + nv_mask(priv, 0x400720, 0x00000001, 0x00000000); + + if (nv_rd32(priv, 0x40032c) == inst) { + if (suspend) { + nv_wr32(priv, 0x400720, 0x00000000); + nv_wr32(priv, 0x400784, inst); + nv_mask(priv, 0x400310, 0x00000020, 0x00000020); + nv_mask(priv, 0x400304, 0x00000001, 0x00000001); + if (!nv_wait(priv, 0x400300, 0x00000001, 0x00000000)) { + u32 insn = nv_rd32(priv, 0x400308); + nv_warn(priv, "ctxprog timeout 0x%08x\n", insn); + ret = -EBUSY; + } + } + + nv_mask(priv, 0x40032c, 0x01000000, 0x00000000); + } + + if (nv_rd32(priv, 0x400330) == inst) + nv_mask(priv, 0x400330, 0x01000000, 0x00000000); + + nv_mask(priv, 0x400720, 0x00000001, 0x00000001); + return ret; +} + +static struct nouveau_oclass +nv40_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x40), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv40_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = _nouveau_graph_context_init, + .fini = nv40_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static void +nv40_graph_tile_prog(struct nouveau_engine *engine, int i) +{ + struct nouveau_fb_tile *tile = &nouveau_fb(engine)->tile.region[i]; + struct nouveau_fifo *pfifo = nouveau_fifo(engine); + struct nv40_graph_priv *priv = (void *)engine; + unsigned long flags; + + pfifo->pause(pfifo, &flags); + nv04_graph_idle(priv); + + switch (nv_device(priv)->chipset) { + case 0x40: + case 0x41: /* guess */ + case 0x42: + case 0x43: + case 0x45: /* guess */ + case 0x4e: + nv_wr32(priv, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(priv, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(priv, NV20_PGRAPH_TILE(i), tile->addr); + nv_wr32(priv, NV40_PGRAPH_TSIZE1(i), tile->pitch); + nv_wr32(priv, NV40_PGRAPH_TLIMIT1(i), tile->limit); + nv_wr32(priv, NV40_PGRAPH_TILE1(i), tile->addr); + break; + case 0x44: + case 0x4a: + nv_wr32(priv, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(priv, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(priv, NV20_PGRAPH_TILE(i), tile->addr); + break; + case 0x46: + case 0x47: + case 0x49: + case 0x4b: + case 0x4c: + case 0x67: + default: + nv_wr32(priv, NV47_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(priv, NV47_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(priv, NV47_PGRAPH_TILE(i), tile->addr); + nv_wr32(priv, NV40_PGRAPH_TSIZE1(i), tile->pitch); + nv_wr32(priv, NV40_PGRAPH_TLIMIT1(i), tile->limit); + nv_wr32(priv, NV40_PGRAPH_TILE1(i), tile->addr); + break; + } + + pfifo->start(pfifo, &flags); +} + +static void +nv40_graph_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_fifo *pfifo = nouveau_fifo(subdev); + struct nouveau_engine *engine = nv_engine(subdev); + struct nouveau_object *engctx; + struct nouveau_handle *handle = NULL; + struct nv40_graph_priv *priv = (void *)subdev; + u32 stat = nv_rd32(priv, NV03_PGRAPH_INTR); + u32 nsource = nv_rd32(priv, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(priv, NV03_PGRAPH_NSTATUS); + u32 inst = nv_rd32(priv, 0x40032c) & 0x000fffff; + u32 addr = nv_rd32(priv, NV04_PGRAPH_TRAPPED_ADDR); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(priv, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(priv, 0x400160 + subc * 4) & 0xffff; + u32 show = stat; + int chid; + + engctx = nouveau_engctx_get(engine, inst); + chid = pfifo->chid(pfifo, engctx); + + if (stat & NV_PGRAPH_INTR_ERROR) { + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { + handle = nouveau_handle_get_class(engctx, class); + if (handle && !nv_call(handle->object, mthd, data)) + show &= ~NV_PGRAPH_INTR_ERROR; + nouveau_handle_put(handle); + } + + if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) { + nv_mask(priv, 0x402000, 0, 0); + } + } + + nv_wr32(priv, NV03_PGRAPH_INTR, stat); + nv_wr32(priv, NV04_PGRAPH_FIFO, 0x00000001); + + if (show) { + nv_info(priv, ""); + nouveau_bitfield_print(nv10_graph_intr_name, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv10_graph_nstatus, nstatus); + printk("\n"); + nv_error(priv, "ch %d [0x%08x] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, inst << 4, subc, class, mthd, data); + } + + nouveau_engctx_put(engctx); +} + +static int +nv40_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv40_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00001000; + nv_subdev(priv)->intr = nv40_graph_intr; + nv_engine(priv)->cclass = &nv40_graph_cclass; + if (nv44_graph_class(priv)) + nv_engine(priv)->sclass = nv44_graph_sclass; + else + nv_engine(priv)->sclass = nv40_graph_sclass; + nv_engine(priv)->tile_prog = nv40_graph_tile_prog; + return 0; +} + +static int +nv40_graph_init(struct nouveau_object *object) +{ + struct nouveau_engine *engine = nv_engine(object); + struct nouveau_fb *pfb = nouveau_fb(object); + struct nv40_graph_priv *priv = (void *)engine; + int ret, i, j; + u32 vramsz; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + /* generate and upload context program */ + nv40_grctx_init(nv_device(priv), &priv->size); + + /* No context present currently */ + nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); + + nv_wr32(priv, NV03_PGRAPH_INTR , 0xFFFFFFFF); + nv_wr32(priv, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF); + + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); + nv_wr32(priv, NV04_PGRAPH_DEBUG_0, 0x00000000); + nv_wr32(priv, NV04_PGRAPH_DEBUG_1, 0x401287c0); + nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0xe0de8055); + nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x00008000); + nv_wr32(priv, NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f); + + nv_wr32(priv, NV10_PGRAPH_CTX_CONTROL, 0x10010100); + nv_wr32(priv, NV10_PGRAPH_STATE , 0xFFFFFFFF); + + j = nv_rd32(priv, 0x1540) & 0xff; + if (j) { + for (i = 0; !(j & 1); j >>= 1, i++) + ; + nv_wr32(priv, 0x405000, i); + } + + if (nv_device(priv)->chipset == 0x40) { + nv_wr32(priv, 0x4009b0, 0x83280fff); + nv_wr32(priv, 0x4009b4, 0x000000a0); + } else { + nv_wr32(priv, 0x400820, 0x83280eff); + nv_wr32(priv, 0x400824, 0x000000a0); + } + + switch (nv_device(priv)->chipset) { + case 0x40: + case 0x45: + nv_wr32(priv, 0x4009b8, 0x0078e366); + nv_wr32(priv, 0x4009bc, 0x0000014c); + break; + case 0x41: + case 0x42: /* pciid also 0x00Cx */ + /* case 0x0120: XXX (pciid) */ + nv_wr32(priv, 0x400828, 0x007596ff); + nv_wr32(priv, 0x40082c, 0x00000108); + break; + case 0x43: + nv_wr32(priv, 0x400828, 0x0072cb77); + nv_wr32(priv, 0x40082c, 0x00000108); + break; + case 0x44: + case 0x46: /* G72 */ + case 0x4a: + case 0x4c: /* G7x-based C51 */ + case 0x4e: + nv_wr32(priv, 0x400860, 0); + nv_wr32(priv, 0x400864, 0); + break; + case 0x47: /* G70 */ + case 0x49: /* G71 */ + case 0x4b: /* G73 */ + nv_wr32(priv, 0x400828, 0x07830610); + nv_wr32(priv, 0x40082c, 0x0000016A); + break; + default: + break; + } + + nv_wr32(priv, 0x400b38, 0x2ffff800); + nv_wr32(priv, 0x400b3c, 0x00006000); + + /* Tiling related stuff. */ + switch (nv_device(priv)->chipset) { + case 0x44: + case 0x4a: + nv_wr32(priv, 0x400bc4, 0x1003d888); + nv_wr32(priv, 0x400bbc, 0xb7a7b500); + break; + case 0x46: + nv_wr32(priv, 0x400bc4, 0x0000e024); + nv_wr32(priv, 0x400bbc, 0xb7a7b520); + break; + case 0x4c: + case 0x4e: + case 0x67: + nv_wr32(priv, 0x400bc4, 0x1003d888); + nv_wr32(priv, 0x400bbc, 0xb7a7b540); + break; + default: + break; + } + + /* Turn all the tiling regions off. */ + for (i = 0; i < pfb->tile.regions; i++) + engine->tile_prog(engine, i); + + /* begin RAM config */ + vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1; + switch (nv_device(priv)->chipset) { + case 0x40: + nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204)); + nv_wr32(priv, 0x4069A4, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x4069A8, nv_rd32(priv, 0x100204)); + nv_wr32(priv, 0x400820, 0); + nv_wr32(priv, 0x400824, 0); + nv_wr32(priv, 0x400864, vramsz); + nv_wr32(priv, 0x400868, vramsz); + break; + default: + switch (nv_device(priv)->chipset) { + case 0x41: + case 0x42: + case 0x43: + case 0x45: + case 0x4e: + case 0x44: + case 0x4a: + nv_wr32(priv, 0x4009F0, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x4009F4, nv_rd32(priv, 0x100204)); + break; + default: + nv_wr32(priv, 0x400DF0, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x400DF4, nv_rd32(priv, 0x100204)); + break; + } + nv_wr32(priv, 0x4069F0, nv_rd32(priv, 0x100200)); + nv_wr32(priv, 0x4069F4, nv_rd32(priv, 0x100204)); + nv_wr32(priv, 0x400840, 0); + nv_wr32(priv, 0x400844, 0); + nv_wr32(priv, 0x4008A0, vramsz); + nv_wr32(priv, 0x4008A4, vramsz); + break; + } + + return 0; +} + +struct nouveau_oclass +nv40_graph_oclass = { + .handle = NV_ENGINE(GR, 0x40), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv40_graph_ctor, + .dtor = _nouveau_graph_dtor, + .init = nv40_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h new file mode 100644 index 00000000000..d2ac975afc2 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h @@ -0,0 +1,21 @@ +#ifndef __NV40_GRAPH_H__ +#define __NV40_GRAPH_H__ + +/* returns 1 if device is one of the nv4x using the 0x4497 object class, + * helpful to determine a number of other hardware features + */ +static inline int +nv44_graph_class(void *priv) +{ + struct nouveau_device *device = nv_device(priv); + + if ((device->chipset & 0xf0) == 0x60) + return 1; + + return !(0x0baf & (1 << (device->chipset & 0x0f))); +} + +void nv40_grctx_init(struct nouveau_device *, u32 *size); +void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c new file mode 100644 index 00000000000..ab3b9dcaf47 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c @@ -0,0 +1,888 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include <core/os.h> +#include <core/class.h> +#include <core/handle.h> +#include <core/engctx.h> +#include <core/enum.h> + +#include <subdev/fb.h> +#include <subdev/vm.h> +#include <subdev/timer.h> + +#include <engine/fifo.h> +#include <engine/graph.h> + +#include "nv50.h" + +struct nv50_graph_priv { + struct nouveau_graph base; + spinlock_t lock; + u32 size; +}; + +struct nv50_graph_chan { + struct nouveau_graph_chan base; +}; + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static int +nv50_graph_object_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_gpuobj *obj; + int ret; + + ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent, + 16, 16, 0, &obj); + *pobject = nv_object(obj); + if (ret) + return ret; + + nv_wo32(obj, 0x00, nv_mclass(obj)); + nv_wo32(obj, 0x04, 0x00000000); + nv_wo32(obj, 0x08, 0x00000000); + nv_wo32(obj, 0x0c, 0x00000000); + return 0; +} + +static struct nouveau_ofuncs +nv50_graph_ofuncs = { + .ctor = nv50_graph_object_ctor, + .dtor = _nouveau_gpuobj_dtor, + .init = _nouveau_gpuobj_init, + .fini = _nouveau_gpuobj_fini, + .rd32 = _nouveau_gpuobj_rd32, + .wr32 = _nouveau_gpuobj_wr32, +}; + +static struct nouveau_oclass +nv50_graph_sclass[] = { + { 0x0030, &nv50_graph_ofuncs }, + { 0x502d, &nv50_graph_ofuncs }, + { 0x5039, &nv50_graph_ofuncs }, + { 0x5097, &nv50_graph_ofuncs }, + { 0x50c0, &nv50_graph_ofuncs }, + {} +}; + +static struct nouveau_oclass +nv84_graph_sclass[] = { + { 0x0030, &nv50_graph_ofuncs }, + { 0x502d, &nv50_graph_ofuncs }, + { 0x5039, &nv50_graph_ofuncs }, + { 0x50c0, &nv50_graph_ofuncs }, + { 0x8297, &nv50_graph_ofuncs }, + {} +}; + +static struct nouveau_oclass +nva0_graph_sclass[] = { + { 0x0030, &nv50_graph_ofuncs }, + { 0x502d, &nv50_graph_ofuncs }, + { 0x5039, &nv50_graph_ofuncs }, + { 0x50c0, &nv50_graph_ofuncs }, + { 0x8397, &nv50_graph_ofuncs }, + {} +}; + +static struct nouveau_oclass +nva3_graph_sclass[] = { + { 0x0030, &nv50_graph_ofuncs }, + { 0x502d, &nv50_graph_ofuncs }, + { 0x5039, &nv50_graph_ofuncs }, + { 0x50c0, &nv50_graph_ofuncs }, + { 0x8597, &nv50_graph_ofuncs }, + { 0x85c0, &nv50_graph_ofuncs }, + {} +}; + +static struct nouveau_oclass +nvaf_graph_sclass[] = { + { 0x0030, &nv50_graph_ofuncs }, + { 0x502d, &nv50_graph_ofuncs }, + { 0x5039, &nv50_graph_ofuncs }, + { 0x50c0, &nv50_graph_ofuncs }, + { 0x85c0, &nv50_graph_ofuncs }, + { 0x8697, &nv50_graph_ofuncs }, + {} +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static int +nv50_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv50_graph_priv *priv = (void *)engine; + struct nv50_graph_chan *chan; + int ret; + + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, + priv->size, 0, + NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + nv50_grctx_fill(nv_device(priv), nv_gpuobj(chan)); + return 0; +} + +static struct nouveau_oclass +nv50_graph_cclass = { + .handle = NV_ENGCTX(GR, 0x50), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_graph_context_ctor, + .dtor = _nouveau_graph_context_dtor, + .init = _nouveau_graph_context_init, + .fini = _nouveau_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static int +nv50_graph_tlb_flush(struct nouveau_engine *engine) +{ + nv50_vm_flush_engine(&engine->base, 0x00); + return 0; +} + +static int +nv84_graph_tlb_flush(struct nouveau_engine *engine) +{ + struct nouveau_timer *ptimer = nouveau_timer(engine); + struct nv50_graph_priv *priv = (void *)engine; + bool idle, timeout = false; + unsigned long flags; + u64 start; + u32 tmp; + + spin_lock_irqsave(&priv->lock, flags); + nv_mask(priv, 0x400500, 0x00000001, 0x00000000); + + start = ptimer->read(ptimer); + do { + idle = true; + + for (tmp = nv_rd32(priv, 0x400380); tmp && idle; tmp >>= 3) { + if ((tmp & 7) == 1) + idle = false; + } + + for (tmp = nv_rd32(priv, 0x400384); tmp && idle; tmp >>= 3) { + if ((tmp & 7) == 1) + idle = false; + } + + for (tmp = nv_rd32(priv, 0x400388); tmp && idle; tmp >>= 3) { + if ((tmp & 7) == 1) + idle = false; + } + } while (!idle && + !(timeout = ptimer->read(ptimer) - start > 2000000000)); + + if (timeout) { + nv_error(priv, "PGRAPH TLB flush idle timeout fail: " + "0x%08x 0x%08x 0x%08x 0x%08x\n", + nv_rd32(priv, 0x400700), nv_rd32(priv, 0x400380), + nv_rd32(priv, 0x400384), nv_rd32(priv, 0x400388)); + } + + nv50_vm_flush_engine(&engine->base, 0x00); + + nv_mask(priv, 0x400500, 0x00000001, 0x00000001); + spin_unlock_irqrestore(&priv->lock, flags); + return timeout ? -EBUSY : 0; +} + +static const struct nouveau_enum nv50_mp_exec_error_names[] = { + { 3, "STACK_UNDERFLOW", NULL }, + { 4, "QUADON_ACTIVE", NULL }, + { 8, "TIMEOUT", NULL }, + { 0x10, "INVALID_OPCODE", NULL }, + { 0x40, "BREAKPOINT", NULL }, + {} +}; + +static const struct nouveau_bitfield nv50_graph_trap_m2mf[] = { + { 0x00000001, "NOTIFY" }, + { 0x00000002, "IN" }, + { 0x00000004, "OUT" }, + {} +}; + +static const struct nouveau_bitfield nv50_graph_trap_vfetch[] = { + { 0x00000001, "FAULT" }, + {} +}; + +static const struct nouveau_bitfield nv50_graph_trap_strmout[] = { + { 0x00000001, "FAULT" }, + {} +}; + +static const struct nouveau_bitfield nv50_graph_trap_ccache[] = { + { 0x00000001, "FAULT" }, + {} +}; + +/* There must be a *lot* of these. Will take some time to gather them up. */ +const struct nouveau_enum nv50_data_error_names[] = { + { 0x00000003, "INVALID_OPERATION", NULL }, + { 0x00000004, "INVALID_VALUE", NULL }, + { 0x00000005, "INVALID_ENUM", NULL }, + { 0x00000008, "INVALID_OBJECT", NULL }, + { 0x00000009, "READ_ONLY_OBJECT", NULL }, + { 0x0000000a, "SUPERVISOR_OBJECT", NULL }, + { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT", NULL }, + { 0x0000000c, "INVALID_BITFIELD", NULL }, + { 0x0000000d, "BEGIN_END_ACTIVE", NULL }, + { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT", NULL }, + { 0x0000000f, "VIEWPORT_ID_NEEDS_GP", NULL }, + { 0x00000010, "RT_DOUBLE_BIND", NULL }, + { 0x00000011, "RT_TYPES_MISMATCH", NULL }, + { 0x00000012, "RT_LINEAR_WITH_ZETA", NULL }, + { 0x00000015, "FP_TOO_FEW_REGS", NULL }, + { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH", NULL }, + { 0x00000017, "RT_LINEAR_WITH_MSAA", NULL }, + { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT", NULL }, + { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT", NULL }, + { 0x0000001a, "RT_INVALID_ALIGNMENT", NULL }, + { 0x0000001b, "SAMPLER_OVER_LIMIT", NULL }, + { 0x0000001c, "TEXTURE_OVER_LIMIT", NULL }, + { 0x0000001e, "GP_TOO_MANY_OUTPUTS", NULL }, + { 0x0000001f, "RT_BPP128_WITH_MS8", NULL }, + { 0x00000021, "Z_OUT_OF_BOUNDS", NULL }, + { 0x00000023, "XY_OUT_OF_BOUNDS", NULL }, + { 0x00000024, "VP_ZERO_INPUTS", NULL }, + { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED", NULL }, + { 0x00000028, "CP_NO_REG_SPACE_STRIPED", NULL }, + { 0x00000029, "CP_NO_REG_SPACE_PACKED", NULL }, + { 0x0000002a, "CP_NOT_ENOUGH_WARPS", NULL }, + { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH", NULL }, + { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS", NULL }, + { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS", NULL }, + { 0x0000002e, "CP_NO_BLOCKDIM_LATCH", NULL }, + { 0x00000031, "ENG2D_FORMAT_MISMATCH", NULL }, + { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP", NULL }, + { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT", NULL }, + { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT", NULL }, + { 0x00000046, "LAYER_ID_NEEDS_GP", NULL }, + { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT", NULL }, + { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT", NULL }, + {} +}; + +static const struct nouveau_bitfield nv50_graph_intr_name[] = { + { 0x00000001, "NOTIFY" }, + { 0x00000002, "COMPUTE_QUERY" }, + { 0x00000010, "ILLEGAL_MTHD" }, + { 0x00000020, "ILLEGAL_CLASS" }, + { 0x00000040, "DOUBLE_NOTIFY" }, + { 0x00001000, "CONTEXT_SWITCH" }, + { 0x00010000, "BUFFER_NOTIFY" }, + { 0x00100000, "DATA_ERROR" }, + { 0x00200000, "TRAP" }, + { 0x01000000, "SINGLE_STEP" }, + {} +}; + +static void +nv50_priv_mp_trap(struct nv50_graph_priv *priv, int tpid, int display) +{ + u32 units = nv_rd32(priv, 0x1540); + u32 addr, mp10, status, pc, oplow, ophigh; + int i; + int mps = 0; + for (i = 0; i < 4; i++) { + if (!(units & 1 << (i+24))) + continue; + if (nv_device(priv)->chipset < 0xa0) + addr = 0x408200 + (tpid << 12) + (i << 7); + else + addr = 0x408100 + (tpid << 11) + (i << 7); + mp10 = nv_rd32(priv, addr + 0x10); + status = nv_rd32(priv, addr + 0x14); + if (!status) + continue; + if (display) { + nv_rd32(priv, addr + 0x20); + pc = nv_rd32(priv, addr + 0x24); + oplow = nv_rd32(priv, addr + 0x70); + ophigh = nv_rd32(priv, addr + 0x74); + nv_error(priv, "TRAP_MP_EXEC - " + "TP %d MP %d: ", tpid, i); + nouveau_enum_print(nv50_mp_exec_error_names, status); + printk(" at %06x warp %d, opcode %08x %08x\n", + pc&0xffffff, pc >> 24, + oplow, ophigh); + } + nv_wr32(priv, addr + 0x10, mp10); + nv_wr32(priv, addr + 0x14, 0); + mps++; + } + if (!mps && display) + nv_error(priv, "TRAP_MP_EXEC - TP %d: " + "No MPs claiming errors?\n", tpid); +} + +static void +nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old, + u32 ustatus_new, int display, const char *name) +{ + int tps = 0; + u32 units = nv_rd32(priv, 0x1540); + int i, r; + u32 ustatus_addr, ustatus; + for (i = 0; i < 16; i++) { + if (!(units & (1 << i))) + continue; + if (nv_device(priv)->chipset < 0xa0) + ustatus_addr = ustatus_old + (i << 12); + else + ustatus_addr = ustatus_new + (i << 11); + ustatus = nv_rd32(priv, ustatus_addr) & 0x7fffffff; + if (!ustatus) + continue; + tps++; + switch (type) { + case 6: /* texture error... unknown for now */ + if (display) { + nv_error(priv, "magic set %d:\n", i); + for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) + nv_error(priv, "\t0x%08x: 0x%08x\n", r, + nv_rd32(priv, r)); + } + break; + case 7: /* MP error */ + if (ustatus & 0x04030000) { + nv50_priv_mp_trap(priv, i, display); + ustatus &= ~0x04030000; + } + break; + case 8: /* TPDMA error */ + { + u32 e0c = nv_rd32(priv, ustatus_addr + 4); + u32 e10 = nv_rd32(priv, ustatus_addr + 8); + u32 e14 = nv_rd32(priv, ustatus_addr + 0xc); + u32 e18 = nv_rd32(priv, ustatus_addr + 0x10); + u32 e1c = nv_rd32(priv, ustatus_addr + 0x14); + u32 e20 = nv_rd32(priv, ustatus_addr + 0x18); + u32 e24 = nv_rd32(priv, ustatus_addr + 0x1c); + /* 2d engine destination */ + if (ustatus & 0x00000010) { + if (display) { + nv_error(priv, "TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n", + i, e14, e10); + nv_error(priv, "TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000010; + } + /* Render target */ + if (ustatus & 0x00000040) { + if (display) { + nv_error(priv, "TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n", + i, e14, e10); + nv_error(priv, "TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000040; + } + /* CUDA memory: l[], g[] or stack. */ + if (ustatus & 0x00000080) { + if (display) { + if (e18 & 0x80000000) { + /* g[] read fault? */ + nv_error(priv, "TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n", + i, e14, e10 | ((e18 >> 24) & 0x1f)); + e18 &= ~0x1f000000; + } else if (e18 & 0xc) { + /* g[] write fault? */ + nv_error(priv, "TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n", + i, e14, e10 | ((e18 >> 7) & 0x1f)); + e18 &= ~0x00000f80; + } else { + nv_error(priv, "TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n", + i, e14, e10); + } + nv_error(priv, "TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000080; + } + } + break; + } + if (ustatus) { + if (display) + nv_info(priv, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus); + } + nv_wr32(priv, ustatus_addr, 0xc0000000); + } + + if (!tps && display) + nv_info(priv, "%s - No TPs claiming errors?\n", name); +} + +static int +nv50_graph_trap_handler(struct nv50_graph_priv *priv, u32 display, + int chid, u64 inst) +{ + u32 status = nv_rd32(priv, 0x400108); + u32 ustatus; + + if (!status && display) { + nv_error(priv, "TRAP: no units reporting traps?\n"); + return 1; + } + + /* DISPATCH: Relays commands to other units and handles NOTIFY, + * COND, QUERY. If you get a trap from it, the command is still stuck + * in DISPATCH and you need to do something about it. */ + if (status & 0x001) { + ustatus = nv_rd32(priv, 0x400804) & 0x7fffffff; + if (!ustatus && display) { + nv_error(priv, "TRAP_DISPATCH - no ustatus?\n"); + } + + nv_wr32(priv, 0x400500, 0x00000000); + + /* Known to be triggered by screwed up NOTIFY and COND... */ + if (ustatus & 0x00000001) { + u32 addr = nv_rd32(priv, 0x400808); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 datal = nv_rd32(priv, 0x40080c); + u32 datah = nv_rd32(priv, 0x400810); + u32 class = nv_rd32(priv, 0x400814); + u32 r848 = nv_rd32(priv, 0x400848); + + nv_error(priv, "TRAP DISPATCH_FAULT\n"); + if (display && (addr & 0x80000000)) { + nv_error(priv, "ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x%08x " + "400808 0x%08x 400848 0x%08x\n", + chid, inst, subc, class, mthd, datah, + datal, addr, r848); + } else + if (display) { + nv_error(priv, "no stuck command?\n"); + } + + nv_wr32(priv, 0x400808, 0); + nv_wr32(priv, 0x4008e8, nv_rd32(priv, 0x4008e8) & 3); + nv_wr32(priv, 0x400848, 0); + ustatus &= ~0x00000001; + } + + if (ustatus & 0x00000002) { + u32 addr = nv_rd32(priv, 0x40084c); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(priv, 0x40085c); + u32 class = nv_rd32(priv, 0x400814); + + nv_error(priv, "TRAP DISPATCH_QUERY\n"); + if (display && (addr & 0x80000000)) { + nv_error(priv, "ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x 40084c 0x%08x\n", + chid, inst, subc, class, mthd, + data, addr); + } else + if (display) { + nv_error(priv, "no stuck command?\n"); + } + + nv_wr32(priv, 0x40084c, 0); + ustatus &= ~0x00000002; + } + + if (ustatus && display) { + nv_error(priv, "TRAP_DISPATCH (unknown " + "0x%08x)\n", ustatus); + } + + nv_wr32(priv, 0x400804, 0xc0000000); + nv_wr32(priv, 0x400108, 0x001); + status &= ~0x001; + if (!status) + return 0; + } + + /* M2MF: Memory to memory copy engine. */ + if (status & 0x002) { + u32 ustatus = nv_rd32(priv, 0x406800) & 0x7fffffff; + if (display) { + nv_error(priv, "TRAP_M2MF"); + nouveau_bitfield_print(nv50_graph_trap_m2mf, ustatus); + printk("\n"); + nv_error(priv, "TRAP_M2MF %08x %08x %08x %08x\n", + nv_rd32(priv, 0x406804), nv_rd32(priv, 0x406808), + nv_rd32(priv, 0x40680c), nv_rd32(priv, 0x406810)); + + } + + /* No sane way found yet -- just reset the bugger. */ + nv_wr32(priv, 0x400040, 2); + nv_wr32(priv, 0x400040, 0); + nv_wr32(priv, 0x406800, 0xc0000000); + nv_wr32(priv, 0x400108, 0x002); + status &= ~0x002; + } + + /* VFETCH: Fetches data from vertex buffers. */ + if (status & 0x004) { + u32 ustatus = nv_rd32(priv, 0x400c04) & 0x7fffffff; + if (display) { + nv_error(priv, "TRAP_VFETCH"); + nouveau_bitfield_print(nv50_graph_trap_vfetch, ustatus); + printk("\n"); + nv_error(priv, "TRAP_VFETCH %08x %08x %08x %08x\n", + nv_rd32(priv, 0x400c00), nv_rd32(priv, 0x400c08), + nv_rd32(priv, 0x400c0c), nv_rd32(priv, 0x400c10)); + } + + nv_wr32(priv, 0x400c04, 0xc0000000); + nv_wr32(priv, 0x400108, 0x004); + status &= ~0x004; + } + + /* STRMOUT: DirectX streamout / OpenGL transform feedback. */ + if (status & 0x008) { + ustatus = nv_rd32(priv, 0x401800) & 0x7fffffff; + if (display) { + nv_error(priv, "TRAP_STRMOUT"); + nouveau_bitfield_print(nv50_graph_trap_strmout, ustatus); + printk("\n"); + nv_error(priv, "TRAP_STRMOUT %08x %08x %08x %08x\n", + nv_rd32(priv, 0x401804), nv_rd32(priv, 0x401808), + nv_rd32(priv, 0x40180c), nv_rd32(priv, 0x401810)); + + } + + /* No sane way found yet -- just reset the bugger. */ + nv_wr32(priv, 0x400040, 0x80); + nv_wr32(priv, 0x400040, 0); + nv_wr32(priv, 0x401800, 0xc0000000); + nv_wr32(priv, 0x400108, 0x008); + status &= ~0x008; + } + + /* CCACHE: Handles code and c[] caches and fills them. */ + if (status & 0x010) { + ustatus = nv_rd32(priv, 0x405018) & 0x7fffffff; + if (display) { + nv_error(priv, "TRAP_CCACHE"); + nouveau_bitfield_print(nv50_graph_trap_ccache, ustatus); + printk("\n"); + nv_error(priv, "TRAP_CCACHE %08x %08x %08x %08x" + " %08x %08x %08x\n", + nv_rd32(priv, 0x405000), nv_rd32(priv, 0x405004), + nv_rd32(priv, 0x405008), nv_rd32(priv, 0x40500c), + nv_rd32(priv, 0x405010), nv_rd32(priv, 0x405014), + nv_rd32(priv, 0x40501c)); + + } + + nv_wr32(priv, 0x405018, 0xc0000000); + nv_wr32(priv, 0x400108, 0x010); + status &= ~0x010; + } + + /* Unknown, not seen yet... 0x402000 is the only trap status reg + * remaining, so try to handle it anyway. Perhaps related to that + * unknown DMA slot on tesla? */ + if (status & 0x20) { + ustatus = nv_rd32(priv, 0x402000) & 0x7fffffff; + if (display) + nv_error(priv, "TRAP_UNKC04 0x%08x\n", ustatus); + nv_wr32(priv, 0x402000, 0xc0000000); + /* no status modifiction on purpose */ + } + + /* TEXTURE: CUDA texturing units */ + if (status & 0x040) { + nv50_priv_tp_trap(priv, 6, 0x408900, 0x408600, display, + "TRAP_TEXTURE"); + nv_wr32(priv, 0x400108, 0x040); + status &= ~0x040; + } + + /* MP: CUDA execution engines. */ + if (status & 0x080) { + nv50_priv_tp_trap(priv, 7, 0x408314, 0x40831c, display, + "TRAP_MP"); + nv_wr32(priv, 0x400108, 0x080); + status &= ~0x080; + } + + /* TPDMA: Handles TP-initiated uncached memory accesses: + * l[], g[], stack, 2d surfaces, render targets. */ + if (status & 0x100) { + nv50_priv_tp_trap(priv, 8, 0x408e08, 0x408708, display, + "TRAP_TPDMA"); + nv_wr32(priv, 0x400108, 0x100); + status &= ~0x100; + } + + if (status) { + if (display) + nv_error(priv, "TRAP: unknown 0x%08x\n", status); + nv_wr32(priv, 0x400108, status); + } + + return 1; +} + +static void +nv50_graph_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_fifo *pfifo = nouveau_fifo(subdev); + struct nouveau_engine *engine = nv_engine(subdev); + struct nouveau_object *engctx; + struct nouveau_handle *handle = NULL; + struct nv50_graph_priv *priv = (void *)subdev; + u32 stat = nv_rd32(priv, 0x400100); + u32 inst = nv_rd32(priv, 0x40032c) & 0x0fffffff; + u32 addr = nv_rd32(priv, 0x400704); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(priv, 0x400708); + u32 class = nv_rd32(priv, 0x400814); + u32 show = stat; + int chid; + + engctx = nouveau_engctx_get(engine, inst); + chid = pfifo->chid(pfifo, engctx); + + if (stat & 0x00000010) { + handle = nouveau_handle_get_class(engctx, class); + if (handle && !nv_call(handle->object, mthd, data)) + show &= ~0x00000010; + nouveau_handle_put(handle); + } + + if (show & 0x00100000) { + u32 ecode = nv_rd32(priv, 0x400110); + nv_error(priv, "DATA_ERROR "); + nouveau_enum_print(nv50_data_error_names, ecode); + printk("\n"); + } + + if (stat & 0x00200000) { + if (!nv50_graph_trap_handler(priv, show, chid, (u64)inst << 12)) + show &= ~0x00200000; + } + + nv_wr32(priv, 0x400100, stat); + nv_wr32(priv, 0x400500, 0x00010001); + + if (show) { + nv_info(priv, ""); + nouveau_bitfield_print(nv50_graph_intr_name, show); + printk("\n"); + nv_error(priv, "ch %d [0x%010llx] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, (u64)inst << 12, subc, class, mthd, data); + nv50_fb_trap(nouveau_fb(priv), 1); + } + + if (nv_rd32(priv, 0x400824) & (1 << 31)) + nv_wr32(priv, 0x400824, nv_rd32(priv, 0x400824) & ~(1 << 31)); + + nouveau_engctx_put(engctx); +} + +static int +nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv50_graph_priv *priv; + int ret; + + ret = nouveau_graph_create(parent, engine, oclass, true, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00201000; + nv_subdev(priv)->intr = nv50_graph_intr; + nv_engine(priv)->cclass = &nv50_graph_cclass; + + switch (nv_device(priv)->chipset) { + case 0x50: + nv_engine(priv)->sclass = nv50_graph_sclass; + break; + case 0x84: + case 0x86: + case 0x92: + case 0x94: + case 0x96: + case 0x98: + nv_engine(priv)->sclass = nv84_graph_sclass; + break; + case 0xa0: + case 0xaa: + case 0xac: + nv_engine(priv)->sclass = nva0_graph_sclass; + break; + case 0xa3: + case 0xa5: + case 0xa8: + nv_engine(priv)->sclass = nva3_graph_sclass; + break; + case 0xaf: + nv_engine(priv)->sclass = nvaf_graph_sclass; + break; + + }; + + if (nv_device(priv)->chipset == 0x50 || + nv_device(priv)->chipset == 0xac) + nv_engine(priv)->tlb_flush = nv50_graph_tlb_flush; + else + nv_engine(priv)->tlb_flush = nv84_graph_tlb_flush; + + spin_lock_init(&priv->lock); + return 0; +} + +static int +nv50_graph_init(struct nouveau_object *object) +{ + struct nv50_graph_priv *priv = (void *)object; + int ret, units, i; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + /* NV_PGRAPH_DEBUG_3_HW_CTX_SWITCH_ENABLED */ + nv_wr32(priv, 0x40008c, 0x00000004); + + /* reset/enable traps and interrupts */ + nv_wr32(priv, 0x400804, 0xc0000000); + nv_wr32(priv, 0x406800, 0xc0000000); + nv_wr32(priv, 0x400c04, 0xc0000000); + nv_wr32(priv, 0x401800, 0xc0000000); + nv_wr32(priv, 0x405018, 0xc0000000); + nv_wr32(priv, 0x402000, 0xc0000000); + + units = nv_rd32(priv, 0x001540); + for (i = 0; i < 16; i++) { + if (!(units & (1 << i))) + continue; + + if (nv_device(priv)->chipset < 0xa0) { + nv_wr32(priv, 0x408900 + (i << 12), 0xc0000000); + nv_wr32(priv, 0x408e08 + (i << 12), 0xc0000000); + nv_wr32(priv, 0x408314 + (i << 12), 0xc0000000); + } else { + nv_wr32(priv, 0x408600 + (i << 11), 0xc0000000); + nv_wr32(priv, 0x408708 + (i << 11), 0xc0000000); + nv_wr32(priv, 0x40831c + (i << 11), 0xc0000000); + } + } + + nv_wr32(priv, 0x400108, 0xffffffff); + nv_wr32(priv, 0x400138, 0xffffffff); + nv_wr32(priv, 0x400100, 0xffffffff); + nv_wr32(priv, 0x40013c, 0xffffffff); + nv_wr32(priv, 0x400500, 0x00010001); + + /* upload context program, initialise ctxctl defaults */ + ret = nv50_grctx_init(nv_device(priv), &priv->size); + if (ret) + return ret; + + nv_wr32(priv, 0x400824, 0x00000000); + nv_wr32(priv, 0x400828, 0x00000000); + nv_wr32(priv, 0x40082c, 0x00000000); + nv_wr32(priv, 0x400830, 0x00000000); + nv_wr32(priv, 0x400724, 0x00000000); + nv_wr32(priv, 0x40032c, 0x00000000); + nv_wr32(priv, 0x400320, 4); /* CTXCTL_CMD = NEWCTXDMA */ + + /* some unknown zcull magic */ + switch (nv_device(priv)->chipset & 0xf0) { + case 0x50: + case 0x80: + case 0x90: + nv_wr32(priv, 0x402ca8, 0x00000800); + break; + case 0xa0: + default: + nv_wr32(priv, 0x402cc0, 0x00000000); + if (nv_device(priv)->chipset == 0xa0 || + nv_device(priv)->chipset == 0xaa || + nv_device(priv)->chipset == 0xac) { + nv_wr32(priv, 0x402ca8, 0x00000802); + } else { + nv_wr32(priv, 0x402cc0, 0x00000000); + nv_wr32(priv, 0x402ca8, 0x00000002); + } + + break; + } + + /* zero out zcull regions */ + for (i = 0; i < 8; i++) { + nv_wr32(priv, 0x402c20 + (i * 8), 0x00000000); + nv_wr32(priv, 0x402c24 + (i * 8), 0x00000000); + nv_wr32(priv, 0x402c28 + (i * 8), 0x00000000); + nv_wr32(priv, 0x402c2c + (i * 8), 0x00000000); + } + return 0; +} + +struct nouveau_oclass +nv50_graph_oclass = { + .handle = NV_ENGINE(GR, 0x50), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_graph_ctor, + .dtor = _nouveau_graph_dtor, + .init = nv50_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h new file mode 100644 index 00000000000..0505fb419bd --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.h @@ -0,0 +1,7 @@ +#ifndef __NV50_GRAPH_H__ +#define __NV50_GRAPH_H__ + +int nv50_grctx_init(struct nouveau_device *, u32 *size); +void nv50_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c new file mode 100644 index 00000000000..c62f2d0f5f0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -0,0 +1,955 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nvc0.h" +#include "fuc/hubnvc0.fuc.h" +#include "fuc/gpcnvc0.fuc.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static struct nouveau_oclass +nvc0_graph_sclass[] = { + { 0x902d, &nouveau_object_ofuncs }, + { 0x9039, &nouveau_object_ofuncs }, + { 0x9097, &nouveau_object_ofuncs }, + { 0x90c0, &nouveau_object_ofuncs }, + {} +}; + +static struct nouveau_oclass +nvc1_graph_sclass[] = { + { 0x902d, &nouveau_object_ofuncs }, + { 0x9039, &nouveau_object_ofuncs }, + { 0x9097, &nouveau_object_ofuncs }, + { 0x90c0, &nouveau_object_ofuncs }, + { 0x9197, &nouveau_object_ofuncs }, + {} +}; + +static struct nouveau_oclass +nvc8_graph_sclass[] = { + { 0x902d, &nouveau_object_ofuncs }, + { 0x9039, &nouveau_object_ofuncs }, + { 0x9097, &nouveau_object_ofuncs }, + { 0x90c0, &nouveau_object_ofuncs }, + { 0x9197, &nouveau_object_ofuncs }, + { 0x9297, &nouveau_object_ofuncs }, + {} +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +int +nvc0_graph_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *args, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_vm *vm = nouveau_client(parent)->vm; + struct nvc0_graph_priv *priv = (void *)engine; + struct nvc0_graph_data *data = priv->mmio_data; + struct nvc0_graph_mmio *mmio = priv->mmio_list; + struct nvc0_graph_chan *chan; + int ret, i; + + /* allocate memory for context, and fill with default values */ + ret = nouveau_graph_context_create(parent, engine, oclass, NULL, + priv->size, 0x100, + NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + /* allocate memory for a "mmio list" buffer that's used by the HUB + * fuc to modify some per-context register settings on first load + * of the context. + */ + ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x100, 0, &chan->mmio); + if (ret) + return ret; + + ret = nouveau_gpuobj_map_vm(nv_gpuobj(chan->mmio), vm, + NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS, + &chan->mmio_vma); + if (ret) + return ret; + + /* allocate buffers referenced by mmio list */ + for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) { + ret = nouveau_gpuobj_new(parent, NULL, data->size, data->align, + 0, &chan->data[i].mem); + if (ret) + return ret; + + ret = nouveau_gpuobj_map_vm(chan->data[i].mem, vm, data->access, + &chan->data[i].vma); + if (ret) + return ret; + + data++; + } + + /* finally, fill in the mmio list and point the context at it */ + for (i = 0; mmio->addr && i < ARRAY_SIZE(priv->mmio_list); i++) { + u32 addr = mmio->addr; + u32 data = mmio->data; + + if (mmio->shift) { + u64 info = chan->data[mmio->buffer].vma.offset; + data |= info >> mmio->shift; + } + + nv_wo32(chan->mmio, chan->mmio_nr++ * 4, addr); + nv_wo32(chan->mmio, chan->mmio_nr++ * 4, data); + mmio++; + } + + for (i = 0; i < priv->size; i += 4) + nv_wo32(chan, i, priv->data[i / 4]); + + if (!priv->firmware) { + nv_wo32(chan, 0x00, chan->mmio_nr / 2); + nv_wo32(chan, 0x04, chan->mmio_vma.offset >> 8); + } else { + nv_wo32(chan, 0xf4, 0); + nv_wo32(chan, 0xf8, 0); + nv_wo32(chan, 0x10, chan->mmio_nr / 2); + nv_wo32(chan, 0x14, lower_32_bits(chan->mmio_vma.offset)); + nv_wo32(chan, 0x18, upper_32_bits(chan->mmio_vma.offset)); + nv_wo32(chan, 0x1c, 1); + nv_wo32(chan, 0x20, 0); + nv_wo32(chan, 0x28, 0); + nv_wo32(chan, 0x2c, 0); + } + + return 0; +} + +void +nvc0_graph_context_dtor(struct nouveau_object *object) +{ + struct nvc0_graph_chan *chan = (void *)object; + int i; + + for (i = 0; i < ARRAY_SIZE(chan->data); i++) { + nouveau_gpuobj_unmap(&chan->data[i].vma); + nouveau_gpuobj_ref(NULL, &chan->data[i].mem); + } + + nouveau_gpuobj_unmap(&chan->mmio_vma); + nouveau_gpuobj_ref(NULL, &chan->mmio); + + nouveau_graph_context_destroy(&chan->base); +} + +static struct nouveau_oclass +nvc0_graph_cclass = { + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_graph_context_ctor, + .dtor = nvc0_graph_context_dtor, + .init = _nouveau_graph_context_init, + .fini = _nouveau_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static void +nvc0_graph_ctxctl_debug_unit(struct nvc0_graph_priv *priv, u32 base) +{ + nv_error(priv, "%06x - done 0x%08x\n", base, + nv_rd32(priv, base + 0x400)); + nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base, + nv_rd32(priv, base + 0x800), nv_rd32(priv, base + 0x804), + nv_rd32(priv, base + 0x808), nv_rd32(priv, base + 0x80c)); + nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base, + nv_rd32(priv, base + 0x810), nv_rd32(priv, base + 0x814), + nv_rd32(priv, base + 0x818), nv_rd32(priv, base + 0x81c)); +} + +void +nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *priv) +{ + u32 gpcnr = nv_rd32(priv, 0x409604) & 0xffff; + u32 gpc; + + nvc0_graph_ctxctl_debug_unit(priv, 0x409000); + for (gpc = 0; gpc < gpcnr; gpc++) + nvc0_graph_ctxctl_debug_unit(priv, 0x502000 + (gpc * 0x8000)); +} + +static void +nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) +{ + u32 ustat = nv_rd32(priv, 0x409c18); + + if (ustat & 0x00000001) + nv_error(priv, "CTXCTRL ucode error\n"); + if (ustat & 0x00080000) + nv_error(priv, "CTXCTRL watchdog timeout\n"); + if (ustat & ~0x00080001) + nv_error(priv, "CTXCTRL 0x%08x\n", ustat); + + nvc0_graph_ctxctl_debug(priv); + nv_wr32(priv, 0x409c20, ustat); +} + +static void +nvc0_graph_trap_tpc(struct nvc0_graph_priv *priv, int gpc, int tpc) +{ + u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0508)); + + if (stat & 0x00000001) { + u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0224)); + nv_error(priv, "GPC%d/TPC%d/TEX: 0x%08x\n", gpc, tpc, trap); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0224), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000001); + stat &= ~0x00000001; + } + + if (stat & 0x00000002) { + u32 trap0 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0644)); + u32 trap1 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x064c)); + nv_error(priv, "GPC%d/TPC%d/MP: 0x%08x 0x%08x\n", + gpc, tpc, trap0, trap1); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0644), 0x001ffffe); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x064c), 0x0000000f); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000002); + stat &= ~0x00000002; + } + + if (stat & 0x00000004) { + u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0084)); + nv_error(priv, "GPC%d/TPC%d/POLY: 0x%08x\n", gpc, tpc, trap); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0084), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000004); + stat &= ~0x00000004; + } + + if (stat & 0x00000008) { + u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x048c)); + nv_error(priv, "GPC%d/TPC%d/L1C: 0x%08x\n", gpc, tpc, trap); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x048c), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000008); + stat &= ~0x00000008; + } + + if (stat) { + nv_error(priv, "GPC%d/TPC%d/0x%08x: unknown\n", gpc, tpc, stat); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), stat); + } +} + +static void +nvc0_graph_trap_gpc(struct nvc0_graph_priv *priv, int gpc) +{ + u32 stat = nv_rd32(priv, GPC_UNIT(gpc, 0x2c90)); + int tpc; + + if (stat & 0x00000001) { + u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0420)); + nv_error(priv, "GPC%d/PROP: 0x%08x\n", gpc, trap); + nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000001); + stat &= ~0x00000001; + } + + if (stat & 0x00000002) { + u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0900)); + nv_error(priv, "GPC%d/ZCULL: 0x%08x\n", gpc, trap); + nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000002); + stat &= ~0x00000002; + } + + if (stat & 0x00000004) { + u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x1028)); + nv_error(priv, "GPC%d/CCACHE: 0x%08x\n", gpc, trap); + nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000004); + stat &= ~0x00000004; + } + + if (stat & 0x00000008) { + u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0824)); + nv_error(priv, "GPC%d/ESETUP: 0x%08x\n", gpc, trap); + nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000008); + stat &= ~0x00000009; + } + + for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { + u32 mask = 0x00010000 << tpc; + if (stat & mask) { + nvc0_graph_trap_tpc(priv, gpc, tpc); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), mask); + stat &= ~mask; + } + } + + if (stat) { + nv_error(priv, "GPC%d/0x%08x: unknown\n", gpc, stat); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), stat); + } +} + +static void +nvc0_graph_trap_intr(struct nvc0_graph_priv *priv) +{ + u32 trap = nv_rd32(priv, 0x400108); + int rop, gpc; + + if (trap & 0x00000001) { + u32 stat = nv_rd32(priv, 0x404000); + nv_error(priv, "DISPATCH 0x%08x\n", stat); + nv_wr32(priv, 0x404000, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000001); + trap &= ~0x00000001; + } + + if (trap & 0x00000002) { + u32 stat = nv_rd32(priv, 0x404600); + nv_error(priv, "M2MF 0x%08x\n", stat); + nv_wr32(priv, 0x404600, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000002); + trap &= ~0x00000002; + } + + if (trap & 0x00000008) { + u32 stat = nv_rd32(priv, 0x408030); + nv_error(priv, "CCACHE 0x%08x\n", stat); + nv_wr32(priv, 0x408030, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000008); + trap &= ~0x00000008; + } + + if (trap & 0x00000010) { + u32 stat = nv_rd32(priv, 0x405840); + nv_error(priv, "SHADER 0x%08x\n", stat); + nv_wr32(priv, 0x405840, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000010); + trap &= ~0x00000010; + } + + if (trap & 0x00000040) { + u32 stat = nv_rd32(priv, 0x40601c); + nv_error(priv, "UNK6 0x%08x\n", stat); + nv_wr32(priv, 0x40601c, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000040); + trap &= ~0x00000040; + } + + if (trap & 0x00000080) { + u32 stat = nv_rd32(priv, 0x404490); + nv_error(priv, "MACRO 0x%08x\n", stat); + nv_wr32(priv, 0x404490, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000080); + trap &= ~0x00000080; + } + + if (trap & 0x01000000) { + u32 stat = nv_rd32(priv, 0x400118); + for (gpc = 0; stat && gpc < priv->gpc_nr; gpc++) { + u32 mask = 0x00000001 << gpc; + if (stat & mask) { + nvc0_graph_trap_gpc(priv, gpc); + nv_wr32(priv, 0x400118, mask); + stat &= ~mask; + } + } + nv_wr32(priv, 0x400108, 0x01000000); + trap &= ~0x01000000; + } + + if (trap & 0x02000000) { + for (rop = 0; rop < priv->rop_nr; rop++) { + u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070)); + u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144)); + nv_error(priv, "ROP%d 0x%08x 0x%08x\n", + rop, statz, statc); + nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); + nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); + } + nv_wr32(priv, 0x400108, 0x02000000); + trap &= ~0x02000000; + } + + if (trap) { + nv_error(priv, "TRAP UNHANDLED 0x%08x\n", trap); + nv_wr32(priv, 0x400108, trap); + } +} + +static void +nvc0_graph_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_fifo *pfifo = nouveau_fifo(subdev); + struct nouveau_engine *engine = nv_engine(subdev); + struct nouveau_object *engctx; + struct nouveau_handle *handle; + struct nvc0_graph_priv *priv = (void *)subdev; + u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff; + u32 stat = nv_rd32(priv, 0x400100); + u32 addr = nv_rd32(priv, 0x400704); + u32 mthd = (addr & 0x00003ffc); + u32 subc = (addr & 0x00070000) >> 16; + u32 data = nv_rd32(priv, 0x400708); + u32 code = nv_rd32(priv, 0x400110); + u32 class = nv_rd32(priv, 0x404200 + (subc * 4)); + int chid; + + engctx = nouveau_engctx_get(engine, inst); + chid = pfifo->chid(pfifo, engctx); + + if (stat & 0x00000010) { + handle = nouveau_handle_get_class(engctx, class); + if (!handle || nv_call(handle->object, mthd, data)) { + nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x\n", + chid, inst << 12, subc, class, mthd, data); + } + nouveau_handle_put(handle); + nv_wr32(priv, 0x400100, 0x00000010); + stat &= ~0x00000010; + } + + if (stat & 0x00000020) { + nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d " + "class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, inst << 12, subc, class, mthd, data); + nv_wr32(priv, 0x400100, 0x00000020); + stat &= ~0x00000020; + } + + if (stat & 0x00100000) { + nv_error(priv, "DATA_ERROR ["); + nouveau_enum_print(nv50_data_error_names, code); + printk("] ch %d [0x%010llx] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, inst << 12, subc, class, mthd, data); + nv_wr32(priv, 0x400100, 0x00100000); + stat &= ~0x00100000; + } + + if (stat & 0x00200000) { + nv_error(priv, "TRAP ch %d [0x%010llx]\n", chid, inst << 12); + nvc0_graph_trap_intr(priv); + nv_wr32(priv, 0x400100, 0x00200000); + stat &= ~0x00200000; + } + + if (stat & 0x00080000) { + nvc0_graph_ctxctl_isr(priv); + nv_wr32(priv, 0x400100, 0x00080000); + stat &= ~0x00080000; + } + + if (stat) { + nv_error(priv, "unknown stat 0x%08x\n", stat); + nv_wr32(priv, 0x400100, stat); + } + + nv_wr32(priv, 0x400500, 0x00010001); + nouveau_engctx_put(engctx); +} + +int +nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname, + struct nvc0_graph_fuc *fuc) +{ + struct nouveau_device *device = nv_device(priv); + const struct firmware *fw; + char f[32]; + int ret; + + snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname); + ret = request_firmware(&fw, f, &device->pdev->dev); + if (ret) { + snprintf(f, sizeof(f), "nouveau/%s", fwname); + ret = request_firmware(&fw, f, &device->pdev->dev); + if (ret) { + nv_error(priv, "failed to load %s\n", fwname); + return ret; + } + } + + fuc->size = fw->size; + fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL); + release_firmware(fw); + return (fuc->data != NULL) ? 0 : -ENOMEM; +} + +static int +nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_device *device = nv_device(parent); + struct nvc0_graph_priv *priv; + bool enable = true; + int ret, i; + + switch (device->chipset) { + case 0xd9: /* known broken without binary driver firmware */ + enable = false; + break; + default: + break; + } + + ret = nouveau_graph_create(parent, engine, oclass, enable, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x18001000; + nv_subdev(priv)->intr = nvc0_graph_intr; + nv_engine(priv)->cclass = &nvc0_graph_cclass; + + if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { + nv_info(priv, "using external firmware\n"); + if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) || + nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) || + nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) || + nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad)) + return -EINVAL; + priv->firmware = true; + } + + switch (nvc0_graph_class(priv)) { + case 0x9097: + nv_engine(priv)->sclass = nvc0_graph_sclass; + break; + case 0x9197: + nv_engine(priv)->sclass = nvc1_graph_sclass; + break; + case 0x9297: + nv_engine(priv)->sclass = nvc8_graph_sclass; + break; + } + + ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8); + if (ret) + return ret; + + for (i = 0; i < 0x1000; i += 4) { + nv_wo32(priv->unk4188b4, i, 0x00000010); + nv_wo32(priv->unk4188b8, i, 0x00000010); + } + + priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16; + priv->gpc_nr = nv_rd32(priv, 0x409604) & 0x0000001f; + for (i = 0; i < priv->gpc_nr; i++) { + priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608)); + priv->tpc_total += priv->tpc_nr[i]; + } + + /*XXX: these need figuring out... though it might not even matter */ + switch (nv_device(priv)->chipset) { + case 0xc0: + if (priv->tpc_total == 11) { /* 465, 3/4/4/0, 4 */ + priv->magic_not_rop_nr = 0x07; + } else + if (priv->tpc_total == 14) { /* 470, 3/3/4/4, 5 */ + priv->magic_not_rop_nr = 0x05; + } else + if (priv->tpc_total == 15) { /* 480, 3/4/4/4, 6 */ + priv->magic_not_rop_nr = 0x06; + } + break; + case 0xc3: /* 450, 4/0/0/0, 2 */ + priv->magic_not_rop_nr = 0x03; + break; + case 0xc4: /* 460, 3/4/0/0, 4 */ + priv->magic_not_rop_nr = 0x01; + break; + case 0xc1: /* 2/0/0/0, 1 */ + priv->magic_not_rop_nr = 0x01; + break; + case 0xc8: /* 4/4/3/4, 5 */ + priv->magic_not_rop_nr = 0x06; + break; + case 0xce: /* 4/4/0/0, 4 */ + priv->magic_not_rop_nr = 0x03; + break; + case 0xcf: /* 4/0/0/0, 3 */ + priv->magic_not_rop_nr = 0x03; + break; + case 0xd9: /* 1/0/0/0, 1 */ + priv->magic_not_rop_nr = 0x01; + break; + } + + return 0; +} + +static void +nvc0_graph_dtor_fw(struct nvc0_graph_fuc *fuc) +{ + if (fuc->data) { + kfree(fuc->data); + fuc->data = NULL; + } +} + +void +nvc0_graph_dtor(struct nouveau_object *object) +{ + struct nvc0_graph_priv *priv = (void *)object; + + if (priv->data) + kfree(priv->data); + + nvc0_graph_dtor_fw(&priv->fuc409c); + nvc0_graph_dtor_fw(&priv->fuc409d); + nvc0_graph_dtor_fw(&priv->fuc41ac); + nvc0_graph_dtor_fw(&priv->fuc41ad); + + nouveau_gpuobj_ref(NULL, &priv->unk4188b8); + nouveau_gpuobj_ref(NULL, &priv->unk4188b4); + + nouveau_graph_destroy(&priv->base); +} + +static void +nvc0_graph_init_obj418880(struct nvc0_graph_priv *priv) +{ + int i; + + nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000); + nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000); + for (i = 0; i < 4; i++) + nv_wr32(priv, GPC_BCAST(0x0888) + (i * 4), 0x00000000); + nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8); + nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8); +} + +static void +nvc0_graph_init_regs(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x400080, 0x003083c2); + nv_wr32(priv, 0x400088, 0x00006fe7); + nv_wr32(priv, 0x40008c, 0x00000000); + nv_wr32(priv, 0x400090, 0x00000030); + nv_wr32(priv, 0x40013c, 0x013901f7); + nv_wr32(priv, 0x400140, 0x00000100); + nv_wr32(priv, 0x400144, 0x00000000); + nv_wr32(priv, 0x400148, 0x00000110); + nv_wr32(priv, 0x400138, 0x00000000); + nv_wr32(priv, 0x400130, 0x00000000); + nv_wr32(priv, 0x400134, 0x00000000); + nv_wr32(priv, 0x400124, 0x00000002); +} + +static void +nvc0_graph_init_gpc_0(struct nvc0_graph_priv *priv) +{ + const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total); + u32 data[TPC_MAX / 8]; + u8 tpcnr[GPC_MAX]; + int i, gpc, tpc; + + nv_wr32(priv, TPC_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */ + + /* + * TP ROP UNKVAL(magic_not_rop_nr) + * 450: 4/0/0/0 2 3 + * 460: 3/4/0/0 4 1 + * 465: 3/4/4/0 4 7 + * 470: 3/3/4/4 5 5 + * 480: 3/4/4/4 6 6 + */ + + memset(data, 0x00, sizeof(data)); + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + for (i = 0, gpc = -1; i < priv->tpc_total; i++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; + + data[i / 8] |= tpc << ((i % 8) * 4); + } + + nv_wr32(priv, GPC_BCAST(0x0980), data[0]); + nv_wr32(priv, GPC_BCAST(0x0984), data[1]); + nv_wr32(priv, GPC_BCAST(0x0988), data[2]); + nv_wr32(priv, GPC_BCAST(0x098c), data[3]); + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + nv_wr32(priv, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 | + priv->tpc_nr[gpc]); + nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total); + nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918); + } + + nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918); + nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800)); +} + +static void +nvc0_graph_init_units(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x409c24, 0x000f0000); + nv_wr32(priv, 0x404000, 0xc0000000); /* DISPATCH */ + nv_wr32(priv, 0x404600, 0xc0000000); /* M2MF */ + nv_wr32(priv, 0x408030, 0xc0000000); + nv_wr32(priv, 0x40601c, 0xc0000000); + nv_wr32(priv, 0x404490, 0xc0000000); /* MACRO */ + nv_wr32(priv, 0x406018, 0xc0000000); + nv_wr32(priv, 0x405840, 0xc0000000); + nv_wr32(priv, 0x405844, 0x00ffffff); + nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008); + nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000); +} + +static void +nvc0_graph_init_gpc_1(struct nvc0_graph_priv *priv) +{ + int gpc, tpc; + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000); + for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); + } + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff); + } +} + +static void +nvc0_graph_init_rop(struct nvc0_graph_priv *priv) +{ + int rop; + + for (rop = 0; rop < priv->rop_nr; rop++) { + nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); + nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); + nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff); + nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff); + } +} + +void +nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base, + struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data) +{ + int i; + + nv_wr32(priv, fuc_base + 0x01c0, 0x01000000); + for (i = 0; i < data->size / 4; i++) + nv_wr32(priv, fuc_base + 0x01c4, data->data[i]); + + nv_wr32(priv, fuc_base + 0x0180, 0x01000000); + for (i = 0; i < code->size / 4; i++) { + if ((i & 0x3f) == 0) + nv_wr32(priv, fuc_base + 0x0188, i >> 6); + nv_wr32(priv, fuc_base + 0x0184, code->data[i]); + } +} + +static int +nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv) +{ + u32 r000260; + int i; + + if (priv->firmware) { + /* load fuc microcode */ + r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, + &priv->fuc409d); + nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, + &priv->fuc41ad); + nv_wr32(priv, 0x000260, r000260); + + /* start both of them running */ + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x41a10c, 0x00000000); + nv_wr32(priv, 0x40910c, 0x00000000); + nv_wr32(priv, 0x41a100, 0x00000002); + nv_wr32(priv, 0x409100, 0x00000002); + if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001)) + nv_info(priv, "0x409800 wait failed\n"); + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x7fffffff); + nv_wr32(priv, 0x409504, 0x00000021); + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x00000000); + nv_wr32(priv, 0x409504, 0x00000010); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x10 timeout\n"); + return -EBUSY; + } + priv->size = nv_rd32(priv, 0x409800); + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x00000000); + nv_wr32(priv, 0x409504, 0x00000016); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x16 timeout\n"); + return -EBUSY; + } + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x00000000); + nv_wr32(priv, 0x409504, 0x00000025); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x25 timeout\n"); + return -EBUSY; + } + + if (priv->data == NULL) { + int ret = nvc0_grctx_generate(priv); + if (ret) { + nv_error(priv, "failed to construct context\n"); + return ret; + } + } + + return 0; + } + + /* load HUB microcode */ + r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nv_wr32(priv, 0x4091c0, 0x01000000); + for (i = 0; i < sizeof(nvc0_grhub_data) / 4; i++) + nv_wr32(priv, 0x4091c4, nvc0_grhub_data[i]); + + nv_wr32(priv, 0x409180, 0x01000000); + for (i = 0; i < sizeof(nvc0_grhub_code) / 4; i++) { + if ((i & 0x3f) == 0) + nv_wr32(priv, 0x409188, i >> 6); + nv_wr32(priv, 0x409184, nvc0_grhub_code[i]); + } + + /* load GPC microcode */ + nv_wr32(priv, 0x41a1c0, 0x01000000); + for (i = 0; i < sizeof(nvc0_grgpc_data) / 4; i++) + nv_wr32(priv, 0x41a1c4, nvc0_grgpc_data[i]); + + nv_wr32(priv, 0x41a180, 0x01000000); + for (i = 0; i < sizeof(nvc0_grgpc_code) / 4; i++) { + if ((i & 0x3f) == 0) + nv_wr32(priv, 0x41a188, i >> 6); + nv_wr32(priv, 0x41a184, nvc0_grgpc_code[i]); + } + nv_wr32(priv, 0x000260, r000260); + + /* start HUB ucode running, it'll init the GPCs */ + nv_wr32(priv, 0x409800, nv_device(priv)->chipset); + nv_wr32(priv, 0x40910c, 0x00000000); + nv_wr32(priv, 0x409100, 0x00000002); + if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) { + nv_error(priv, "HUB_INIT timed out\n"); + nvc0_graph_ctxctl_debug(priv); + return -EBUSY; + } + + priv->size = nv_rd32(priv, 0x409804); + if (priv->data == NULL) { + int ret = nvc0_grctx_generate(priv); + if (ret) { + nv_error(priv, "failed to construct context\n"); + return ret; + } + } + + return 0; +} + +static int +nvc0_graph_init(struct nouveau_object *object) +{ + struct nvc0_graph_priv *priv = (void *)object; + int ret; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + nvc0_graph_init_obj418880(priv); + nvc0_graph_init_regs(priv); + /*nvc0_graph_init_unitplemented_magics(priv);*/ + nvc0_graph_init_gpc_0(priv); + /*nvc0_graph_init_unitplemented_c242(priv);*/ + + nv_wr32(priv, 0x400500, 0x00010001); + nv_wr32(priv, 0x400100, 0xffffffff); + nv_wr32(priv, 0x40013c, 0xffffffff); + + nvc0_graph_init_units(priv); + nvc0_graph_init_gpc_1(priv); + nvc0_graph_init_rop(priv); + + nv_wr32(priv, 0x400108, 0xffffffff); + nv_wr32(priv, 0x400138, 0xffffffff); + nv_wr32(priv, 0x400118, 0xffffffff); + nv_wr32(priv, 0x400130, 0xffffffff); + nv_wr32(priv, 0x40011c, 0xffffffff); + nv_wr32(priv, 0x400134, 0xffffffff); + nv_wr32(priv, 0x400054, 0x34ce3464); + + ret = nvc0_graph_init_ctxctl(priv); + if (ret) + return ret; + + return 0; +} + +struct nouveau_oclass +nvc0_graph_oclass = { + .handle = NV_ENGINE(GR, 0xc0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_graph_ctor, + .dtor = nvc0_graph_dtor, + .init = nvc0_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h new file mode 100644 index 00000000000..18d2210e12e --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h @@ -0,0 +1,171 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#ifndef __NVC0_GRAPH_H__ +#define __NVC0_GRAPH_H__ + +#include <core/client.h> +#include <core/handle.h> +#include <core/gpuobj.h> +#include <core/option.h> + +#include <subdev/fb.h> +#include <subdev/vm.h> +#include <subdev/bar.h> +#include <subdev/timer.h> + +#include <engine/fifo.h> +#include <engine/graph.h> + +#define GPC_MAX 4 +#define TPC_MAX 32 + +#define ROP_BCAST(r) (0x408800 + (r)) +#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r)) +#define GPC_BCAST(r) (0x418000 + (r)) +#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r)) +#define TPC_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) + +struct nvc0_graph_data { + u32 size; + u32 align; + u32 access; +}; + +struct nvc0_graph_mmio { + u32 addr; + u32 data; + u32 shift; + u32 buffer; +}; + +struct nvc0_graph_fuc { + u32 *data; + u32 size; +}; + +struct nvc0_graph_priv { + struct nouveau_graph base; + + struct nvc0_graph_fuc fuc409c; + struct nvc0_graph_fuc fuc409d; + struct nvc0_graph_fuc fuc41ac; + struct nvc0_graph_fuc fuc41ad; + bool firmware; + + u8 rop_nr; + u8 gpc_nr; + u8 tpc_nr[GPC_MAX]; + u8 tpc_total; + + struct nouveau_gpuobj *unk4188b4; + struct nouveau_gpuobj *unk4188b8; + + struct nvc0_graph_data mmio_data[4]; + struct nvc0_graph_mmio mmio_list[4096/8]; + u32 size; + u32 *data; + + u8 magic_not_rop_nr; +}; + +struct nvc0_graph_chan { + struct nouveau_graph_chan base; + + struct nouveau_gpuobj *mmio; + struct nouveau_vma mmio_vma; + int mmio_nr; + struct { + struct nouveau_gpuobj *mem; + struct nouveau_vma vma; + } data[4]; +}; + +static inline u32 +nvc0_graph_class(void *obj) +{ + struct nouveau_device *device = nv_device(obj); + + switch (device->chipset) { + case 0xc0: + case 0xc3: + case 0xc4: + case 0xce: /* guess, mmio trace shows only 0x9097 state */ + case 0xcf: /* guess, mmio trace shows only 0x9097 state */ + return 0x9097; + case 0xc1: + return 0x9197; + case 0xc8: + case 0xd9: + return 0x9297; + case 0xe4: + case 0xe7: + return 0xa097; + default: + return 0; + } +} + +void nv_icmd(struct nvc0_graph_priv *priv, u32 icmd, u32 data); + +static inline void +nv_mthd(struct nvc0_graph_priv *priv, u32 class, u32 mthd, u32 data) +{ + nv_wr32(priv, 0x40448c, data); + nv_wr32(priv, 0x404488, 0x80000000 | (mthd << 14) | class); +} + +struct nvc0_grctx { + struct nvc0_graph_priv *priv; + struct nvc0_graph_data *data; + struct nvc0_graph_mmio *mmio; + struct nouveau_gpuobj *chan; + int buffer_nr; + u64 buffer[4]; + u64 addr; +}; + +int nvc0_grctx_generate(struct nvc0_graph_priv *); +int nvc0_grctx_init(struct nvc0_graph_priv *, struct nvc0_grctx *); +void nvc0_grctx_data(struct nvc0_grctx *, u32, u32, u32); +void nvc0_grctx_mmio(struct nvc0_grctx *, u32, u32, u32, u32); +int nvc0_grctx_fini(struct nvc0_grctx *); + +int nve0_grctx_generate(struct nvc0_graph_priv *); + +#define mmio_data(s,a,p) nvc0_grctx_data(&info, (s), (a), (p)) +#define mmio_list(r,d,s,b) nvc0_grctx_mmio(&info, (r), (d), (s), (b)) + +void nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *); +int nvc0_graph_ctor_fw(struct nvc0_graph_priv *, const char *, + struct nvc0_graph_fuc *); +void nvc0_graph_dtor(struct nouveau_object *); +void nvc0_graph_init_fw(struct nvc0_graph_priv *, u32 base, + struct nvc0_graph_fuc *, struct nvc0_graph_fuc *); +int nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void nvc0_graph_context_dtor(struct nouveau_object *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c new file mode 100644 index 00000000000..539d4c72f19 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c @@ -0,0 +1,576 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nvc0.h" +#include "fuc/hubnve0.fuc.h" +#include "fuc/gpcnve0.fuc.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static struct nouveau_oclass +nve0_graph_sclass[] = { + { 0x902d, &nouveau_object_ofuncs }, + { 0xa040, &nouveau_object_ofuncs }, + { 0xa097, &nouveau_object_ofuncs }, + { 0xa0c0, &nouveau_object_ofuncs }, + { 0xa0b5, &nouveau_object_ofuncs }, + {} +}; + +/******************************************************************************* + * PGRAPH context + ******************************************************************************/ + +static struct nouveau_oclass +nve0_graph_cclass = { + .handle = NV_ENGCTX(GR, 0xe0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_graph_context_ctor, + .dtor = nvc0_graph_context_dtor, + .init = _nouveau_graph_context_init, + .fini = _nouveau_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static void +nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) +{ + u32 ustat = nv_rd32(priv, 0x409c18); + + if (ustat & 0x00000001) + nv_error(priv, "CTXCTRL ucode error\n"); + if (ustat & 0x00080000) + nv_error(priv, "CTXCTRL watchdog timeout\n"); + if (ustat & ~0x00080001) + nv_error(priv, "CTXCTRL 0x%08x\n", ustat); + + nvc0_graph_ctxctl_debug(priv); + nv_wr32(priv, 0x409c20, ustat); +} + +static void +nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst) +{ + u32 trap = nv_rd32(priv, 0x400108); + int rop; + + if (trap & 0x00000001) { + u32 stat = nv_rd32(priv, 0x404000); + nv_error(priv, "DISPATCH ch %d [0x%010llx] 0x%08x\n", + chid, inst, stat); + nv_wr32(priv, 0x404000, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000001); + trap &= ~0x00000001; + } + + if (trap & 0x00000010) { + u32 stat = nv_rd32(priv, 0x405840); + nv_error(priv, "SHADER ch %d [0x%010llx] 0x%08x\n", + chid, inst, stat); + nv_wr32(priv, 0x405840, 0xc0000000); + nv_wr32(priv, 0x400108, 0x00000010); + trap &= ~0x00000010; + } + + if (trap & 0x02000000) { + for (rop = 0; rop < priv->rop_nr; rop++) { + u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070)); + u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144)); + nv_error(priv, "ROP%d ch %d [0x%010llx] 0x%08x 0x%08x\n", + rop, chid, inst, statz, statc); + nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); + nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); + } + nv_wr32(priv, 0x400108, 0x02000000); + trap &= ~0x02000000; + } + + if (trap) { + nv_error(priv, "TRAP ch %d [0x%010llx] 0x%08x\n", + chid, inst, trap); + nv_wr32(priv, 0x400108, trap); + } +} + +static void +nve0_graph_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_fifo *pfifo = nouveau_fifo(subdev); + struct nouveau_engine *engine = nv_engine(subdev); + struct nouveau_object *engctx; + struct nouveau_handle *handle; + struct nvc0_graph_priv *priv = (void *)subdev; + u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff; + u32 stat = nv_rd32(priv, 0x400100); + u32 addr = nv_rd32(priv, 0x400704); + u32 mthd = (addr & 0x00003ffc); + u32 subc = (addr & 0x00070000) >> 16; + u32 data = nv_rd32(priv, 0x400708); + u32 code = nv_rd32(priv, 0x400110); + u32 class = nv_rd32(priv, 0x404200 + (subc * 4)); + int chid; + + engctx = nouveau_engctx_get(engine, inst); + chid = pfifo->chid(pfifo, engctx); + + if (stat & 0x00000010) { + handle = nouveau_handle_get_class(engctx, class); + if (!handle || nv_call(handle->object, mthd, data)) { + nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x\n", + chid, inst, subc, class, mthd, data); + } + nouveau_handle_put(handle); + nv_wr32(priv, 0x400100, 0x00000010); + stat &= ~0x00000010; + } + + if (stat & 0x00000020) { + nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d " + "class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); + nv_wr32(priv, 0x400100, 0x00000020); + stat &= ~0x00000020; + } + + if (stat & 0x00100000) { + nv_error(priv, "DATA_ERROR ["); + nouveau_enum_print(nv50_data_error_names, code); + printk("] ch %d [0x%010llx] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); + nv_wr32(priv, 0x400100, 0x00100000); + stat &= ~0x00100000; + } + + if (stat & 0x00200000) { + nve0_graph_trap_isr(priv, chid, inst); + nv_wr32(priv, 0x400100, 0x00200000); + stat &= ~0x00200000; + } + + if (stat & 0x00080000) { + nve0_graph_ctxctl_isr(priv); + nv_wr32(priv, 0x400100, 0x00080000); + stat &= ~0x00080000; + } + + if (stat) { + nv_error(priv, "unknown stat 0x%08x\n", stat); + nv_wr32(priv, 0x400100, stat); + } + + nv_wr32(priv, 0x400500, 0x00010001); + nouveau_engctx_put(engctx); +} + +static int +nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_device *device = nv_device(parent); + struct nvc0_graph_priv *priv; + int ret, i; + + ret = nouveau_graph_create(parent, engine, oclass, false, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x18001000; + nv_subdev(priv)->intr = nve0_graph_intr; + nv_engine(priv)->cclass = &nve0_graph_cclass; + nv_engine(priv)->sclass = nve0_graph_sclass; + + if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { + nv_info(priv, "using external firmware\n"); + if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) || + nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) || + nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) || + nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad)) + return -EINVAL; + priv->firmware = true; + } + + ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8); + if (ret) + return ret; + + for (i = 0; i < 0x1000; i += 4) { + nv_wo32(priv->unk4188b4, i, 0x00000010); + nv_wo32(priv->unk4188b8, i, 0x00000010); + } + + priv->gpc_nr = nv_rd32(priv, 0x409604) & 0x0000001f; + priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16; + for (i = 0; i < priv->gpc_nr; i++) { + priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608)); + priv->tpc_total += priv->tpc_nr[i]; + } + + switch (nv_device(priv)->chipset) { + case 0xe4: + if (priv->tpc_total == 8) + priv->magic_not_rop_nr = 3; + else + if (priv->tpc_total == 7) + priv->magic_not_rop_nr = 1; + break; + case 0xe7: + priv->magic_not_rop_nr = 1; + break; + default: + break; + } + + return 0; +} + +static void +nve0_graph_init_obj418880(struct nvc0_graph_priv *priv) +{ + int i; + + nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000); + nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000); + for (i = 0; i < 4; i++) + nv_wr32(priv, GPC_BCAST(0x0888) + (i * 4), 0x00000000); + nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8); + nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8); +} + +static void +nve0_graph_init_regs(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x400080, 0x003083c2); + nv_wr32(priv, 0x400088, 0x0001ffe7); + nv_wr32(priv, 0x40008c, 0x00000000); + nv_wr32(priv, 0x400090, 0x00000030); + nv_wr32(priv, 0x40013c, 0x003901f7); + nv_wr32(priv, 0x400140, 0x00000100); + nv_wr32(priv, 0x400144, 0x00000000); + nv_wr32(priv, 0x400148, 0x00000110); + nv_wr32(priv, 0x400138, 0x00000000); + nv_wr32(priv, 0x400130, 0x00000000); + nv_wr32(priv, 0x400134, 0x00000000); + nv_wr32(priv, 0x400124, 0x00000002); +} + +static void +nve0_graph_init_units(struct nvc0_graph_priv *priv) +{ + nv_wr32(priv, 0x409ffc, 0x00000000); + nv_wr32(priv, 0x409c14, 0x00003e3e); + nv_wr32(priv, 0x409c24, 0x000f0000); + + nv_wr32(priv, 0x404000, 0xc0000000); + nv_wr32(priv, 0x404600, 0xc0000000); + nv_wr32(priv, 0x408030, 0xc0000000); + nv_wr32(priv, 0x404490, 0xc0000000); + nv_wr32(priv, 0x406018, 0xc0000000); + nv_wr32(priv, 0x407020, 0xc0000000); + nv_wr32(priv, 0x405840, 0xc0000000); + nv_wr32(priv, 0x405844, 0x00ffffff); + + nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008); + nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000); + +} + +static void +nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv) +{ + const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total); + u32 data[TPC_MAX / 8]; + u8 tpcnr[GPC_MAX]; + int i, gpc, tpc; + + nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001); + + memset(data, 0x00, sizeof(data)); + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + for (i = 0, gpc = -1; i < priv->tpc_total; i++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; + + data[i / 8] |= tpc << ((i % 8) * 4); + } + + nv_wr32(priv, GPC_BCAST(0x0980), data[0]); + nv_wr32(priv, GPC_BCAST(0x0984), data[1]); + nv_wr32(priv, GPC_BCAST(0x0988), data[2]); + nv_wr32(priv, GPC_BCAST(0x098c), data[3]); + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + nv_wr32(priv, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 | + priv->tpc_nr[gpc]); + nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total); + nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918); + } + + nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918); + nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800)); +} + +static void +nve0_graph_init_gpc_1(struct nvc0_graph_priv *priv) +{ + int gpc, tpc; + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + nv_wr32(priv, GPC_UNIT(gpc, 0x3038), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000); + for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f); + } + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff); + } +} + +static void +nve0_graph_init_rop(struct nvc0_graph_priv *priv) +{ + int rop; + + for (rop = 0; rop < priv->rop_nr; rop++) { + nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000); + nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000); + nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff); + nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff); + } +} + +static int +nve0_graph_init_ctxctl(struct nvc0_graph_priv *priv) +{ + u32 r000260; + int i; + + if (priv->firmware) { + /* load fuc microcode */ + r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, &priv->fuc409d); + nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, &priv->fuc41ad); + nv_wr32(priv, 0x000260, r000260); + + /* start both of them running */ + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x41a10c, 0x00000000); + nv_wr32(priv, 0x40910c, 0x00000000); + nv_wr32(priv, 0x41a100, 0x00000002); + nv_wr32(priv, 0x409100, 0x00000002); + if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001)) + nv_error(priv, "0x409800 wait failed\n"); + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x7fffffff); + nv_wr32(priv, 0x409504, 0x00000021); + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x00000000); + nv_wr32(priv, 0x409504, 0x00000010); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x10 timeout\n"); + return -EBUSY; + } + priv->size = nv_rd32(priv, 0x409800); + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x00000000); + nv_wr32(priv, 0x409504, 0x00000016); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x16 timeout\n"); + return -EBUSY; + } + + nv_wr32(priv, 0x409840, 0xffffffff); + nv_wr32(priv, 0x409500, 0x00000000); + nv_wr32(priv, 0x409504, 0x00000025); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x25 timeout\n"); + return -EBUSY; + } + + nv_wr32(priv, 0x409800, 0x00000000); + nv_wr32(priv, 0x409500, 0x00000001); + nv_wr32(priv, 0x409504, 0x00000030); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x30 timeout\n"); + return -EBUSY; + } + + nv_wr32(priv, 0x409810, 0xb00095c8); + nv_wr32(priv, 0x409800, 0x00000000); + nv_wr32(priv, 0x409500, 0x00000001); + nv_wr32(priv, 0x409504, 0x00000031); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x31 timeout\n"); + return -EBUSY; + } + + nv_wr32(priv, 0x409810, 0x00080420); + nv_wr32(priv, 0x409800, 0x00000000); + nv_wr32(priv, 0x409500, 0x00000001); + nv_wr32(priv, 0x409504, 0x00000032); + if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) { + nv_error(priv, "fuc09 req 0x32 timeout\n"); + return -EBUSY; + } + + nv_wr32(priv, 0x409614, 0x00000070); + nv_wr32(priv, 0x409614, 0x00000770); + nv_wr32(priv, 0x40802c, 0x00000001); + + if (priv->data == NULL) { + int ret = nve0_grctx_generate(priv); + if (ret) { + nv_error(priv, "failed to construct context\n"); + return ret; + } + } + + return 0; + } + + /* load HUB microcode */ + r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nv_wr32(priv, 0x4091c0, 0x01000000); + for (i = 0; i < sizeof(nve0_grhub_data) / 4; i++) + nv_wr32(priv, 0x4091c4, nve0_grhub_data[i]); + + nv_wr32(priv, 0x409180, 0x01000000); + for (i = 0; i < sizeof(nve0_grhub_code) / 4; i++) { + if ((i & 0x3f) == 0) + nv_wr32(priv, 0x409188, i >> 6); + nv_wr32(priv, 0x409184, nve0_grhub_code[i]); + } + + /* load GPC microcode */ + nv_wr32(priv, 0x41a1c0, 0x01000000); + for (i = 0; i < sizeof(nve0_grgpc_data) / 4; i++) + nv_wr32(priv, 0x41a1c4, nve0_grgpc_data[i]); + + nv_wr32(priv, 0x41a180, 0x01000000); + for (i = 0; i < sizeof(nve0_grgpc_code) / 4; i++) { + if ((i & 0x3f) == 0) + nv_wr32(priv, 0x41a188, i >> 6); + nv_wr32(priv, 0x41a184, nve0_grgpc_code[i]); + } + nv_wr32(priv, 0x000260, r000260); + + /* start HUB ucode running, it'll init the GPCs */ + nv_wr32(priv, 0x409800, nv_device(priv)->chipset); + nv_wr32(priv, 0x40910c, 0x00000000); + nv_wr32(priv, 0x409100, 0x00000002); + if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) { + nv_error(priv, "HUB_INIT timed out\n"); + nvc0_graph_ctxctl_debug(priv); + return -EBUSY; + } + + priv->size = nv_rd32(priv, 0x409804); + if (priv->data == NULL) { + int ret = nve0_grctx_generate(priv); + if (ret) { + nv_error(priv, "failed to construct context\n"); + return ret; + } + } + + return 0; +} + +static int +nve0_graph_init(struct nouveau_object *object) +{ + struct nvc0_graph_priv *priv = (void *)object; + int ret; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + nve0_graph_init_obj418880(priv); + nve0_graph_init_regs(priv); + nve0_graph_init_gpc_0(priv); + + nv_wr32(priv, 0x400500, 0x00010001); + nv_wr32(priv, 0x400100, 0xffffffff); + nv_wr32(priv, 0x40013c, 0xffffffff); + + nve0_graph_init_units(priv); + nve0_graph_init_gpc_1(priv); + nve0_graph_init_rop(priv); + + nv_wr32(priv, 0x400108, 0xffffffff); + nv_wr32(priv, 0x400138, 0xffffffff); + nv_wr32(priv, 0x400118, 0xffffffff); + nv_wr32(priv, 0x400130, 0xffffffff); + nv_wr32(priv, 0x40011c, 0xffffffff); + nv_wr32(priv, 0x400134, 0xffffffff); + nv_wr32(priv, 0x400054, 0x34ce3464); + + ret = nve0_graph_init_ctxctl(priv); + if (ret) + return ret; + + return 0; +} + +struct nouveau_oclass +nve0_graph_oclass = { + .handle = NV_ENGINE(GR, 0xe0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nve0_graph_ctor, + .dtor = nvc0_graph_dtor, + .init = nve0_graph_init, + .fini = _nouveau_graph_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/regs.h b/drivers/gpu/drm/nouveau/core/engine/graph/regs.h new file mode 100644 index 00000000000..9c715a25cec --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/regs.h @@ -0,0 +1,269 @@ +#ifndef __NOUVEAU_GRAPH_REGS_H__ +#define __NOUVEAU_GRAPH_REGS_H__ + +#define NV04_PGRAPH_DEBUG_0 0x00400080 +#define NV04_PGRAPH_DEBUG_1 0x00400084 +#define NV04_PGRAPH_DEBUG_2 0x00400088 +#define NV04_PGRAPH_DEBUG_3 0x0040008c +#define NV10_PGRAPH_DEBUG_4 0x00400090 +#define NV03_PGRAPH_INTR 0x00400100 +#define NV03_PGRAPH_NSTATUS 0x00400104 +# define NV04_PGRAPH_NSTATUS_STATE_IN_USE (1<<11) +# define NV04_PGRAPH_NSTATUS_INVALID_STATE (1<<12) +# define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<13) +# define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<14) +# define NV10_PGRAPH_NSTATUS_STATE_IN_USE (1<<23) +# define NV10_PGRAPH_NSTATUS_INVALID_STATE (1<<24) +# define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<25) +# define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<26) +#define NV03_PGRAPH_NSOURCE 0x00400108 +# define NV03_PGRAPH_NSOURCE_NOTIFICATION (1<<0) +# define NV03_PGRAPH_NSOURCE_DATA_ERROR (1<<1) +# define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR (1<<2) +# define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION (1<<3) +# define NV03_PGRAPH_NSOURCE_LIMIT_COLOR (1<<4) +# define NV03_PGRAPH_NSOURCE_LIMIT_ZETA (1<<5) +# define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD (1<<6) +# define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION (1<<7) +# define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION (1<<8) +# define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION (1<<9) +# define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION (1<<10) +# define NV03_PGRAPH_NSOURCE_STATE_INVALID (1<<11) +# define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY (1<<12) +# define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE (1<<13) +# define NV03_PGRAPH_NSOURCE_METHOD_CNT (1<<14) +# define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION (1<<15) +# define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION (1<<16) +# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A (1<<17) +# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B (1<<18) +#define NV03_PGRAPH_INTR_EN 0x00400140 +#define NV40_PGRAPH_INTR_EN 0x0040013C +# define NV_PGRAPH_INTR_NOTIFY (1<<0) +# define NV_PGRAPH_INTR_MISSING_HW (1<<4) +# define NV_PGRAPH_INTR_CONTEXT_SWITCH (1<<12) +# define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16) +# define NV_PGRAPH_INTR_ERROR (1<<20) +#define NV10_PGRAPH_CTX_CONTROL 0x00400144 +#define NV10_PGRAPH_CTX_USER 0x00400148 +#define NV10_PGRAPH_CTX_SWITCH(i) (0x0040014C + 0x4*(i)) +#define NV04_PGRAPH_CTX_SWITCH1 0x00400160 +#define NV10_PGRAPH_CTX_CACHE(i, j) (0x00400160 \ + + 0x4*(i) + 0x20*(j)) +#define NV04_PGRAPH_CTX_SWITCH2 0x00400164 +#define NV04_PGRAPH_CTX_SWITCH3 0x00400168 +#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C +#define NV04_PGRAPH_CTX_CONTROL 0x00400170 +#define NV04_PGRAPH_CTX_USER 0x00400174 +#define NV04_PGRAPH_CTX_CACHE1 0x00400180 +#define NV03_PGRAPH_CTX_CONTROL 0x00400190 +#define NV03_PGRAPH_CTX_USER 0x00400194 +#define NV04_PGRAPH_CTX_CACHE2 0x004001A0 +#define NV04_PGRAPH_CTX_CACHE3 0x004001C0 +#define NV04_PGRAPH_CTX_CACHE4 0x004001E0 +#define NV40_PGRAPH_CTXCTL_0304 0x00400304 +#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK 0xff000000 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT 24 +#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK 0x00ffffff +#define NV40_PGRAPH_CTXCTL_0310 0x00400310 +#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE 0x00000020 +#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD 0x00000040 +#define NV40_PGRAPH_CTXCTL_030C 0x0040030c +#define NV40_PGRAPH_CTXCTL_UCODE_INDEX 0x00400324 +#define NV40_PGRAPH_CTXCTL_UCODE_DATA 0x00400328 +#define NV40_PGRAPH_CTXCTL_CUR 0x0040032c +#define NV40_PGRAPH_CTXCTL_CUR_LOADED 0x01000000 +#define NV40_PGRAPH_CTXCTL_CUR_INSTANCE 0x000FFFFF +#define NV40_PGRAPH_CTXCTL_NEXT 0x00400330 +#define NV40_PGRAPH_CTXCTL_NEXT_INSTANCE 0x000fffff +#define NV50_PGRAPH_CTXCTL_CUR 0x0040032c +#define NV50_PGRAPH_CTXCTL_CUR_LOADED 0x80000000 +#define NV50_PGRAPH_CTXCTL_CUR_INSTANCE 0x00ffffff +#define NV50_PGRAPH_CTXCTL_NEXT 0x00400330 +#define NV50_PGRAPH_CTXCTL_NEXT_INSTANCE 0x00ffffff +#define NV03_PGRAPH_ABS_X_RAM 0x00400400 +#define NV03_PGRAPH_ABS_Y_RAM 0x00400480 +#define NV03_PGRAPH_X_MISC 0x00400500 +#define NV03_PGRAPH_Y_MISC 0x00400504 +#define NV04_PGRAPH_VALID1 0x00400508 +#define NV04_PGRAPH_SOURCE_COLOR 0x0040050C +#define NV04_PGRAPH_MISC24_0 0x00400510 +#define NV03_PGRAPH_XY_LOGIC_MISC0 0x00400514 +#define NV03_PGRAPH_XY_LOGIC_MISC1 0x00400518 +#define NV03_PGRAPH_XY_LOGIC_MISC2 0x0040051C +#define NV03_PGRAPH_XY_LOGIC_MISC3 0x00400520 +#define NV03_PGRAPH_CLIPX_0 0x00400524 +#define NV03_PGRAPH_CLIPX_1 0x00400528 +#define NV03_PGRAPH_CLIPY_0 0x0040052C +#define NV03_PGRAPH_CLIPY_1 0x00400530 +#define NV03_PGRAPH_ABS_ICLIP_XMAX 0x00400534 +#define NV03_PGRAPH_ABS_ICLIP_YMAX 0x00400538 +#define NV03_PGRAPH_ABS_UCLIP_XMIN 0x0040053C +#define NV03_PGRAPH_ABS_UCLIP_YMIN 0x00400540 +#define NV03_PGRAPH_ABS_UCLIP_XMAX 0x00400544 +#define NV03_PGRAPH_ABS_UCLIP_YMAX 0x00400548 +#define NV03_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 +#define NV03_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 +#define NV03_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 +#define NV03_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C +#define NV04_PGRAPH_MISC24_1 0x00400570 +#define NV04_PGRAPH_MISC24_2 0x00400574 +#define NV04_PGRAPH_VALID2 0x00400578 +#define NV04_PGRAPH_PASSTHRU_0 0x0040057C +#define NV04_PGRAPH_PASSTHRU_1 0x00400580 +#define NV04_PGRAPH_PASSTHRU_2 0x00400584 +#define NV10_PGRAPH_DIMX_TEXTURE 0x00400588 +#define NV10_PGRAPH_WDIMX_TEXTURE 0x0040058C +#define NV04_PGRAPH_COMBINE_0_ALPHA 0x00400590 +#define NV04_PGRAPH_COMBINE_0_COLOR 0x00400594 +#define NV04_PGRAPH_COMBINE_1_ALPHA 0x00400598 +#define NV04_PGRAPH_COMBINE_1_COLOR 0x0040059C +#define NV04_PGRAPH_FORMAT_0 0x004005A8 +#define NV04_PGRAPH_FORMAT_1 0x004005AC +#define NV04_PGRAPH_FILTER_0 0x004005B0 +#define NV04_PGRAPH_FILTER_1 0x004005B4 +#define NV03_PGRAPH_MONO_COLOR0 0x00400600 +#define NV04_PGRAPH_ROP3 0x00400604 +#define NV04_PGRAPH_BETA_AND 0x00400608 +#define NV04_PGRAPH_BETA_PREMULT 0x0040060C +#define NV04_PGRAPH_LIMIT_VIOL_PIX 0x00400610 +#define NV04_PGRAPH_FORMATS 0x00400618 +#define NV10_PGRAPH_DEBUG_2 0x00400620 +#define NV04_PGRAPH_BOFFSET0 0x00400640 +#define NV04_PGRAPH_BOFFSET1 0x00400644 +#define NV04_PGRAPH_BOFFSET2 0x00400648 +#define NV04_PGRAPH_BOFFSET3 0x0040064C +#define NV04_PGRAPH_BOFFSET4 0x00400650 +#define NV04_PGRAPH_BOFFSET5 0x00400654 +#define NV04_PGRAPH_BBASE0 0x00400658 +#define NV04_PGRAPH_BBASE1 0x0040065C +#define NV04_PGRAPH_BBASE2 0x00400660 +#define NV04_PGRAPH_BBASE3 0x00400664 +#define NV04_PGRAPH_BBASE4 0x00400668 +#define NV04_PGRAPH_BBASE5 0x0040066C +#define NV04_PGRAPH_BPITCH0 0x00400670 +#define NV04_PGRAPH_BPITCH1 0x00400674 +#define NV04_PGRAPH_BPITCH2 0x00400678 +#define NV04_PGRAPH_BPITCH3 0x0040067C +#define NV04_PGRAPH_BPITCH4 0x00400680 +#define NV04_PGRAPH_BLIMIT0 0x00400684 +#define NV04_PGRAPH_BLIMIT1 0x00400688 +#define NV04_PGRAPH_BLIMIT2 0x0040068C +#define NV04_PGRAPH_BLIMIT3 0x00400690 +#define NV04_PGRAPH_BLIMIT4 0x00400694 +#define NV04_PGRAPH_BLIMIT5 0x00400698 +#define NV04_PGRAPH_BSWIZZLE2 0x0040069C +#define NV04_PGRAPH_BSWIZZLE5 0x004006A0 +#define NV03_PGRAPH_STATUS 0x004006B0 +#define NV04_PGRAPH_STATUS 0x00400700 +# define NV40_PGRAPH_STATUS_SYNC_STALL 0x00004000 +#define NV04_PGRAPH_TRAPPED_ADDR 0x00400704 +#define NV04_PGRAPH_TRAPPED_DATA 0x00400708 +#define NV04_PGRAPH_SURFACE 0x0040070C +#define NV10_PGRAPH_TRAPPED_DATA_HIGH 0x0040070C +#define NV04_PGRAPH_STATE 0x00400710 +#define NV10_PGRAPH_SURFACE 0x00400710 +#define NV04_PGRAPH_NOTIFY 0x00400714 +#define NV10_PGRAPH_STATE 0x00400714 +#define NV10_PGRAPH_NOTIFY 0x00400718 + +#define NV04_PGRAPH_FIFO 0x00400720 + +#define NV04_PGRAPH_BPIXEL 0x00400724 +#define NV10_PGRAPH_RDI_INDEX 0x00400750 +#define NV04_PGRAPH_FFINTFC_ST2 0x00400754 +#define NV10_PGRAPH_RDI_DATA 0x00400754 +#define NV04_PGRAPH_DMA_PITCH 0x00400760 +#define NV10_PGRAPH_FFINTFC_FIFO_PTR 0x00400760 +#define NV04_PGRAPH_DVD_COLORFMT 0x00400764 +#define NV10_PGRAPH_FFINTFC_ST2 0x00400764 +#define NV04_PGRAPH_SCALED_FORMAT 0x00400768 +#define NV10_PGRAPH_FFINTFC_ST2_DL 0x00400768 +#define NV10_PGRAPH_FFINTFC_ST2_DH 0x0040076c +#define NV10_PGRAPH_DMA_PITCH 0x00400770 +#define NV10_PGRAPH_DVD_COLORFMT 0x00400774 +#define NV10_PGRAPH_SCALED_FORMAT 0x00400778 +#define NV20_PGRAPH_CHANNEL_CTX_TABLE 0x00400780 +#define NV20_PGRAPH_CHANNEL_CTX_POINTER 0x00400784 +#define NV20_PGRAPH_CHANNEL_CTX_XFER 0x00400788 +#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD 0x00000001 +#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE 0x00000002 +#define NV04_PGRAPH_PATT_COLOR0 0x00400800 +#define NV04_PGRAPH_PATT_COLOR1 0x00400804 +#define NV04_PGRAPH_PATTERN 0x00400808 +#define NV04_PGRAPH_PATTERN_SHAPE 0x00400810 +#define NV04_PGRAPH_CHROMA 0x00400814 +#define NV04_PGRAPH_CONTROL0 0x00400818 +#define NV04_PGRAPH_CONTROL1 0x0040081C +#define NV04_PGRAPH_CONTROL2 0x00400820 +#define NV04_PGRAPH_BLEND 0x00400824 +#define NV04_PGRAPH_STORED_FMT 0x00400830 +#define NV04_PGRAPH_PATT_COLORRAM 0x00400900 +#define NV20_PGRAPH_TILE(i) (0x00400900 + (i*16)) +#define NV20_PGRAPH_TLIMIT(i) (0x00400904 + (i*16)) +#define NV20_PGRAPH_TSIZE(i) (0x00400908 + (i*16)) +#define NV20_PGRAPH_TSTATUS(i) (0x0040090C + (i*16)) +#define NV20_PGRAPH_ZCOMP(i) (0x00400980 + 4*(i)) +#define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) +#define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) +#define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) +#define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) +#define NV04_PGRAPH_U_RAM 0x00400D00 +#define NV47_PGRAPH_TILE(i) (0x00400D00 + (i*16)) +#define NV47_PGRAPH_TLIMIT(i) (0x00400D04 + (i*16)) +#define NV47_PGRAPH_TSIZE(i) (0x00400D08 + (i*16)) +#define NV47_PGRAPH_TSTATUS(i) (0x00400D0C + (i*16)) +#define NV04_PGRAPH_V_RAM 0x00400D40 +#define NV04_PGRAPH_W_RAM 0x00400D80 +#define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 +#define NV10_PGRAPH_COMBINER1_IN_ALPHA 0x00400E44 +#define NV10_PGRAPH_COMBINER0_IN_RGB 0x00400E48 +#define NV10_PGRAPH_COMBINER1_IN_RGB 0x00400E4C +#define NV10_PGRAPH_COMBINER_COLOR0 0x00400E50 +#define NV10_PGRAPH_COMBINER_COLOR1 0x00400E54 +#define NV10_PGRAPH_COMBINER0_OUT_ALPHA 0x00400E58 +#define NV10_PGRAPH_COMBINER1_OUT_ALPHA 0x00400E5C +#define NV10_PGRAPH_COMBINER0_OUT_RGB 0x00400E60 +#define NV10_PGRAPH_COMBINER1_OUT_RGB 0x00400E64 +#define NV10_PGRAPH_COMBINER_FINAL0 0x00400E68 +#define NV10_PGRAPH_COMBINER_FINAL1 0x00400E6C +#define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL 0x00400F00 +#define NV10_PGRAPH_WINDOWCLIP_VERTICAL 0x00400F20 +#define NV10_PGRAPH_XFMODE0 0x00400F40 +#define NV10_PGRAPH_XFMODE1 0x00400F44 +#define NV10_PGRAPH_GLOBALSTATE0 0x00400F48 +#define NV10_PGRAPH_GLOBALSTATE1 0x00400F4C +#define NV10_PGRAPH_PIPE_ADDRESS 0x00400F50 +#define NV10_PGRAPH_PIPE_DATA 0x00400F54 +#define NV04_PGRAPH_DMA_START_0 0x00401000 +#define NV04_PGRAPH_DMA_START_1 0x00401004 +#define NV04_PGRAPH_DMA_LENGTH 0x00401008 +#define NV04_PGRAPH_DMA_MISC 0x0040100C +#define NV04_PGRAPH_DMA_DATA_0 0x00401020 +#define NV04_PGRAPH_DMA_DATA_1 0x00401024 +#define NV04_PGRAPH_DMA_RM 0x00401030 +#define NV04_PGRAPH_DMA_A_XLATE_INST 0x00401040 +#define NV04_PGRAPH_DMA_A_CONTROL 0x00401044 +#define NV04_PGRAPH_DMA_A_LIMIT 0x00401048 +#define NV04_PGRAPH_DMA_A_TLB_PTE 0x0040104C +#define NV04_PGRAPH_DMA_A_TLB_TAG 0x00401050 +#define NV04_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 +#define NV04_PGRAPH_DMA_A_OFFSET 0x00401058 +#define NV04_PGRAPH_DMA_A_SIZE 0x0040105C +#define NV04_PGRAPH_DMA_A_Y_SIZE 0x00401060 +#define NV04_PGRAPH_DMA_B_XLATE_INST 0x00401080 +#define NV04_PGRAPH_DMA_B_CONTROL 0x00401084 +#define NV04_PGRAPH_DMA_B_LIMIT 0x00401088 +#define NV04_PGRAPH_DMA_B_TLB_PTE 0x0040108C +#define NV04_PGRAPH_DMA_B_TLB_TAG 0x00401090 +#define NV04_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 +#define NV04_PGRAPH_DMA_B_OFFSET 0x00401098 +#define NV04_PGRAPH_DMA_B_SIZE 0x0040109C +#define NV04_PGRAPH_DMA_B_Y_SIZE 0x004010A0 +#define NV40_PGRAPH_TILE1(i) (0x00406900 + (i*16)) +#define NV40_PGRAPH_TLIMIT1(i) (0x00406904 + (i*16)) +#define NV40_PGRAPH_TSIZE1(i) (0x00406908 + (i*16)) +#define NV40_PGRAPH_TSTATUS1(i) (0x0040690C + (i*16)) + +#endif |