/***************************************************************************\ |* *| |* 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
*/
/****************************************************************************\ * * * The video arbitration routines calculate some "magic" numbers. Fixes * * the snow seen when accessing the framebuffer without it. * * It just works (I hope). * * *
\****************************************************************************/
typedefstruct { 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; typedefstruct { 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; typedefstruct { 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; typedefstruct { int graphics_lwm; int video_lwm; int graphics_burst_size; int video_burst_size; int valid;
} nv4_fifo_info; typedefstruct { 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; typedefstruct { int graphics_lwm; int video_lwm; int graphics_burst_size; int video_burst_size; int valid;
} nv10_fifo_info; typedefstruct { int pclk_khz; int mclk_khz; int nvclk_khz; char mem_page_miss; char mem_latency;
u32 memory_type; int memory_width; char enable_video; char gr_during_vid; char pix_bpp; char mem_aligned; char enable_mp;
} nv10_sim_state; staticint 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; int last, next, cur; int max_gfsize ; long ns;
mclks += 2; /* tc_req latency fifo */
mclks += 2; /* fb_cas_n_ memory request to fbio block */
mclks += 7; /* sm_d_rdv data returned from fbio block */
/* fb.rd.d.Put_gc need to accumulate 256 bits for read */ if (arb->memory_type == 0) if (arb->memory_width == 64) /* 64 bit bus */
mclks += 4; else
mclks += 2; else if (arb->memory_width == 64) /* 64 bit bus */
mclks += 2; else
mclks += 1;
nvclks += 1; /* 2 edge sync. may be very close to edge so just put one. */
nvclks += 1; /* fbi_d_rdv_n */
nvclks += 1; /* Fbi_d_rdata */
nvclks += 1; /* crtfifo load */
if(mp_enable)
mclks+=4; /* Mp can get in with a burst of 8. */ /* Extra clocks determined by heuristics */
nvclks += 0;
pclks += 0;
found = 0; while(found != 1) {
fifo->valid = 1;
found = 1;
mclk_loop = mclks+mclk_extra;
us_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
us_m_min = mclks * 1000*1000 / mclk_freq; /* Minimum Mclk latency in us */
us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq;
us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */
us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */
us_pipe_min = us_m_min + us_n + us_p;
vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
/* // // Another concern, only for high pclks so don't do this // with video: // What happens if the latency to fetch the cbs is so large that // fifo empties. In that case we need to have an alternate clwm value // based off the total burst fetch // us_crt = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ; us_crt = us_crt + us_m + us_n + us_p + (4 * 1000 * 1000)/mclk_freq; clwm_mt = us_crt * crtc_drain_rate/(1000*1000); clwm_mt ++; if(clwm_mt > clwm) clwm = clwm_mt;
*/ /* Finally, a heuristic check when width == 64 bits */ if(width == 1){
nvclk_fill = nvclk_freq * 8; if(crtc_drain_rate * 100 >= nvclk_fill * 102)
clwm = 0xfff; /*Large number to fail */
/* * Calculate the Video Clock parameters for the PLL.
*/ staticint CalcVClock
( int clockIn, int *clockOut, int *mOut, int *nOut, int *pOut,
RIVA_HW_INST *chip
)
{ unsigned lowM, highM, highP; unsigned DeltaNew, DeltaOld; unsigned VClk, Freq; unsigned M, N, P;
highP = 4 - (chip->Architecture == NV_ARCH_03); for (P = 0; P <= highP; P ++)
{
Freq = VClk << P; if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
{ for (M = lowM; M <= highM; M++)
{
N = (VClk << P) * M / chip->CrystalFreqKHz; if(N <= 255) {
Freq = (chip->CrystalFreqKHz * N / M) >> P; if (Freq > VClk)
DeltaNew = Freq - VClk; else
DeltaNew = VClk - Freq; if (DeltaNew < DeltaOld)
{
*mOut = M;
*nOut = N;
*pOut = P;
*clockOut = Freq;
DeltaOld = DeltaNew;
}
}
}
}
}
/* non-zero: M/N/P/clock values assigned. zero: error (not set) */ return (DeltaOld != 0xFFFFFFFF);
} /* * Calculate extended mode parameters (SVGA) and save in a * mode state structure.
*/ int CalcStateExt
(
RIVA_HW_INST *chip,
RIVA_HW_STATE *state, struct pci_dev *pdev, int bpp, int width, int hDisplaySize, int height, int dotClock
)
{ int pixelDepth; int VClk, m, n, p;
/* * Save mode parameters.
*/
state->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
state->width = width;
state->height = height; /* * Extended RIVA registers.
*/
pixelDepth = (bpp + 1)/8; if (!CalcVClock(dotClock, &VClk, &m, &n, &p, chip)) return -EINVAL;
/* Paul Richards: below if block borks things in kernel for some reason */ /* Tony: Below is needed to set hardware in DirectColor */ if((bpp != 8) && (chip->Architecture != NV_ARCH_03))
state->general |= 0x00000030;
return 0;
} /* * Load fixed function state and pre-calculated/stored state.
*/ #define LOAD_FIXED_STATE(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \
NV_WR32(&chip->dev[tbl##Table##dev[i][0]], 0, tbl##Table##dev[i][1]) #define LOAD_FIXED_STATE_8BPP(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \
NV_WR32(&chip->dev[tbl##Table##dev##_8BPP[i][0]], 0, tbl##Table##dev##_8BPP[i][1]) #define LOAD_FIXED_STATE_15BPP(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \
NV_WR32(&chip->dev[tbl##Table##dev##_15BPP[i][0]], 0, tbl##Table##dev##_15BPP[i][1]) #define LOAD_FIXED_STATE_16BPP(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \
NV_WR32(&chip->dev[tbl##Table##dev##_16BPP[i][0]], 0, tbl##Table##dev##_16BPP[i][1]) #define LOAD_FIXED_STATE_32BPP(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \
NV_WR32(&chip->dev[tbl##Table##dev##_32BPP[i][0]], 0, tbl##Table##dev##_32BPP[i][1])
staticvoid UpdateFifoState
(
RIVA_HW_INST *chip
)
{ int i;
switch (chip->Architecture)
{ case NV_ARCH_04:
LOAD_FIXED_STATE(nv4,FIFO);
chip->Tri03 = NULL;
chip->Tri05 = (RivaTexturedTriangle05 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: /* * Initialize state for the RivaTriangle3D05 routines.
*/
LOAD_FIXED_STATE(nv10tri05,PGRAPH);
LOAD_FIXED_STATE(nv10,FIFO);
chip->Tri03 = NULL;
chip->Tri05 = (RivaTexturedTriangle05 __iomem *)&(chip->FIFO[0x0000E000/4]); break;
}
} staticvoid LoadStateExt
(
RIVA_HW_INST *chip,
RIVA_HW_STATE *state
)
{ int i;
/* * Load HW fixed function state.
*/
LOAD_FIXED_STATE(Riva,PMC);
LOAD_FIXED_STATE(Riva,PTIMER); switch (chip->Architecture)
{ case NV_ARCH_03: /* * Make sure frame buffer config gets set before loading PRAMIN.
*/
NV_WR32(chip->PFB, 0x00000200, state->config);
LOAD_FIXED_STATE(nv3,PFIFO);
LOAD_FIXED_STATE(nv3,PRAMIN);
LOAD_FIXED_STATE(nv3,PGRAPH); switch (state->bpp)
{ case 15: case 16:
LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 24: case 32:
LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
chip->Tri03 = NULL; break; case 8: default:
LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
chip->Tri03 = NULL; break;
} for (i = 0x00000; i < 0x00800; i++)
NV_WR32(&chip->PRAMIN[0x00000502 + i], 0, (i << 12) | 0x03);
NV_WR32(chip->PGRAPH, 0x00000630, state->offset0);
NV_WR32(chip->PGRAPH, 0x00000634, state->offset1);
NV_WR32(chip->PGRAPH, 0x00000638, state->offset2);
NV_WR32(chip->PGRAPH, 0x0000063C, state->offset3);
NV_WR32(chip->PGRAPH, 0x00000650, state->pitch0);
NV_WR32(chip->PGRAPH, 0x00000654, state->pitch1);
NV_WR32(chip->PGRAPH, 0x00000658, state->pitch2);
NV_WR32(chip->PGRAPH, 0x0000065C, state->pitch3); break; case NV_ARCH_04: /* * Make sure frame buffer config gets set before loading PRAMIN.
*/
NV_WR32(chip->PFB, 0x00000200, state->config);
LOAD_FIXED_STATE(nv4,PFIFO);
LOAD_FIXED_STATE(nv4,PRAMIN);
LOAD_FIXED_STATE(nv4,PGRAPH); switch (state->bpp)
{ case 15:
LOAD_FIXED_STATE_15BPP(nv4,PRAMIN);
LOAD_FIXED_STATE_15BPP(nv4,PGRAPH);
chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 16:
LOAD_FIXED_STATE_16BPP(nv4,PRAMIN);
LOAD_FIXED_STATE_16BPP(nv4,PGRAPH);
chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 24: case 32:
LOAD_FIXED_STATE_32BPP(nv4,PRAMIN);
LOAD_FIXED_STATE_32BPP(nv4,PGRAPH);
chip->Tri03 = NULL; break; case 8: default:
LOAD_FIXED_STATE_8BPP(nv4,PRAMIN);
LOAD_FIXED_STATE_8BPP(nv4,PGRAPH);
chip->Tri03 = NULL; break;
}
NV_WR32(chip->PGRAPH, 0x00000640, state->offset0);
NV_WR32(chip->PGRAPH, 0x00000644, state->offset1);
NV_WR32(chip->PGRAPH, 0x00000648, state->offset2);
NV_WR32(chip->PGRAPH, 0x0000064C, state->offset3);
NV_WR32(chip->PGRAPH, 0x00000670, state->pitch0);
NV_WR32(chip->PGRAPH, 0x00000674, state->pitch1);
NV_WR32(chip->PGRAPH, 0x00000678, state->pitch2);
NV_WR32(chip->PGRAPH, 0x0000067C, state->pitch3); break; case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: if(chip->twoHeads) {
VGA_WR08(chip->PCIO, 0x03D4, 0x44);
VGA_WR08(chip->PCIO, 0x03D5, state->crtcOwner);
chip->LockUnlock(chip, 0);
}
LOAD_FIXED_STATE(nv10,PFIFO);
LOAD_FIXED_STATE(nv10,PRAMIN);
LOAD_FIXED_STATE(nv10,PGRAPH); switch (state->bpp)
{ case 15:
LOAD_FIXED_STATE_15BPP(nv10,PRAMIN);
LOAD_FIXED_STATE_15BPP(nv10,PGRAPH);
chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 16:
LOAD_FIXED_STATE_16BPP(nv10,PRAMIN);
LOAD_FIXED_STATE_16BPP(nv10,PGRAPH);
chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 24: case 32:
LOAD_FIXED_STATE_32BPP(nv10,PRAMIN);
LOAD_FIXED_STATE_32BPP(nv10,PGRAPH);
chip->Tri03 = NULL; break; case 8: default:
LOAD_FIXED_STATE_8BPP(nv10,PRAMIN);
LOAD_FIXED_STATE_8BPP(nv10,PGRAPH);
chip->Tri03 = NULL; break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.