2005-04-16 15:20:36 -07:00
/***************************************************************************\
| * * |
| * 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 3 D 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 256
typedef 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 ;
2008-04-28 02:15:33 -07:00
u32 memory_type ;
2005-04-16 15:20:36 -07:00
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 ;
glwm = ainfo - > gocc - glwm ;
}
ns = 1000000 * ( misses * state - > mem_page_miss + ainfo - > gburst_size / ( state - > memory_width / 8 ) ) / state - > mclk_khz ;
ainfo - > vocc = ainfo - > vocc + 0 - ns * ainfo - > vdrain_rate / 1000000 ;
ainfo - > gocc = ainfo - > gocc + ainfo - > gburst_size - ns * ainfo - > gdrain_rate / 1000000 ;
ainfo - > mocc = ainfo - > mocc + 0 - ns * ainfo - > mdrain_rate / 1000000 ;
break ;
default :
if ( last = = cur ) misses = 0 ;
else if ( ainfo - > first_macc ) misses = mmisses ;
else misses = 1 ;
ainfo - > first_macc = 0 ;
ns = 1000000 * ( misses * state - > mem_page_miss + mburst_size / ( state - > memory_width / 8 ) ) / state - > mclk_khz ;
ainfo - > vocc = ainfo - > vocc + 0 - ns * ainfo - > vdrain_rate / 1000000 ;
ainfo - > gocc = ainfo - > gocc + 0 - ns * ainfo - > gdrain_rate / 1000000 ;
ainfo - > mocc = ainfo - > mocc + mburst_size - ns * ainfo - > mdrain_rate / 1000000 ;
break ;
}
if ( iter > 100 )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
ns = 1000000 * ainfo - > gburst_size / ( state - > memory_width / 8 ) / state - > mclk_khz ;
tmp = ns * ainfo - > gdrain_rate / 1000000 ;
if ( abs ( ainfo - > gburst_size ) + ( ( abs ( ainfo - > wcglwm ) + 16 ) & ~ 0x7 ) - tmp > max_gfsize )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
ns = 1000000 * ainfo - > vburst_size / ( state - > memory_width / 8 ) / state - > mclk_khz ;
tmp = ns * ainfo - > vdrain_rate / 1000000 ;
if ( abs ( ainfo - > vburst_size ) + ( abs ( ainfo - > wcvlwm + 32 ) & ~ 0xf ) - tmp > VFIFO_SIZE )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
if ( abs ( ainfo - > gocc ) > max_gfsize )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
if ( abs ( ainfo - > vocc ) > VFIFO_SIZE )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
if ( abs ( ainfo - > mocc ) > MFIFO_SIZE )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
if ( abs ( vfsize ) > VFIFO_SIZE )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
if ( abs ( gfsize ) > max_gfsize )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
if ( abs ( mfsize ) > MFIFO_SIZE )
{
ainfo - > converged = 0 ;
return ( 1 ) ;
}
}
}
static char nv3_arb ( nv3_fifo_info * res_info , nv3_sim_state * state , nv3_arb_info * ainfo )
{
long ens , vns , mns , gns ;
int mmisses , gmisses , vmisses , eburst_size , mburst_size ;
int refresh_cycle ;
refresh_cycle = 0 ;
refresh_cycle = 2 * ( state - > mclk_khz / state - > pclk_khz ) + 5 ;
mmisses = 2 ;
if ( state - > mem_aligned ) gmisses = 2 ;
else gmisses = 3 ;
vmisses = 2 ;
eburst_size = state - > memory_width * 1 ;
mburst_size = 32 ;
gns = 1000000 * ( gmisses * state - > mem_page_miss + state - > mem_latency ) / state - > mclk_khz ;
ainfo - > by_gfacc = gns * ainfo - > gdrain_rate / 1000000 ;
ainfo - > wcmocc = 0 ;
ainfo - > wcgocc = 0 ;
ainfo - > wcvocc = 0 ;
ainfo - > wcvlwm = 0 ;
ainfo - > wcglwm = 0 ;
ainfo - > engine_en = 1 ;
ainfo - > converged = 1 ;
if ( ainfo - > engine_en )
{
ens = 1000000 * ( state - > mem_page_miss + eburst_size / ( state - > memory_width / 8 ) + refresh_cycle ) / state - > mclk_khz ;
ainfo - > mocc = state - > enable_mp ? 0 - ens * ainfo - > mdrain_rate / 1000000 : 0 ;
ainfo - > vocc = ainfo - > vid_en ? 0 - ens * ainfo - > vdrain_rate / 1000000 : 0 ;
ainfo - > gocc = ainfo - > gr_en ? 0 - ens * ainfo - > gdrain_rate / 1000000 : 0 ;
ainfo - > cur = ENGINE ;
ainfo - > first_vacc = 1 ;
ainfo - > first_gacc = 1 ;
ainfo - > first_macc = 1 ;
nv3_iterate ( res_info , state , ainfo ) ;
}
if ( state - > enable_mp )
{
mns = 1000000 * ( mmisses * state - > mem_page_miss + mburst_size / ( state - > memory_width / 8 ) + refresh_cycle ) / state - > mclk_khz ;
ainfo - > mocc = state - > enable_mp ? 0 : mburst_size - mns * ainfo - > mdrain_rate / 1000000 ;
ainfo - > vocc = ainfo - > vid_en ? 0 : 0 - mns * ainfo - > vdrain_rate / 1000000 ;
ainfo - > gocc = ainfo - > gr_en ? 0 : 0 - mns * ainfo - > gdrain_rate / 1000000 ;
ainfo - > cur = MPORT ;
ainfo - > first_vacc = 1 ;
ainfo - > first_gacc = 1 ;
ainfo - > first_macc = 0 ;
nv3_iterate ( res_info , state , ainfo ) ;
}
if ( ainfo - > gr_en )
{
ainfo - > first_vacc = 1 ;
ainfo - > first_gacc = 0 ;
ainfo - > first_macc = 1 ;
gns = 1000000 * ( gmisses * state - > mem_page_miss + ainfo - > gburst_size / ( state - > memory_width / 8 ) + refresh_cycle ) / state - > mclk_khz ;
ainfo - > gocc = ainfo - > gburst_size - gns * ainfo - > gdrain_rate / 1000000 ;
ainfo - > vocc = ainfo - > vid_en ? 0 - gns * ainfo - > vdrain_rate / 1000000 : 0 ;
ainfo - > mocc = state - > enable_mp ? 0 - gns * ainfo - > mdrain_rate / 1000000 : 0 ;
ainfo - > cur = GRAPHICS ;
nv3_iterate ( res_info , state , ainfo ) ;
}
if ( ainfo - > vid_en )
{
ainfo - > first_vacc = 0 ;
ainfo - > first_gacc = 1 ;
ainfo - > first_macc = 1 ;
vns = 1000000 * ( vmisses * state - > mem_page_miss + ainfo - > vburst_size / ( state - > memory_width / 8 ) + refresh_cycle ) / state - > mclk_khz ;
ainfo - > vocc = ainfo - > vburst_size - vns * ainfo - > vdrain_rate / 1000000 ;
ainfo - > gocc = ainfo - > gr_en ? ( 0 - vns * ainfo - > gdrain_rate / 1000000 ) : 0 ;
ainfo - > mocc = state - > enable_mp ? 0 - vns * ainfo - > mdrain_rate / 1000000 : 0 ;
ainfo - > cur = VIDEO ;
nv3_iterate ( res_info , state , ainfo ) ;
}
if ( ainfo - > converged )
{
res_info - > graphics_lwm = ( int ) abs ( ainfo - > wcglwm ) + 16 ;
res_info - > video_lwm = ( int ) abs ( ainfo - > wcvlwm ) + 32 ;
res_info - > graphics_burst_size = ainfo - > gburst_size ;
res_info - > video_burst_size = ainfo - > vburst_size ;
res_info - > graphics_hi_priority = ( ainfo - > priority = = GRAPHICS ) ;
res_info - > media_hi_priority = ( ainfo - > priority = = MPORT ) ;
if ( res_info - > video_lwm > 160 )
{
res_info - > graphics_lwm = 256 ;
res_info - > video_lwm = 128 ;
res_info - > graphics_burst_size = 64 ;
res_info - > video_burst_size = 64 ;
res_info - > graphics_hi_priority = 0 ;
res_info - > media_hi_priority = 0 ;
ainfo - > converged = 0 ;
return ( 0 ) ;
}
if ( res_info - > video_lwm > 128 )
{
res_info - > video_lwm = 128 ;
}
return ( 1 ) ;
}
else
{
res_info - > graphics_lwm = 256 ;
res_info - > video_lwm = 128 ;
res_info - > graphics_burst_size = 64 ;
res_info - > video_burst_size = 64 ;
res_info - > graphics_hi_priority = 0 ;
res_info - > media_hi_priority = 0 ;
return ( 0 ) ;
}
}
static char nv3_get_param ( nv3_fifo_info * res_info , nv3_sim_state * state , nv3_arb_info * ainfo )
{
int done , g , v , p ;
done = 0 ;
for ( p = 0 ; p < 2 ; p + + )
{
for ( g = 128 ; g > 32 ; g = g > > 1 )
{
for ( v = 128 ; v > = 32 ; v = v > > 1 )
{
ainfo - > priority = p ;
ainfo - > gburst_size = g ;
ainfo - > vburst_size = v ;
done = nv3_arb ( res_info , state , ainfo ) ;
if ( done & & ( g = = 128 ) )
if ( ( res_info - > graphics_lwm + g ) > 256 )
done = 0 ;
if ( done )
goto Done ;
}
}
}
Done :
return done ;
}
static void nv3CalcArbitration
(
nv3_fifo_info * res_info ,
nv3_sim_state * state
)
{
nv3_fifo_info save_info ;
nv3_arb_info ainfo ;
char res_gr , res_vid ;
ainfo . gr_en = 1 ;
ainfo . vid_en = state - > enable_video ;
ainfo . vid_only_once = 0 ;
ainfo . gr_only_once = 0 ;
ainfo . gdrain_rate = ( int ) state - > pclk_khz * ( state - > pix_bpp / 8 ) ;
ainfo . vdrain_rate = ( int ) state - > pclk_khz * 2 ;
if ( state - > video_scale ! = 0 )
ainfo . vdrain_rate = ainfo . vdrain_rate / state - > video_scale ;
ainfo . mdrain_rate = 33000 ;
res_info - > rtl_values = 0 ;
if ( ! state - > gr_during_vid & & state - > enable_video )
{
ainfo . gr_only_once = 1 ;
ainfo . gr_en = 1 ;
ainfo . gdrain_rate = 0 ;
res_vid = nv3_get_param ( res_info , state , & ainfo ) ;
res_vid = ainfo . converged ;
save_info . video_lwm = res_info - > video_lwm ;
save_info . video_burst_size = res_info - > video_burst_size ;
ainfo . vid_en = 1 ;
ainfo . vid_only_once = 1 ;
ainfo . gr_en = 1 ;
ainfo . gdrain_rate = ( int ) state - > pclk_khz * ( state - > pix_bpp / 8 ) ;
ainfo . vdrain_rate = 0 ;
res_gr = nv3_get_param ( res_info , state , & ainfo ) ;
res_gr = ainfo . converged ;
res_info - > video_lwm = save_info . video_lwm ;
res_info - > video_burst_size = save_info . video_burst_size ;
res_info - > valid = res_gr & res_vid ;
}
else
{
if ( ! ainfo . gr_en ) ainfo . gdrain_rate = 0 ;
if ( ! ainfo . vid_en ) ainfo . vdrain_rate = 0 ;
res_gr = nv3_get_param ( res_info , state , & ainfo ) ;
res_info - > valid = ainfo . converged ;
}
}
static void nv3UpdateArbitrationSettings
(
unsigned VClk ,
unsigned pixelDepth ,
unsigned * burst ,
unsigned * lwm ,
RIVA_HW_INST * chip
)
{
nv3_fifo_info fifo_data ;
nv3_sim_state sim_data ;
unsigned int M , N , P , pll , MClk ;
pll = NV_RD32 ( & chip - > PRAMDAC0 [ 0x00000504 / 4 ] , 0 ) ;
M = ( pll > > 0 ) & 0xFF ; N = ( pll > > 8 ) & 0xFF ; P = ( pll > > 16 ) & 0x0F ;
MClk = ( N * chip - > CrystalFreqKHz / M ) > > P ;
sim_data . pix_bpp = ( char ) pixelDepth ;
sim_data . enable_video = 0 ;
sim_data . enable_mp = 0 ;
sim_data . video_scale = 1 ;
sim_data . memory_width = ( NV_RD32 ( & chip - > PEXTDEV [ 0x00000000 / 4 ] , 0 ) & 0x10 ) ?
128 : 64 ;
sim_data . memory_width = 128 ;
sim_data . mem_latency = 9 ;
sim_data . mem_aligned = 1 ;
sim_data . mem_page_miss = 11 ;
sim_data . gr_during_vid = 0 ;
sim_data . pclk_khz = VClk ;
sim_data . mclk_khz = MClk ;
nv3CalcArbitration ( & fifo_data , & sim_data ) ;
if ( fifo_data . valid )
{
int b = fifo_data . graphics_burst_size > > 4 ;
* burst = 0 ;
while ( b > > = 1 )
( * burst ) + + ;
* lwm = fifo_data . graphics_lwm > > 3 ;
}
else
{
* lwm = 0x24 ;
* burst = 0x2 ;
}
}
static void nv4CalcArbitration
(
nv4_fifo_info * fifo ,
nv4_sim_state * arb
)
{
int data , pagemiss , cas , width , video_enable , color_key_enable , bpp , align ;
int nvclks , mclks , pclks , vpagemiss , crtpagemiss , vbs ;
int found , mclk_extra , mclk_loop , cbs , m1 , p1 ;
int mclk_freq , pclk_freq , nvclk_freq , mp_enable ;
int us_m , us_n , us_p , video_drain_rate , crtc_drain_rate ;
int vpm_us , us_video , vlwm , video_fill_us , cpm_us , us_crt , clwm ;
int craw , vraw ;
fifo - > valid = 1 ;
pclk_freq = arb - > pclk_khz ;
mclk_freq = arb - > mclk_khz ;
nvclk_freq = arb - > nvclk_khz ;
pagemiss = arb - > mem_page_miss ;
cas = arb - > mem_latency ;
width = arb - > memory_width > > 6 ;
video_enable = arb - > enable_video ;
color_key_enable = arb - > gr_during_vid ;
bpp = arb - > pix_bpp ;
align = arb - > mem_aligned ;
mp_enable = arb - > enable_mp ;
clwm = 0 ;
vlwm = 0 ;
cbs = 128 ;
pclks = 2 ;
nvclks = 2 ;
nvclks + = 2 ;
nvclks + = 1 ;
mclks = 5 ;
mclks + = 3 ;
mclks + = 1 ;
mclks + = cas ;
mclks + = 1 ;
mclks + = 1 ;
mclks + = 1 ;
mclks + = 1 ;
mclk_extra = 3 ;
nvclks + = 2 ;
nvclks + = 1 ;
nvclks + = 1 ;
nvclks + = 1 ;
if ( mp_enable )
mclks + = 4 ;
nvclks + = 0 ;
pclks + = 0 ;
found = 0 ;
vbs = 0 ;
while ( found ! = 1 )
{
fifo - > valid = 1 ;
found = 1 ;
mclk_loop = mclks + mclk_extra ;
us_m = mclk_loop * 1000 * 1000 / mclk_freq ;
us_n = nvclks * 1000 * 1000 / nvclk_freq ;
us_p = nvclks * 1000 * 1000 / pclk_freq ;
if ( video_enable )
{
video_drain_rate = pclk_freq * 2 ;
crtc_drain_rate = pclk_freq * bpp / 8 ;
vpagemiss = 2 ;
vpagemiss + = 1 ;
crtpagemiss = 2 ;
vpm_us = ( vpagemiss * pagemiss ) * 1000 * 1000 / mclk_freq ;
if ( nvclk_freq * 2 > mclk_freq * width )
video_fill_us = cbs * 1000 * 1000 / 16 / nvclk_freq ;
else
video_fill_us = cbs * 1000 * 1000 / ( 8 * width ) / mclk_freq ;
us_video = vpm_us + us_m + us_n + us_p + video_fill_us ;
vlwm = us_video * video_drain_rate / ( 1000 * 1000 ) ;
vlwm + + ;
vbs = 128 ;
if ( vlwm > 128 ) vbs = 64 ;
if ( vlwm > ( 256 - 64 ) ) vbs = 32 ;
if ( nvclk_freq * 2 > mclk_freq * width )
video_fill_us = vbs * 1000 * 1000 / 16 / nvclk_freq ;
else
video_fill_us = vbs * 1000 * 1000 / ( 8 * width ) / mclk_freq ;
cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq ;
us_crt =
us_video
+ video_fill_us
+ cpm_us
+ us_m + us_n + us_p
;
clwm = us_crt * crtc_drain_rate / ( 1000 * 1000 ) ;
clwm + + ;
}
else
{
crtc_drain_rate = pclk_freq * bpp / 8 ;
crtpagemiss = 2 ;
crtpagemiss + = 1 ;
cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq ;
us_crt = cpm_us + us_m + us_n + us_p ;
clwm = us_crt * crtc_drain_rate / ( 1000 * 1000 ) ;
clwm + + ;
}
m1 = clwm + cbs - 512 ;
p1 = m1 * pclk_freq / mclk_freq ;
p1 = p1 * bpp / 8 ;
if ( ( p1 < m1 ) & & ( m1 > 0 ) )
{
fifo - > valid = 0 ;
found = 0 ;
if ( mclk_extra = = 0 ) found = 1 ;
mclk_extra - - ;
}
else if ( video_enable )
{
if ( ( clwm > 511 ) | | ( vlwm > 255 ) )
{
fifo - > valid = 0 ;
found = 0 ;
if ( mclk_extra = = 0 ) found = 1 ;
mclk_extra - - ;
}
}
else
{
if ( clwm > 519 )
{
fifo - > valid = 0 ;
found = 0 ;
if ( mclk_extra = = 0 ) found = 1 ;
mclk_extra - - ;
}
}
craw = clwm ;
vraw = vlwm ;
if ( clwm < 384 ) clwm = 384 ;
if ( vlwm < 128 ) vlwm = 128 ;
data = ( int ) ( clwm ) ;
fifo - > graphics_lwm = data ;
fifo - > graphics_burst_size = 128 ;
data = ( int ) ( ( vlwm + 15 ) ) ;
fifo - > video_lwm = data ;
fifo - > video_burst_size = vbs ;
}
}
static void nv4UpdateArbitrationSettings
(
unsigned VClk ,
unsigned pixelDepth ,
unsigned * burst ,
unsigned * lwm ,
RIVA_HW_INST * chip
)
{
nv4_fifo_info fifo_data ;
nv4_sim_state sim_data ;
unsigned int M , N , P , pll , MClk , NVClk , cfg1 ;
pll = NV_RD32 ( & chip - > PRAMDAC0 [ 0x00000504 / 4 ] , 0 ) ;
M = ( pll > > 0 ) & 0xFF ; N = ( pll > > 8 ) & 0xFF ; P = ( pll > > 16 ) & 0x0F ;
MClk = ( N * chip - > CrystalFreqKHz / M ) > > P ;
pll = NV_RD32 ( & chip - > PRAMDAC0 [ 0x00000500 / 4 ] , 0 ) ;
M = ( pll > > 0 ) & 0xFF ; N = ( pll > > 8 ) & 0xFF ; P = ( pll > > 16 ) & 0x0F ;
NVClk = ( N * chip - > CrystalFreqKHz / M ) > > P ;
cfg1 = NV_RD32 ( & chip - > PFB [ 0x00000204 / 4 ] , 0 ) ;
sim_data . pix_bpp = ( char ) pixelDepth ;
sim_data . enable_video = 0 ;
sim_data . enable_mp = 0 ;
sim_data . memory_width = ( NV_RD32 ( & chip - > PEXTDEV [ 0x00000000 / 4 ] , 0 ) & 0x10 ) ?
128 : 64 ;
sim_data . mem_latency = ( char ) cfg1 & 0x0F ;
sim_data . mem_aligned = 1 ;
sim_data . mem_page_miss = ( char ) ( ( ( cfg1 > > 4 ) & 0x0F ) + ( ( cfg1 > > 31 ) & 0x01 ) ) ;
sim_data . gr_during_vid = 0 ;
sim_data . pclk_khz = VClk ;
sim_data . mclk_khz = MClk ;
sim_data . nvclk_khz = NVClk ;
nv4CalcArbitration ( & fifo_data , & sim_data ) ;
if ( fifo_data . valid )
{
int b = fifo_data . graphics_burst_size > > 4 ;
* burst = 0 ;
while ( b > > = 1 )
( * burst ) + + ;
* lwm = fifo_data . graphics_lwm > > 3 ;
}
}
static void nv10CalcArbitration
(
nv10_fifo_info * fifo ,
nv10_sim_state * arb
)
{
int data , pagemiss , cas , width , video_enable , color_key_enable , bpp , align ;
int nvclks , mclks , pclks , vpagemiss , crtpagemiss , vbs ;
int nvclk_fill , us_extra ;
int found , mclk_extra , mclk_loop , cbs , m1 ;
int mclk_freq , pclk_freq , nvclk_freq , mp_enable ;
int us_m , us_m_min , us_n , us_p , video_drain_rate , crtc_drain_rate ;
int vus_m , vus_n , vus_p ;
int vpm_us , us_video , vlwm , cpm_us , us_crt , clwm ;
int clwm_rnd_down ;
int craw , m2us , us_pipe , us_pipe_min , vus_pipe , p1clk , p2 ;
int pclks_2_top_fifo , min_mclk_extra ;
int us_min_mclk_extra ;
fifo - > valid = 1 ;
pclk_freq = arb - > pclk_khz ; /* freq in KHz */
mclk_freq = arb - > mclk_khz ;
nvclk_freq = arb - > nvclk_khz ;
pagemiss = arb - > mem_page_miss ;
cas = arb - > mem_latency ;
width = arb - > memory_width / 64 ;
video_enable = arb - > enable_video ;
color_key_enable = arb - > gr_during_vid ;
bpp = arb - > pix_bpp ;
align = arb - > mem_aligned ;
mp_enable = arb - > enable_mp ;
clwm = 0 ;
vlwm = 1024 ;
cbs = 512 ;
vbs = 512 ;
pclks = 4 ; /* lwm detect. */
nvclks = 3 ; /* lwm -> sync. */
nvclks + = 2 ; /* fbi bus cycles (1 req + 1 busy) */
mclks = 1 ; /* 2 edge sync. may be very close to edge so just put one. */
mclks + = 1 ; /* arb_hp_req */
mclks + = 5 ; /* ap_hp_req tiling pipeline */
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 ;
if ( ( ! video_enable ) & & ( arb - > memory_width = = 128 ) )
{
mclk_extra = ( bpp = = 32 ) ? 31 : 42 ; /* Margin of error */
min_mclk_extra = 17 ;
}
else
{
mclk_extra = ( bpp = = 32 ) ? 8 : 4 ; /* Margin of error */
/* mclk_extra = 4; */ /* Margin of error */
min_mclk_extra = 18 ;
}
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 = us_m + us_n + us_p ;
us_pipe_min = us_m_min + us_n + us_p ;
us_extra = 0 ;
vus_m = mclk_loop * 1000 * 1000 / mclk_freq ; /* Mclk latency in us */
vus_n = ( 4 ) * 1000 * 1000 / nvclk_freq ; /* nvclk latency in us */
vus_p = 0 * 1000 * 1000 / pclk_freq ; /* pclk latency in us */
vus_pipe = vus_m + vus_n + vus_p ;
if ( video_enable ) {
video_drain_rate = pclk_freq * 4 ; /* MB/s */
crtc_drain_rate = pclk_freq * bpp / 8 ; /* MB/s */
vpagemiss = 1 ; /* self generating page miss */
vpagemiss + = 1 ; /* One higher priority before */
crtpagemiss = 2 ; /* self generating page miss */
if ( mp_enable )
crtpagemiss + = 1 ; /* if MA0 conflict */
vpm_us = ( vpagemiss * pagemiss ) * 1000 * 1000 / mclk_freq ;
us_video = vpm_us + vus_m ; /* Video has separate read return path */
cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq ;
us_crt =
us_video /* Wait for video */
+ cpm_us /* CRT Page miss */
+ us_m + us_n + us_p /* other latency */
;
clwm = us_crt * crtc_drain_rate / ( 1000 * 1000 ) ;
clwm + + ; /* fixed point <= float_point - 1. Fixes that */
} else {
crtc_drain_rate = pclk_freq * bpp / 8 ; /* bpp * pclk/8 */
crtpagemiss = 1 ; /* self generating page miss */
crtpagemiss + = 1 ; /* MA0 page miss */
if ( mp_enable )
crtpagemiss + = 1 ; /* if MA0 conflict */
cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq ;
us_crt = cpm_us + us_m + us_n + us_p ;
clwm = us_crt * crtc_drain_rate / ( 1000 * 1000 ) ;
clwm + + ; /* fixed point <= float_point - 1. Fixes that */
/*
//
// 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 */
else if ( crtc_drain_rate * 100 > = nvclk_fill * 98 ) {
clwm = 1024 ;
cbs = 512 ;
us_extra = ( cbs * 1000 * 1000 ) / ( 8 * width ) / mclk_freq ;
}
}
}
/*
Overfill check :
*/
clwm_rnd_down = ( ( int ) clwm / 8 ) * 8 ;
if ( clwm_rnd_down < clwm )
clwm + = 8 ;
m1 = clwm + cbs - 1024 ; /* Amount of overfill */
m2us = us_pipe_min + us_min_mclk_extra ;
pclks_2_top_fifo = ( 1024 - clwm ) / ( 8 * width ) ;
/* pclk cycles to drain */
p1clk = m2us * pclk_freq / ( 1000 * 1000 ) ;
p2 = p1clk * bpp / 8 ; /* bytes drained. */
if ( ( p2 < m1 ) & & ( m1 > 0 ) ) {
fifo - > valid = 0 ;
found = 0 ;
if ( min_mclk_extra = = 0 ) {
if ( cbs < = 32 ) {
found = 1 ; /* Can't adjust anymore! */
} else {
cbs = cbs / 2 ; /* reduce the burst size */
}
} else {
min_mclk_extra - - ;
}
} else {
if ( clwm > 1023 ) { /* Have some margin */
fifo - > valid = 0 ;
found = 0 ;
if ( min_mclk_extra = = 0 )
found = 1 ; /* Can't adjust anymore! */
else
min_mclk_extra - - ;
}
}
craw = clwm ;
if ( clwm < ( 1024 - cbs + 8 ) ) clwm = 1024 - cbs + 8 ;
data = ( int ) ( clwm ) ;
/* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
fifo - > graphics_lwm = data ; fifo - > graphics_burst_size = cbs ;
/* printf("VID LWM: %f bytes, prog: 0x%x, bs: %d\n, ", vlwm, data, vbs ); */
fifo - > video_lwm = 1024 ; fifo - > video_burst_size = 512 ;
}
}
static void nv10UpdateArbitrationSettings
(
unsigned VClk ,
unsigned pixelDepth ,
unsigned * burst ,
unsigned * lwm ,
RIVA_HW_INST * chip
)
{
nv10_fifo_info fifo_data ;
nv10_sim_state sim_data ;
unsigned int M , N , P , pll , MClk , NVClk , cfg1 ;
pll = NV_RD32 ( & chip - > PRAMDAC0 [ 0x00000504 / 4 ] , 0 ) ;
M = ( pll > > 0 ) & 0xFF ; N = ( pll > > 8 ) & 0xFF ; P = ( pll > > 16 ) & 0x0F ;
MClk = ( N * chip - > CrystalFreqKHz / M ) > > P ;
pll = NV_RD32 ( & chip - > PRAMDAC0 [ 0x00000500 / 4 ] , 0 ) ;
M = ( pll > > 0 ) & 0xFF ; N = ( pll > > 8 ) & 0xFF ; P = ( pll > > 16 ) & 0x0F ;
NVClk = ( N * chip - > CrystalFreqKHz / M ) > > P ;
cfg1 = NV_RD32 ( & chip - > PFB [ 0x00000204 / 4 ] , 0 ) ;
sim_data . pix_bpp = ( char ) pixelDepth ;
sim_data . enable_video = 0 ;
sim_data . enable_mp = 0 ;
sim_data . memory_type = ( NV_RD32 ( & chip - > PFB [ 0x00000200 / 4 ] , 0 ) & 0x01 ) ?
1 : 0 ;
sim_data . memory_width = ( NV_RD32 ( & chip - > PEXTDEV [ 0x00000000 / 4 ] , 0 ) & 0x10 ) ?
128 : 64 ;
sim_data . mem_latency = ( char ) cfg1 & 0x0F ;
sim_data . mem_aligned = 1 ;
sim_data . mem_page_miss = ( char ) ( ( ( cfg1 > > 4 ) & 0x0F ) + ( ( cfg1 > > 31 ) & 0x01 ) ) ;
sim_data . gr_during_vid = 0 ;
sim_data . pclk_khz = VClk ;
sim_data . mclk_khz = MClk ;
sim_data . nvclk_khz = NVClk ;
nv10CalcArbitration ( & fifo_data , & sim_data ) ;
if ( fifo_data . valid )
{
int b = fifo_data . graphics_burst_size > > 4 ;
* burst = 0 ;
while ( b > > = 1 )
( * burst ) + + ;
* lwm = fifo_data . graphics_lwm > > 3 ;
}
}
static void nForceUpdateArbitrationSettings
(
unsigned VClk ,
unsigned pixelDepth ,
unsigned * burst ,
unsigned * lwm ,
RIVA_HW_INST * chip
)
{
nv10_fifo_info fifo_data ;
nv10_sim_state sim_data ;
unsigned int M , N , P , pll , MClk , NVClk ;
unsigned int uMClkPostDiv ;
struct pci_dev * dev ;
2007-05-08 00:39:28 -07:00
dev = pci_get_bus_and_slot ( 0 , 3 ) ;
2005-04-16 15:20:36 -07:00
pci_read_config_dword ( dev , 0x6C , & uMClkPostDiv ) ;
2007-05-08 00:39:28 -07:00
pci_dev_put ( dev ) ;
2005-04-16 15:20:36 -07:00
uMClkPostDiv = ( uMClkPostDiv > > 8 ) & 0xf ;
if ( ! uMClkPostDiv ) uMClkPostDiv = 4 ;
MClk = 400000 / uMClkPostDiv ;
pll = NV_RD32 ( & chip - > PRAMDAC0 [ 0x00000500 / 4 ] , 0 ) ;
M = ( pll > > 0 ) & 0xFF ; N = ( pll > > 8 ) & 0xFF ; P = ( pll > > 16 ) & 0x0F ;
NVClk = ( N * chip - > CrystalFreqKHz / M ) > > P ;
sim_data . pix_bpp = ( char ) pixelDepth ;
sim_data . enable_video = 0 ;
sim_data . enable_mp = 0 ;
2007-05-08 00:39:28 -07:00
dev = pci_get_bus_and_slot ( 0 , 1 ) ;
2005-04-16 15:20:36 -07:00
pci_read_config_dword ( dev , 0x7C , & sim_data . memory_type ) ;
2007-05-08 00:39:28 -07:00
pci_dev_put ( dev ) ;
2005-04-16 15:20:36 -07:00
sim_data . memory_type = ( sim_data . memory_type > > 12 ) & 1 ;
sim_data . memory_width = 64 ;
sim_data . mem_latency = 3 ;
sim_data . mem_aligned = 1 ;
sim_data . mem_page_miss = 10 ;
sim_data . gr_during_vid = 0 ;
sim_data . pclk_khz = VClk ;
sim_data . mclk_khz = MClk ;
sim_data . nvclk_khz = NVClk ;
nv10CalcArbitration ( & fifo_data , & sim_data ) ;
if ( fifo_data . valid )
{
int b = fifo_data . graphics_burst_size > > 4 ;
* burst = 0 ;
while ( b > > = 1 )
( * burst ) + + ;
* lwm = fifo_data . graphics_lwm > > 3 ;
}
}
/****************************************************************************\
* *
* RIVA Mode State Routines *
* *
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Calculate the Video Clock parameters for the PLL .
*/
static int 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 ;
DeltaOld = 0xFFFFFFFF ;
VClk = ( unsigned ) clockIn ;
if ( chip - > CrystalFreqKHz = = 13500 )
{
lowM = 7 ;
highM = 13 - ( chip - > Architecture = = NV_ARCH_03 ) ;
}
else
{
lowM = 8 ;
highM = 14 - ( chip - > Architecture = = NV_ARCH_03 ) ;
}
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 ;
}
}
}
}
}
2007-07-17 05:39:58 -04:00
/* non-zero: M/N/P/clock values assigned. zero: error (not set) */
2005-04-16 15:20:36 -07:00
return ( DeltaOld ! = 0xFFFFFFFF ) ;
}
/*
* Calculate extended mode parameters ( SVGA ) and save in a
* mode state structure .
*/
2006-12-08 02:40:17 -08:00
int CalcStateExt
2005-04-16 15:20:36 -07:00
(
RIVA_HW_INST * chip ,
RIVA_HW_STATE * state ,
int bpp ,
int width ,
int hDisplaySize ,
int height ,
int dotClock
)
{
2007-07-17 05:39:58 -04:00
int pixelDepth ;
int uninitialized_var ( VClk ) , uninitialized_var ( m ) ,
uninitialized_var ( n ) , uninitialized_var ( p ) ;
2005-04-16 15:20:36 -07:00
/*
* 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 ;
2006-12-08 02:40:17 -08:00
if ( ! CalcVClock ( dotClock , & VClk , & m , & n , & p , chip ) )
return - EINVAL ;
2005-04-16 15:20:36 -07:00
switch ( chip - > Architecture )
{
case NV_ARCH_03 :
nv3UpdateArbitrationSettings ( VClk ,
pixelDepth * 8 ,
& ( state - > arbitration0 ) ,
& ( state - > arbitration1 ) ,
chip ) ;
state - > cursor0 = 0x00 ;
state - > cursor1 = 0x78 ;
state - > cursor2 = 0x00000000 ;
state - > pllsel = 0x10010100 ;
state - > config = ( ( width + 31 ) / 32 )
| ( ( ( pixelDepth > 2 ) ? 3 : pixelDepth ) < < 8 )
| 0x1000 ;
state - > general = 0x00100100 ;
state - > repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02 ;
break ;
case NV_ARCH_04 :
nv4UpdateArbitrationSettings ( VClk ,
pixelDepth * 8 ,
& ( state - > arbitration0 ) ,
& ( state - > arbitration1 ) ,
chip ) ;
state - > cursor0 = 0x00 ;
state - > cursor1 = 0xFC ;
state - > cursor2 = 0x00000000 ;
state - > pllsel = 0x10000700 ;
state - > config = 0x00001114 ;
state - > general = bpp = = 16 ? 0x00101100 : 0x00100100 ;
state - > repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00 ;
break ;
case NV_ARCH_10 :
case NV_ARCH_20 :
case NV_ARCH_30 :
if ( ( chip - > Chipset = = NV_CHIP_IGEFORCE2 ) | |
( chip - > Chipset = = NV_CHIP_0x01F0 ) )
{
nForceUpdateArbitrationSettings ( VClk ,
pixelDepth * 8 ,
& ( state - > arbitration0 ) ,
& ( state - > arbitration1 ) ,
chip ) ;
} else {
nv10UpdateArbitrationSettings ( VClk ,
pixelDepth * 8 ,
& ( state - > arbitration0 ) ,
& ( state - > arbitration1 ) ,
chip ) ;
}
state - > cursor0 = 0x80 | ( chip - > CursorStart > > 17 ) ;
state - > cursor1 = ( chip - > CursorStart > > 11 ) < < 2 ;
state - > cursor2 = chip - > CursorStart > > 24 ;
state - > pllsel = 0x10000700 ;
state - > config = NV_RD32 ( & chip - > PFB [ 0x00000200 / 4 ] , 0 ) ;
state - > general = bpp = = 16 ? 0x00101100 : 0x00100100 ;
state - > repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00 ;
break ;
}
/* 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 ;
state - > vpll = ( p < < 16 ) | ( n < < 8 ) | m ;
state - > repaint0 = ( ( ( width / 8 ) * pixelDepth ) & 0x700 ) > > 3 ;
state - > pixel = pixelDepth > 2 ? 3 : pixelDepth ;
state - > offset0 =
state - > offset1 =
state - > offset2 =
state - > offset3 = 0 ;
state - > pitch0 =
state - > pitch1 =
state - > pitch2 =
state - > pitch3 = pixelDepth * width ;
2006-12-08 02:40:17 -08:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
/*
* Load fixed function state and pre - calculated / stored state .
*/
#if 0
# define LOAD_FIXED_STATE(tbl,dev) \
for ( i = 0 ; i < sizeof ( tbl # # Table # # dev ) / 8 ; i + + ) \
chip - > dev [ tbl # # Table # # dev [ i ] [ 0 ] ] = tbl # # Table # # dev [ i ] [ 1 ]
# define LOAD_FIXED_STATE_8BPP(tbl,dev) \
for ( i = 0 ; i < sizeof ( tbl # # Table # # dev # # _8BPP ) / 8 ; i + + ) \
chip - > dev [ tbl # # Table # # dev # # _8BPP [ i ] [ 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 + + ) \
chip - > dev [ tbl # # Table # # dev # # _15BPP [ i ] [ 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 + + ) \
chip - > dev [ tbl # # Table # # dev # # _16BPP [ i ] [ 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 + + ) \
chip - > dev [ tbl # # Table # # dev # # _32BPP [ i ] [ 0 ] ] = tbl # # Table # # dev # # _32BPP [ i ] [ 1 ]
# endif
# 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 ] )
static void 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 ;
}
}
static void 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 ;
}
if ( chip - > Architecture = = NV_ARCH_10 ) {
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 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000680 , state - > pitch3 ) ;
} else {
NV_WR32 ( chip - > PGRAPH , 0x00000820 , state - > offset0 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000824 , state - > offset1 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000828 , state - > offset2 ) ;
NV_WR32 ( chip - > PGRAPH , 0x0000082C , state - > offset3 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000850 , state - > pitch0 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000854 , state - > pitch1 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000858 , state - > pitch2 ) ;
NV_WR32 ( chip - > PGRAPH , 0x0000085C , state - > pitch3 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000860 , state - > pitch3 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000864 , state - > pitch3 ) ;
NV_WR32 ( chip - > PGRAPH , 0x000009A4 , NV_RD32 ( chip - > PFB , 0x00000200 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x000009A8 , NV_RD32 ( chip - > PFB , 0x00000204 ) ) ;
}
if ( chip - > twoHeads ) {
NV_WR32 ( chip - > PCRTC0 , 0x00000860 , state - > head ) ;
NV_WR32 ( chip - > PCRTC0 , 0x00002860 , state - > head2 ) ;
}
NV_WR32 ( chip - > PRAMDAC , 0x00000404 , NV_RD32 ( chip - > PRAMDAC , 0x00000404 ) | ( 1 < < 25 ) ) ;
NV_WR32 ( chip - > PMC , 0x00008704 , 1 ) ;
NV_WR32 ( chip - > PMC , 0x00008140 , 0 ) ;
NV_WR32 ( chip - > PMC , 0x00008920 , 0 ) ;
NV_WR32 ( chip - > PMC , 0x00008924 , 0 ) ;
NV_WR32 ( chip - > PMC , 0x00008908 , 0x01ffffff ) ;
NV_WR32 ( chip - > PMC , 0x0000890C , 0x01ffffff ) ;
NV_WR32 ( chip - > PMC , 0x00001588 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x00000240 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x00000250 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x00000260 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x00000270 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x00000280 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x00000290 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x000002A0 , 0 ) ;
NV_WR32 ( chip - > PFB , 0x000002B0 , 0 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B00 , NV_RD32 ( chip - > PFB , 0x00000240 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B04 , NV_RD32 ( chip - > PFB , 0x00000244 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B08 , NV_RD32 ( chip - > PFB , 0x00000248 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B0C , NV_RD32 ( chip - > PFB , 0x0000024C ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B10 , NV_RD32 ( chip - > PFB , 0x00000250 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B14 , NV_RD32 ( chip - > PFB , 0x00000254 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B18 , NV_RD32 ( chip - > PFB , 0x00000258 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B1C , NV_RD32 ( chip - > PFB , 0x0000025C ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B20 , NV_RD32 ( chip - > PFB , 0x00000260 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B24 , NV_RD32 ( chip - > PFB , 0x00000264 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B28 , NV_RD32 ( chip - > PFB , 0x00000268 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B2C , NV_RD32 ( chip - > PFB , 0x0000026C ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B30 , NV_RD32 ( chip - > PFB , 0x00000270 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B34 , NV_RD32 ( chip - > PFB , 0x00000274 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B38 , NV_RD32 ( chip - > PFB , 0x00000278 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B3C , NV_RD32 ( chip - > PFB , 0x0000027C ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B40 , NV_RD32 ( chip - > PFB , 0x00000280 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B44 , NV_RD32 ( chip - > PFB , 0x00000284 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B48 , NV_RD32 ( chip - > PFB , 0x00000288 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B4C , NV_RD32 ( chip - > PFB , 0x0000028C ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B50 , NV_RD32 ( chip - > PFB , 0x00000290 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B54 , NV_RD32 ( chip - > PFB , 0x00000294 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B58 , NV_RD32 ( chip - > PFB , 0x00000298 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B5C , NV_RD32 ( chip - > PFB , 0x0000029C ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B60 , NV_RD32 ( chip - > PFB , 0x000002A0 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B64 , NV_RD32 ( chip - > PFB , 0x000002A4 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B68 , NV_RD32 ( chip - > PFB , 0x000002A8 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B6C , NV_RD32 ( chip - > PFB , 0x000002AC ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B70 , NV_RD32 ( chip - > PFB , 0x000002B0 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B74 , NV_RD32 ( chip - > PFB , 0x000002B4 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B78 , NV_RD32 ( chip - > PFB , 0x000002B8 ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000B7C , NV_RD32 ( chip - > PFB , 0x000002BC ) ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F40 , 0x10000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F44 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00000040 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000008 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00000200 ) ;
for ( i = 0 ; i < ( 3 * 16 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00000040 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00000800 ) ;
for ( i = 0 ; i < ( 16 * 16 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F40 , 0x30000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F44 , 0x00000004 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00006400 ) ;
for ( i = 0 ; i < ( 59 * 4 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00006800 ) ;
for ( i = 0 ; i < ( 47 * 4 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00006C00 ) ;
for ( i = 0 ; i < ( 3 * 4 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00007000 ) ;
for ( i = 0 ; i < ( 19 * 4 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00007400 ) ;
for ( i = 0 ; i < ( 12 * 4 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00007800 ) ;
for ( i = 0 ; i < ( 12 * 4 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00004400 ) ;
for ( i = 0 ; i < ( 8 * 4 ) ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00000000 ) ;
for ( i = 0 ; i < 16 ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PGRAPH , 0x00000F50 , 0x00000040 ) ;
for ( i = 0 ; i < 4 ; i + + )
NV_WR32 ( chip - > PGRAPH , 0x00000F54 , 0x00000000 ) ;
NV_WR32 ( chip - > PCRTC , 0x00000810 , state - > cursorConfig ) ;
if ( chip - > flatPanel ) {
if ( ( chip - > Chipset & 0x0ff0 ) = = 0x0110 ) {
NV_WR32 ( chip - > PRAMDAC , 0x0528 , state - > dither ) ;
} else
if ( ( chip - > Chipset & 0x0ff0 ) > = 0x0170 ) {
NV_WR32 ( chip - > PRAMDAC , 0x083C , state - > dither ) ;
}
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x53 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , 0 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x54 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , 0 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x21 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , 0xfa ) ;
}
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x41 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > extra ) ;
}
LOAD_FIXED_STATE ( Riva , FIFO ) ;
UpdateFifoState ( chip ) ;
/*
* Load HW mode state .
*/
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x19 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > repaint0 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x1A ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > repaint1 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x25 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > screen ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x28 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > pixel ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x2D ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > horiz ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x1B ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > arbitration0 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x20 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > arbitration1 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x30 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > cursor0 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x31 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > cursor1 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x2F ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > cursor2 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x39 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D5 , state - > interlace ) ;
if ( ! chip - > flatPanel ) {
NV_WR32 ( chip - > PRAMDAC0 , 0x00000508 , state - > vpll ) ;
NV_WR32 ( chip - > PRAMDAC0 , 0x0000050C , state - > pllsel ) ;
if ( chip - > twoHeads )
NV_WR32 ( chip - > PRAMDAC0 , 0x00000520 , state - > vpll2 ) ;
} else {
NV_WR32 ( chip - > PRAMDAC , 0x00000848 , state - > scale ) ;
}
NV_WR32 ( chip - > PRAMDAC , 0x00000600 , state - > general ) ;
/*
* Turn off VBlank enable and reset .
*/
NV_WR32 ( chip - > PCRTC , 0x00000140 , 0 ) ;
NV_WR32 ( chip - > PCRTC , 0x00000100 , chip - > VBlankBit ) ;
/*
* Set interrupt enable .
*/
NV_WR32 ( chip - > PMC , 0x00000140 , chip - > EnableIRQ & 0x01 ) ;
/*
* Set current state pointer .
*/
chip - > CurrentState = state ;
/*
* Reset FIFO free and empty counts .
*/
chip - > FifoFreeCount = 0 ;
/* Free count from first subchannel */
chip - > FifoEmptyCount = NV_RD32 ( & chip - > Rop - > FifoFree , 0 ) ;
}
static void UnloadStateExt
(
RIVA_HW_INST * chip ,
RIVA_HW_STATE * state
)
{
/*
* Save current HW state .
*/
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x19 ) ;
state - > repaint0 = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x1A ) ;
state - > repaint1 = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x25 ) ;
state - > screen = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x28 ) ;
state - > pixel = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x2D ) ;
state - > horiz = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x1B ) ;
state - > arbitration0 = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x20 ) ;
state - > arbitration1 = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x30 ) ;
state - > cursor0 = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x31 ) ;
state - > cursor1 = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x2F ) ;
state - > cursor2 = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x39 ) ;
state - > interlace = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
state - > vpll = NV_RD32 ( chip - > PRAMDAC0 , 0x00000508 ) ;
state - > vpll2 = NV_RD32 ( chip - > PRAMDAC0 , 0x00000520 ) ;
state - > pllsel = NV_RD32 ( chip - > PRAMDAC0 , 0x0000050C ) ;
state - > general = NV_RD32 ( chip - > PRAMDAC , 0x00000600 ) ;
state - > scale = NV_RD32 ( chip - > PRAMDAC , 0x00000848 ) ;
state - > config = NV_RD32 ( chip - > PFB , 0x00000200 ) ;
switch ( chip - > Architecture )
{
case NV_ARCH_03 :
state - > offset0 = NV_RD32 ( chip - > PGRAPH , 0x00000630 ) ;
state - > offset1 = NV_RD32 ( chip - > PGRAPH , 0x00000634 ) ;
state - > offset2 = NV_RD32 ( chip - > PGRAPH , 0x00000638 ) ;
state - > offset3 = NV_RD32 ( chip - > PGRAPH , 0x0000063C ) ;
state - > pitch0 = NV_RD32 ( chip - > PGRAPH , 0x00000650 ) ;
state - > pitch1 = NV_RD32 ( chip - > PGRAPH , 0x00000654 ) ;
state - > pitch2 = NV_RD32 ( chip - > PGRAPH , 0x00000658 ) ;
state - > pitch3 = NV_RD32 ( chip - > PGRAPH , 0x0000065C ) ;
break ;
case NV_ARCH_04 :
state - > offset0 = NV_RD32 ( chip - > PGRAPH , 0x00000640 ) ;
state - > offset1 = NV_RD32 ( chip - > PGRAPH , 0x00000644 ) ;
state - > offset2 = NV_RD32 ( chip - > PGRAPH , 0x00000648 ) ;
state - > offset3 = NV_RD32 ( chip - > PGRAPH , 0x0000064C ) ;
state - > pitch0 = NV_RD32 ( chip - > PGRAPH , 0x00000670 ) ;
state - > pitch1 = NV_RD32 ( chip - > PGRAPH , 0x00000674 ) ;
state - > pitch2 = NV_RD32 ( chip - > PGRAPH , 0x00000678 ) ;
state - > pitch3 = NV_RD32 ( chip - > PGRAPH , 0x0000067C ) ;
break ;
case NV_ARCH_10 :
case NV_ARCH_20 :
case NV_ARCH_30 :
state - > offset0 = NV_RD32 ( chip - > PGRAPH , 0x00000640 ) ;
state - > offset1 = NV_RD32 ( chip - > PGRAPH , 0x00000644 ) ;
state - > offset2 = NV_RD32 ( chip - > PGRAPH , 0x00000648 ) ;
state - > offset3 = NV_RD32 ( chip - > PGRAPH , 0x0000064C ) ;
state - > pitch0 = NV_RD32 ( chip - > PGRAPH , 0x00000670 ) ;
state - > pitch1 = NV_RD32 ( chip - > PGRAPH , 0x00000674 ) ;
state - > pitch2 = NV_RD32 ( chip - > PGRAPH , 0x00000678 ) ;
state - > pitch3 = NV_RD32 ( chip - > PGRAPH , 0x0000067C ) ;
if ( chip - > twoHeads ) {
state - > head = NV_RD32 ( chip - > PCRTC0 , 0x00000860 ) ;
state - > head2 = NV_RD32 ( chip - > PCRTC0 , 0x00002860 ) ;
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x44 ) ;
state - > crtcOwner = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
}
VGA_WR08 ( chip - > PCIO , 0x03D4 , 0x41 ) ;
state - > extra = VGA_RD08 ( chip - > PCIO , 0x03D5 ) ;
state - > cursorConfig = NV_RD32 ( chip - > PCRTC , 0x00000810 ) ;
if ( ( chip - > Chipset & 0x0ff0 ) = = 0x0110 ) {
state - > dither = NV_RD32 ( chip - > PRAMDAC , 0x0528 ) ;
} else
if ( ( chip - > Chipset & 0x0ff0 ) > = 0x0170 ) {
state - > dither = NV_RD32 ( chip - > PRAMDAC , 0x083C ) ;
}
break ;
}
}
static void SetStartAddress
(
RIVA_HW_INST * chip ,
unsigned start
)
{
NV_WR32 ( chip - > PCRTC , 0x800 , start ) ;
}
static void SetStartAddress3
(
RIVA_HW_INST * chip ,
unsigned start
)
{
int offset = start > > 2 ;
int pan = ( start & 3 ) < < 1 ;
unsigned char tmp ;
/*
* Unlock extended registers .
*/
chip - > LockUnlock ( chip , 0 ) ;
/*
* Set start address .
*/
VGA_WR08 ( chip - > PCIO , 0x3D4 , 0x0D ) ; VGA_WR08 ( chip - > PCIO , 0x3D5 , offset ) ;
offset > > = 8 ;
VGA_WR08 ( chip - > PCIO , 0x3D4 , 0x0C ) ; VGA_WR08 ( chip - > PCIO , 0x3D5 , offset ) ;
offset > > = 8 ;
VGA_WR08 ( chip - > PCIO , 0x3D4 , 0x19 ) ; tmp = VGA_RD08 ( chip - > PCIO , 0x3D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x3D5 , ( offset & 0x01F ) | ( tmp & ~ 0x1F ) ) ;
VGA_WR08 ( chip - > PCIO , 0x3D4 , 0x2D ) ; tmp = VGA_RD08 ( chip - > PCIO , 0x3D5 ) ;
VGA_WR08 ( chip - > PCIO , 0x3D5 , ( offset & 0x60 ) | ( tmp & ~ 0x60 ) ) ;
/*
* 4 pixel pan register .
*/
offset = VGA_RD08 ( chip - > PCIO , chip - > IO + 0x0A ) ;
VGA_WR08 ( chip - > PCIO , 0x3C0 , 0x13 ) ;
VGA_WR08 ( chip - > PCIO , 0x3C0 , pan ) ;
}
static void nv3SetSurfaces2D
(
RIVA_HW_INST * chip ,
unsigned surf0 ,
unsigned surf1
)
{
RivaSurface __iomem * Surface =
( RivaSurface __iomem * ) & ( chip - > FIFO [ 0x0000E000 / 4 ] ) ;
RIVA_FIFO_FREE ( * chip , Tri03 , 5 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000003 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf0 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000004 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf1 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000013 ) ;
}
static void nv4SetSurfaces2D
(
RIVA_HW_INST * chip ,
unsigned surf0 ,
unsigned surf1
)
{
RivaSurface __iomem * Surface =
( RivaSurface __iomem * ) & ( chip - > FIFO [ 0x0000E000 / 4 ] ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000003 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf0 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000004 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf1 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000014 ) ;
}
static void nv10SetSurfaces2D
(
RIVA_HW_INST * chip ,
unsigned surf0 ,
unsigned surf1
)
{
RivaSurface __iomem * Surface =
( RivaSurface __iomem * ) & ( chip - > FIFO [ 0x0000E000 / 4 ] ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000003 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf0 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000004 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf1 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000014 ) ;
}
static void nv3SetSurfaces3D
(
RIVA_HW_INST * chip ,
unsigned surf0 ,
unsigned surf1
)
{
RivaSurface __iomem * Surface =
( RivaSurface __iomem * ) & ( chip - > FIFO [ 0x0000E000 / 4 ] ) ;
RIVA_FIFO_FREE ( * chip , Tri03 , 5 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000005 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf0 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000006 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf1 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000013 ) ;
}
static void nv4SetSurfaces3D
(
RIVA_HW_INST * chip ,
unsigned surf0 ,
unsigned surf1
)
{
RivaSurface __iomem * Surface =
( RivaSurface __iomem * ) & ( chip - > FIFO [ 0x0000E000 / 4 ] ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000005 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf0 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000006 ) ;
NV_WR32 ( & Surface - > Offset , 0 , surf1 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000014 ) ;
}
static void nv10SetSurfaces3D
(
RIVA_HW_INST * chip ,
unsigned surf0 ,
unsigned surf1
)
{
RivaSurface3D __iomem * Surfaces3D =
( RivaSurface3D __iomem * ) & ( chip - > FIFO [ 0x0000E000 / 4 ] ) ;
RIVA_FIFO_FREE ( * chip , Tri03 , 4 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000007 ) ;
NV_WR32 ( & Surfaces3D - > RenderBufferOffset , 0 , surf0 ) ;
NV_WR32 ( & Surfaces3D - > ZBufferOffset , 0 , surf1 ) ;
NV_WR32 ( & chip - > FIFO [ 0x00003800 ] , 0 , 0x80000014 ) ;
}
/****************************************************************************\
* *
* Probe RIVA Chip Configuration *
* *
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void nv3GetConfig
(
RIVA_HW_INST * chip
)
{
/*
* Fill in chip configuration .
*/
if ( NV_RD32 ( & chip - > PFB [ 0x00000000 / 4 ] , 0 ) & 0x00000020 )
{
if ( ( ( NV_RD32 ( chip - > PMC , 0x00000000 ) & 0xF0 ) = = 0x20 )
& & ( ( NV_RD32 ( chip - > PMC , 0x00000000 ) & 0x0F ) > = 0x02 ) )
{
/*
* SDRAM 128 ZX .
*/
chip - > RamBandwidthKBytesPerSec = 800000 ;
switch ( NV_RD32 ( chip - > PFB , 0x00000000 ) & 0x03 )
{
case 2 :
chip - > RamAmountKBytes = 1024 * 4 ;
break ;
case 1 :
chip - > RamAmountKBytes = 1024 * 2 ;
break ;
default :
chip - > RamAmountKBytes = 1024 * 8 ;
break ;
}
}
else
{
chip - > RamBandwidthKBytesPerSec = 1000000 ;
chip - > RamAmountKBytes = 1024 * 8 ;
}
}
else
{
/*
* SGRAM 128.
*/
chip - > RamBandwidthKBytesPerSec = 1000000 ;
switch ( NV_RD32 ( chip - > PFB , 0x00000000 ) & 0x00000003 )
{
case 0 :
chip - > RamAmountKBytes = 1024 * 8 ;
break ;
case 2 :
chip - > RamAmountKBytes = 1024 * 4 ;
break ;
default :
chip - > RamAmountKBytes = 1024 * 2 ;
break ;
}
}
chip - > CrystalFreqKHz = ( NV_RD32 ( chip - > PEXTDEV , 0x00000000 ) & 0x00000040 ) ? 14318 : 13500 ;
chip - > CURSOR = & ( chip - > PRAMIN [ 0x00008000 / 4 - 0x0800 / 4 ] ) ;
chip - > VBlankBit = 0x00000100 ;
chip - > MaxVClockFreqKHz = 256000 ;
/*
* Set chip functions .
*/
chip - > Busy = nv3Busy ;
chip - > ShowHideCursor = ShowHideCursor ;
chip - > LoadStateExt = LoadStateExt ;
chip - > UnloadStateExt = UnloadStateExt ;
chip - > SetStartAddress = SetStartAddress3 ;
chip - > SetSurfaces2D = nv3SetSurfaces2D ;
chip - > SetSurfaces3D = nv3SetSurfaces3D ;
chip - > LockUnlock = nv3LockUnlock ;
}
static void nv4GetConfig
(
RIVA_HW_INST * chip
)
{
/*
* Fill in chip configuration .
*/
if ( NV_RD32 ( chip - > PFB , 0x00000000 ) & 0x00000100 )
{
chip - > RamAmountKBytes = ( ( NV_RD32 ( chip - > PFB , 0x00000000 ) > > 12 ) & 0x0F ) * 1024 * 2
+ 1024 * 2 ;
}
else
{
switch ( NV_RD32 ( chip - > PFB , 0x00000000 ) & 0x00000003 )
{
case 0 :
chip - > RamAmountKBytes = 1024 * 32 ;
break ;
case 1 :
chip - > RamAmountKBytes = 1024 * 4 ;
break ;
case 2 :
chip - > RamAmountKBytes = 1024 * 8 ;
break ;
case 3 :
default :
chip - > RamAmountKBytes = 1024 * 16 ;
break ;
}
}
switch ( ( NV_RD32 ( chip - > PFB , 0x00000000 ) > > 3 ) & 0x00000003 )
{
case 3 :
chip - > RamBandwidthKBytesPerSec = 800000 ;
break ;
default :
chip - > RamBandwidthKBytesPerSec = 1000000 ;
break ;
}
chip - > CrystalFreqKHz = ( NV_RD32 ( chip - > PEXTDEV , 0x00000000 ) & 0x00000040 ) ? 14318 : 13500 ;
chip - > CURSOR = & ( chip - > PRAMIN [ 0x00010000 / 4 - 0x0800 / 4 ] ) ;
chip - > VBlankBit = 0x00000001 ;
chip - > MaxVClockFreqKHz = 350000 ;
/*
* Set chip functions .
*/
chip - > Busy = nv4Busy ;
chip - > ShowHideCursor = ShowHideCursor ;
chip - > LoadStateExt = LoadStateExt ;
chip - > UnloadStateExt = UnloadStateExt ;
chip - > SetStartAddress = SetStartAddress ;
chip - > SetSurfaces2D = nv4SetSurfaces2D ;
chip - > SetSurfaces3D = nv4SetSurfaces3D ;
chip - > LockUnlock = nv4LockUnlock ;
}
static void nv10GetConfig
(
RIVA_HW_INST * chip ,
unsigned int chipset
)
{
struct pci_dev * dev ;
2008-04-28 02:15:33 -07:00
u32 amt ;
2005-04-16 15:20:36 -07:00
# ifdef __BIG_ENDIAN
/* turn on big endian register access */
if ( ! ( NV_RD32 ( chip - > PMC , 0x00000004 ) & 0x01000001 ) )
NV_WR32 ( chip - > PMC , 0x00000004 , 0x01000001 ) ;
# endif
/*
* Fill in chip configuration .
*/
if ( chipset = = NV_CHIP_IGEFORCE2 ) {
2007-05-08 00:39:28 -07:00
dev = pci_get_bus_and_slot ( 0 , 1 ) ;
2005-04-16 15:20:36 -07:00
pci_read_config_dword ( dev , 0x7C , & amt ) ;
2007-05-08 00:39:28 -07:00
pci_dev_put ( dev ) ;
2005-04-16 15:20:36 -07:00
chip - > RamAmountKBytes = ( ( ( amt > > 6 ) & 31 ) + 1 ) * 1024 ;
} else if ( chipset = = NV_CHIP_0x01F0 ) {
2007-05-08 00:39:28 -07:00
dev = pci_get_bus_and_slot ( 0 , 1 ) ;
2005-04-16 15:20:36 -07:00
pci_read_config_dword ( dev , 0x84 , & amt ) ;
2007-05-08 00:39:28 -07:00
pci_dev_put ( dev ) ;
2005-04-16 15:20:36 -07:00
chip - > RamAmountKBytes = ( ( ( amt > > 4 ) & 127 ) + 1 ) * 1024 ;
} else {
switch ( ( NV_RD32 ( chip - > PFB , 0x0000020C ) > > 20 ) & 0x000000FF )
{
case 0x02 :
chip - > RamAmountKBytes = 1024 * 2 ;
break ;
case 0x04 :
chip - > RamAmountKBytes = 1024 * 4 ;
break ;
case 0x08 :
chip - > RamAmountKBytes = 1024 * 8 ;
break ;
case 0x10 :
chip - > RamAmountKBytes = 1024 * 16 ;
break ;
case 0x20 :
chip - > RamAmountKBytes = 1024 * 32 ;
break ;
case 0x40 :
chip - > RamAmountKBytes = 1024 * 64 ;
break ;
case 0x80 :
chip - > RamAmountKBytes = 1024 * 128 ;
break ;
default :
chip - > RamAmountKBytes = 1024 * 16 ;
break ;
}
}
switch ( ( NV_RD32 ( chip - > PFB , 0x00000000 ) > > 3 ) & 0x00000003 )
{
case 3 :
chip - > RamBandwidthKBytesPerSec = 800000 ;
break ;
default :
chip - > RamBandwidthKBytesPerSec = 1000000 ;
break ;
}
chip - > CrystalFreqKHz = ( NV_RD32 ( chip - > PEXTDEV , 0x0000 ) & ( 1 < < 6 ) ) ?
14318 : 13500 ;
switch ( chipset & 0x0ff0 ) {
case 0x0170 :
case 0x0180 :
case 0x01F0 :
case 0x0250 :
case 0x0280 :
case 0x0300 :
case 0x0310 :
case 0x0320 :
case 0x0330 :
case 0x0340 :
if ( NV_RD32 ( chip - > PEXTDEV , 0x0000 ) & ( 1 < < 22 ) )
chip - > CrystalFreqKHz = 27000 ;
break ;
default :
break ;
}
chip - > CursorStart = ( chip - > RamAmountKBytes - 128 ) * 1024 ;
chip - > CURSOR = NULL ; /* can't set this here */
chip - > VBlankBit = 0x00000001 ;
chip - > MaxVClockFreqKHz = 350000 ;
/*
* Set chip functions .
*/
chip - > Busy = nv10Busy ;
chip - > ShowHideCursor = ShowHideCursor ;
chip - > LoadStateExt = LoadStateExt ;
chip - > UnloadStateExt = UnloadStateExt ;
chip - > SetStartAddress = SetStartAddress ;
chip - > SetSurfaces2D = nv10SetSurfaces2D ;
chip - > SetSurfaces3D = nv10SetSurfaces3D ;
chip - > LockUnlock = nv4LockUnlock ;
switch ( chipset & 0x0ff0 ) {
case 0x0110 :
case 0x0170 :
case 0x0180 :
case 0x01F0 :
case 0x0250 :
case 0x0280 :
case 0x0300 :
case 0x0310 :
case 0x0320 :
case 0x0330 :
case 0x0340 :
chip - > twoHeads = TRUE ;
break ;
default :
chip - > twoHeads = FALSE ;
break ;
}
}
int RivaGetConfig
(
RIVA_HW_INST * chip ,
unsigned int chipset
)
{
/*
* Save this so future SW know whats it ' s dealing with .
*/
chip - > Version = RIVA_SW_VERSION ;
/*
* Chip specific configuration .
*/
switch ( chip - > Architecture )
{
case NV_ARCH_03 :
nv3GetConfig ( chip ) ;
break ;
case NV_ARCH_04 :
nv4GetConfig ( chip ) ;
break ;
case NV_ARCH_10 :
case NV_ARCH_20 :
case NV_ARCH_30 :
nv10GetConfig ( chip , chipset ) ;
break ;
default :
return ( - 1 ) ;
}
chip - > Chipset = chipset ;
/*
* Fill in FIFO pointers .
*/
chip - > Rop = ( RivaRop __iomem * ) & ( chip - > FIFO [ 0x00000000 / 4 ] ) ;
chip - > Clip = ( RivaClip __iomem * ) & ( chip - > FIFO [ 0x00002000 / 4 ] ) ;
chip - > Patt = ( RivaPattern __iomem * ) & ( chip - > FIFO [ 0x00004000 / 4 ] ) ;
chip - > Pixmap = ( RivaPixmap __iomem * ) & ( chip - > FIFO [ 0x00006000 / 4 ] ) ;
chip - > Blt = ( RivaScreenBlt __iomem * ) & ( chip - > FIFO [ 0x00008000 / 4 ] ) ;
chip - > Bitmap = ( RivaBitmap __iomem * ) & ( chip - > FIFO [ 0x0000A000 / 4 ] ) ;
chip - > Line = ( RivaLine __iomem * ) & ( chip - > FIFO [ 0x0000C000 / 4 ] ) ;
chip - > Tri03 = ( RivaTexturedTriangle03 __iomem * ) & ( chip - > FIFO [ 0x0000E000 / 4 ] ) ;
return ( 0 ) ;
}