📄 riva_hw.c
字号:
/***************************************************************************\|* *||* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *||* *||* NOTICE TO USER: The source code is copyrighted under U.S. and *||* international laws. Users and possessors of this source code are *||* hereby granted a nonexclusive, royalty-free copyright license to *||* use this code in individual and commercial software. *||* *||* Any use of this source code must include, in the user documenta- *||* tion and internal comments to the code, notices to the end user *||* as follows: *||* *||* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *||* *||* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *||* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *||* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *||* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *||* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *||* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *||* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *||* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *||* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *||* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *||* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *||* *||* U.S. Government End Users. This source code is a "commercial *||* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *||* consisting of "commercial computer software" and "commercial *||* computer software documentation," as such terms are used in *||* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *||* ment only as a commercial end item. Consistent with 48 C.F.R. *||* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *||* all U.S. Government End Users acquire the source code with only *||* those rights set forth herein. *||* *| \***************************************************************************//* * GPL licensing note -- nVidia is allowing a liberal interpretation of * the documentation restriction above, to merely say that this nVidia's * copyright and disclaimer should be included with all code derived * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 *//* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.33 2002/08/05 20:47:06 mvojkovi Exp $ */#include <linux/kernel.h>#include <linux/pci.h>#include <linux/pci_ids.h>#include "riva_hw.h"#include "riva_tbl.h"#include "nv_type.h"/* * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT * operate identically (except TNT has more memory and better 3D quality. */static int nv3Busy( RIVA_HW_INST *chip){ return ((NV_RD32(&chip->Rop->FifoFree, 0) < chip->FifoEmptyCount) || NV_RD32(&chip->PGRAPH[0x000006B0/4], 0) & 0x01);}static int nv4Busy( RIVA_HW_INST *chip){ return ((NV_RD32(&chip->Rop->FifoFree, 0) < chip->FifoEmptyCount) || NV_RD32(&chip->PGRAPH[0x00000700/4], 0) & 0x01);}static int nv10Busy( RIVA_HW_INST *chip){ return ((NV_RD32(&chip->Rop->FifoFree, 0) < chip->FifoEmptyCount) || NV_RD32(&chip->PGRAPH[0x00000700/4], 0) & 0x01);}static void vgaLockUnlock( RIVA_HW_INST *chip, int Lock){ U008 cr11; VGA_WR08(chip->PCIO, 0x3D4, 0x11); cr11 = VGA_RD08(chip->PCIO, 0x3D5); if(Lock) cr11 |= 0x80; else cr11 &= ~0x80; VGA_WR08(chip->PCIO, 0x3D5, cr11);}static void nv3LockUnlock( RIVA_HW_INST *chip, int Lock){ VGA_WR08(chip->PVIO, 0x3C4, 0x06); VGA_WR08(chip->PVIO, 0x3C5, Lock ? 0x99 : 0x57); vgaLockUnlock(chip, Lock);}static void nv4LockUnlock( RIVA_HW_INST *chip, int Lock){ VGA_WR08(chip->PCIO, 0x3D4, 0x1F); VGA_WR08(chip->PCIO, 0x3D5, Lock ? 0x99 : 0x57); vgaLockUnlock(chip, Lock);}static int ShowHideCursor( RIVA_HW_INST *chip, int ShowHide){ int cursor; cursor = chip->CurrentState->cursor1; chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) | (ShowHide & 0x01); VGA_WR08(chip->PCIO, 0x3D4, 0x31); VGA_WR08(chip->PCIO, 0x3D5, chip->CurrentState->cursor1); return (cursor & 0x01);}/****************************************************************************\* ** The video arbitration routines calculate some "magic" numbers. Fixes ** the snow seen when accessing the framebuffer without it. ** It just works (I hope). ** *\****************************************************************************/#define DEFAULT_GR_LWM 100#define DEFAULT_VID_LWM 100#define DEFAULT_GR_BURST_SIZE 256#define DEFAULT_VID_BURST_SIZE 128#define VIDEO 0#define GRAPHICS 1#define MPORT 2#define ENGINE 3#define GFIFO_SIZE 320#define GFIFO_SIZE_128 256#define MFIFO_SIZE 120#define VFIFO_SIZE 256typedef struct { int gdrain_rate; int vdrain_rate; int mdrain_rate; int gburst_size; int vburst_size; char vid_en; char gr_en; int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm; int by_gfacc; char vid_only_once; char gr_only_once; char first_vacc; char first_gacc; char first_macc; int vocc; int gocc; int mocc; char cur; char engine_en; char converged; int priority;} nv3_arb_info;typedef struct { int graphics_lwm; int video_lwm; int graphics_burst_size; int video_burst_size; int graphics_hi_priority; int media_hi_priority; int rtl_values; int valid;} nv3_fifo_info;typedef struct { char pix_bpp; char enable_video; char gr_during_vid; char enable_mp; int memory_width; int video_scale; int pclk_khz; int mclk_khz; int mem_page_miss; int mem_latency; char mem_aligned;} nv3_sim_state;typedef struct { int graphics_lwm; int video_lwm; int graphics_burst_size; int video_burst_size; int valid;} nv4_fifo_info;typedef struct { int pclk_khz; int mclk_khz; int nvclk_khz; char mem_page_miss; char mem_latency; int memory_width; char enable_video; char gr_during_vid; char pix_bpp; char mem_aligned; char enable_mp;} nv4_sim_state;typedef struct { int graphics_lwm; int video_lwm; int graphics_burst_size; int video_burst_size; int valid;} nv10_fifo_info;typedef struct { int pclk_khz; int mclk_khz; int nvclk_khz; char mem_page_miss; char mem_latency; int memory_type; int memory_width; char enable_video; char gr_during_vid; char pix_bpp; char mem_aligned; char enable_mp;} nv10_sim_state;static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo){ int iter = 0; int tmp; int vfsize, mfsize, gfsize; int mburst_size = 32; int mmisses, gmisses, vmisses; int misses; int vlwm, glwm, mlwm; int last, next, cur; int max_gfsize ; long ns; vlwm = 0; glwm = 0; mlwm = 0; vfsize = 0; gfsize = 0; cur = ainfo->cur; mmisses = 2; gmisses = 2; vmisses = 2; if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128; else max_gfsize = GFIFO_SIZE; max_gfsize = GFIFO_SIZE; while (1) { if (ainfo->vid_en) { if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc; if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ; ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz; vfsize = ns * ainfo->vdrain_rate / 1000000; vfsize = ainfo->wcvlwm - ainfo->vburst_size + vfsize; } if (state->enable_mp) { if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc; } if (ainfo->gr_en) { if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ; if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc; ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz; gfsize = (ns * (long) ainfo->gdrain_rate)/1000000; gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize; } mfsize = 0; if (!state->gr_during_vid && ainfo->vid_en) if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once) next = VIDEO; else if (ainfo->mocc < 0) next = MPORT; else if (ainfo->gocc< ainfo->by_gfacc) next = GRAPHICS; else return (0); else switch (ainfo->priority) { case VIDEO: if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once) next = VIDEO; else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once) next = GRAPHICS; else if (ainfo->mocc<0) next = MPORT; else return (0); break; case GRAPHICS: if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once) next = GRAPHICS; else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once) next = VIDEO; else if (ainfo->mocc<0) next = MPORT; else return (0); break; default: if (ainfo->mocc<0) next = MPORT; else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once) next = GRAPHICS; else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once) next = VIDEO; else return (0); break; } last = cur; cur = next; iter++; switch (cur) { case VIDEO: if (last==cur) misses = 0; else if (ainfo->first_vacc) misses = vmisses; else misses = 1; ainfo->first_vacc = 0; if (last!=cur) { ns = 1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; vlwm = ns * ainfo->vdrain_rate/ 1000000; vlwm = ainfo->vocc - vlwm; } ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz; ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000; ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000; ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000; break; case GRAPHICS: if (last==cur) misses = 0; else if (ainfo->first_gacc) misses = gmisses; else misses = 1; ainfo->first_gacc = 0; if (last!=cur) { ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ; glwm = ns * ainfo->gdrain_rate/1000000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -