/* * 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 */ /* 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 … #define CP_FLAG_SET … #define CP_FLAG_SWAP_DIRECTION … #define CP_FLAG_SWAP_DIRECTION_LOAD … #define CP_FLAG_SWAP_DIRECTION_SAVE … #define CP_FLAG_USER_SAVE … #define CP_FLAG_USER_SAVE_NOT_PENDING … #define CP_FLAG_USER_SAVE_PENDING … #define CP_FLAG_USER_LOAD … #define CP_FLAG_USER_LOAD_NOT_PENDING … #define CP_FLAG_USER_LOAD_PENDING … #define CP_FLAG_STATUS … #define CP_FLAG_STATUS_IDLE … #define CP_FLAG_STATUS_BUSY … #define CP_FLAG_AUTO_SAVE … #define CP_FLAG_AUTO_SAVE_NOT_PENDING … #define CP_FLAG_AUTO_SAVE_PENDING … #define CP_FLAG_AUTO_LOAD … #define CP_FLAG_AUTO_LOAD_NOT_PENDING … #define CP_FLAG_AUTO_LOAD_PENDING … #define CP_FLAG_UNK54 … #define CP_FLAG_UNK54_CLEAR … #define CP_FLAG_UNK54_SET … #define CP_FLAG_ALWAYS … #define CP_FLAG_ALWAYS_FALSE … #define CP_FLAG_ALWAYS_TRUE … #define CP_FLAG_UNK57 … #define CP_FLAG_UNK57_CLEAR … #define CP_FLAG_UNK57_SET … #define CP_CTX … #define CP_CTX_COUNT … #define CP_CTX_COUNT_SHIFT … #define CP_CTX_REG … #define CP_LOAD_SR … #define CP_LOAD_SR_VALUE … #define CP_BRA … #define CP_BRA_IP … #define CP_BRA_IP_SHIFT … #define CP_BRA_IF_CLEAR … #define CP_BRA_FLAG … #define CP_WAIT … #define CP_WAIT_SET … #define CP_WAIT_FLAG … #define CP_SET … #define CP_SET_1 … #define CP_SET_FLAG … #define CP_NEXT_TO_SWAP … #define CP_NEXT_TO_CURRENT … #define CP_SET_CONTEXT_POINTER … #define CP_END … #define CP_LOAD_MAGIC_UNK01 … #define CP_LOAD_MAGIC_NV44TCL … #define CP_LOAD_MAGIC_NV40TCL … #include "ctxnv40.h" #include "nv40.h" /* TODO: * - get vs count from 0x1540 */ static int nv40_gr_vs_count(struct nvkm_device *device) { … } enum cp_label { … }; static void nv40_gr_construct_general(struct nvkm_grctx *ctx) { … } static void nv40_gr_construct_state3d(struct nvkm_grctx *ctx) { … } static void nv40_gr_construct_state3d_2(struct nvkm_grctx *ctx) { … } static void nv40_gr_construct_state3d_3(struct nvkm_grctx *ctx) { … } static void nv40_gr_construct_shader(struct nvkm_grctx *ctx) { … } static void nv40_grctx_generate(struct nvkm_grctx *ctx) { … } void nv40_grctx_fill(struct nvkm_device *device, struct nvkm_gpuobj *mem) { … } int nv40_grctx_init(struct nvkm_device *device, u32 *size) { … }