917 lines
35 KiB
C
917 lines
35 KiB
C
/*
|
|
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
|
|
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
|
|
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
|
|
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
|
|
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
|
|
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
|
|
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
|
|
**
|
|
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
|
|
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
|
|
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
|
|
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
|
|
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
|
|
** THE UNITED STATES.
|
|
**
|
|
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
|
|
**
|
|
** $Revision$
|
|
** $Date$
|
|
**
|
|
*/
|
|
|
|
/*
|
|
** Initialization code for SST-1 board.
|
|
**
|
|
** NOTE: This code must compiled with optimizations DISABLED!!
|
|
**
|
|
** The following environment variables can optionally be used to alter
|
|
** functionality (A value of X is a "don't care"):
|
|
**
|
|
** Variable Value Description
|
|
** -------- ----- -----------
|
|
** SST_ARCADE X Allow special configs for arcade use
|
|
** SST_BACKPORCH hex Specify value of backPorch video register
|
|
** SST_BOARDS val Specify number of SST-1 boards in system
|
|
** SST_DEBUGDAC X Print out debug information for DAC
|
|
** reads and writes
|
|
** SST_DIMENSIONS hex Specify value of videoDimensions register
|
|
** SST_FASTMEM 1 Default. Enable fast memory timing
|
|
** SST_FASTMEM 0 Disable fast memory timing
|
|
** SST_FASTPCIRD X Enable fast PCI reads
|
|
** SST_FBICFG hex Specify FBI configuration strapping bits
|
|
** SST_FBIMEM_SIZE val Specify amount of frame buffer memory
|
|
** SST_FT_CLK_DEL hex Fbi-to-Trex clock delay value
|
|
** SST_GAMMA float Floating point value for gamma correction
|
|
** SST_GRXCLK val 16 <= Frequency < 80 (50 is default)
|
|
** SST_HSYNC hex Specify value of hSync video register
|
|
** SST_IGNORE_INIT_GAMMA X Bypass sst1InitGamma call and return
|
|
** SST_IGNORE_INIT_REGISTERS X Bypass sst1InitRegisters call and return
|
|
** SST_IGNORE_INIT_VIDEO X Bypass sst1InitVideo call and return
|
|
** SST_IGNORE_SLI_CHECK X Ignore checking for proper SLI install
|
|
** SST_INITDEBUG X Enable debug output
|
|
** SST_INITDEBUG_FILE file File to direct all debug output
|
|
** SST_MEMFIFO 0 Disable FBI Memory FIFO
|
|
** SST_MEMFIFO 1 Enable FBI Memory FIFO
|
|
** SST_MEMFIFO_ENTRIES hex Set number of entries in memory fifo
|
|
** SST_MEMFIFO_HWM hex Set memory fifo high water mark
|
|
** SST_MEMFIFO_LFB 0 or 1 Specify LFB writes through Memory FIFO
|
|
** SST_MEMFIFO_LWM hex Set memory fifo low water mark
|
|
** SST_MEMFIFO_TEX 0 or 1 Specify Texture writes through Mem FIFO
|
|
** SST_MEMOFFSET hex Specify value of memoffset video register
|
|
** SST_NOCHECKHANG X Do not Check for FBI Hangs for texturing
|
|
** SST_NODEVICEINFO X Ignore calls to sst1InitFillDeviceInfo()
|
|
** SST_NOSHUTDOWN X Do not turn off monitor refresh on call
|
|
** to sst1InitShutdown()
|
|
** SST_PCIFIFO_LWM hex Set pci fifo low water mark
|
|
** SST_PFT_CLK_DEL hex Preliminary Fbi-to-Trex clock delay value
|
|
** SST_PTF0_CLK_DEL hex Prelim TMU2Fbi clock delay value (TMU #0)
|
|
** SST_PTF1_CLK_DEL hex Prelim TMU2Fbi clock delay value (TMU #1)
|
|
** SST_PTF2_CLK_DEL hex Prelim TMU2Fbi clock delay value (TMU #2)
|
|
** SST_SLIDETECT 0 or 1 Specify Scanline Interleaving detection
|
|
** SST_SLIM_VIN_CLKDEL hex Specify FBI internal video clock delay
|
|
** (SLI Master)
|
|
** SST_SLIM_VOUT_CLKDEL hex Specify FBI external video clock delay
|
|
** (SLI Master)
|
|
** SST_SLIS_VIN_CLKDEL hex Specify FBI internal video clock delay
|
|
** (SLI Slave)
|
|
** SST_SLIS_VOUT_CLKDEL hex Specify FBI external video clock delay
|
|
** (SLI Slave)
|
|
** SST_SCREENREFRESH 60 Select 60Hz monitor refresh rate
|
|
** (overrides argument to sst1InitVideo)
|
|
** SST_SCREENREFRESH 75 Select 75Hz monitor refresh rate
|
|
** SST_SCREENREZ 512 Select 512x384 video resolution
|
|
** (overrides argument to sst1InitVideo)
|
|
** SST_SCREENREZ 640 Select 640x480 video resolution
|
|
** SST_SCREENREZ 800 Select 800x600 video resolution
|
|
** SST_SLOWPCIWR X Enable 1 wait-state PCI writes
|
|
** SST_TEXMAP_DISABLE X Disable texture mapping
|
|
** SST_TF0_CLK_DEL hex Trex-to-Fbi clock delay value (TMU #0)
|
|
** SST_TF1_CLK_DEL hex Trex-to-Fbi clock delay value (TMU #1)
|
|
** SST_TF2_CLK_DEL hex Trex-to-Fbi clock delay value (TMU #2)
|
|
** SST_TF_FIFO_THRESH hex Set TREX-to-FBI FIFO threshold
|
|
** SST_TILESINX hex Specify value of tilesInX video register
|
|
** SST_TMUCFG hex Specify TMU configuration strapping bits
|
|
** SST_TMUMEM X Enable accurate determination of TMU mem
|
|
** SST_TMUMEM_SIZE val Specify amount of texture memory
|
|
** SST_TREX0INIT0 hex Set trexInit0 register value - TMU #0
|
|
** SST_TREX0INIT1 hex Set trexInit1 register value - TMU #0
|
|
** SST_TREX1INIT0 hex Set trexInit0 register value - TMU #1
|
|
** SST_TREX1INIT1 hex Set trexInit1 register value - TMU #1
|
|
** SST_TREX2INIT0 hex Set trexInit0 register value - TMU #2
|
|
** SST_TREX2INIT1 hex Set trexInit1 register value - TMU #2
|
|
** SST_TRIPLE_BUFFER X Enable Triple Buffering
|
|
** SST_VIN_CLKDEL hex Specify FBI internal video clock delay
|
|
** SST_VOUT_CLKDEL hex Specify FBI external video clock delay
|
|
** SST_VGA_PASS 0,1 Force VGA_PASS output to {0,1}
|
|
** SST_VIDCLK2X val Video clock frequency (2x dot clock)
|
|
** SST_VIDEO_24BPP 0 Select 16-bit video output
|
|
** SST_VIDEO_24BPP 1 Select 24-bit video output
|
|
** SST_VIDEO_DISABLE X Turn off Video/Monitor refresh in FBI
|
|
** SST_VIDEO_FILTER_DISABLE X Disable video filtering
|
|
** SST_VIDEO_FILTER_THRESHOLD hex Set video filtering threshold
|
|
** SST_VIDEO_NOCLEAR X Do not clear buffers in sst1InitVideo()
|
|
** SST_VIDEO_CLEARCOLOR hex Clear screen color
|
|
** SST_VFIFO_THRESH 0-31 Select video fifo threshold
|
|
** SST_VSYNC hex Specify value of vSync video register
|
|
**
|
|
** VOODOO_FILE name Filename used in place of "voodoo.ini"
|
|
** VOODOO_PATH path Path used to locate "voodoo.ini" file
|
|
**
|
|
*/
|
|
|
|
#pragma optimize ("",off)
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <sst.h>
|
|
#include <fxpci.h>
|
|
#define SST1INIT_ALLOCATE /* Allocate variables in sst1init.h */
|
|
#define FX_DLL_DEFINITION
|
|
#include <fxdll.h>
|
|
#include <sst1vid.h>
|
|
#include <sst1init.h>
|
|
#include "rcver.h"
|
|
|
|
#ifdef __WIN32__
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
/* Allow SourceSafe to track Revision */
|
|
static char codeIdent[] = "@#%" VERSIONSTR ;
|
|
|
|
/*
|
|
** sst1InitMapBoard():
|
|
** Find and map SST-1 board into virtual memory
|
|
**
|
|
** Returns:
|
|
** FxU32 pointer to base of SST-1 board if successful mapping occurs
|
|
** FXFALSE if cannot map or find SST-1 board
|
|
**
|
|
*/
|
|
FX_EXPORT FxU32 * FX_CSTYLE sst1InitMapBoard(FxU32 BoardNumber)
|
|
{
|
|
static FxU32 firstTime = 1;
|
|
FxU32 sizeOfCard = 0x1000000; /* 16 MBytes of addr space for SST-1 */
|
|
FxU32 *sst;
|
|
volatile Sstregs *sstptr;
|
|
FxU32 n, j;
|
|
|
|
if(firstTime) {
|
|
/* Make Watcom happy */
|
|
codeIdent[0] = '@';
|
|
headersIdent[0] = '@';
|
|
|
|
/* Find "voodoo.ini" file if it exists... */
|
|
sst1InitUseVoodooFile = sst1InitVoodooFile();
|
|
|
|
if(!(boardsInSystem = sst1InitNumBoardsInSystem()))
|
|
return(NULL);
|
|
}
|
|
|
|
if(BoardNumber == 0) {
|
|
INIT_PRINTF(("sst1Init Routines"));
|
|
#ifdef FX_DLL_ENABLE
|
|
INIT_PRINTF(("(DLL)"));
|
|
#endif
|
|
INIT_PRINTF((": %s\n", VERSIONSTR));
|
|
INIT_PRINTF(("sst1InitMapBoard(): BoardsInSystem = %d\n",
|
|
boardsInSystem));
|
|
|
|
/* Clear board info structure */
|
|
sst1InitClearBoardInfo();
|
|
}
|
|
|
|
if(firstTime) {
|
|
firstTime = 0;
|
|
sst1InitClearBoardInfo();
|
|
|
|
/* Map all boards in the system */
|
|
/* Check that scanline interleaving is not enabled... */
|
|
for(j=0; j<SST1INIT_MAX_BOARDS; j++) {
|
|
FxU32 vendorID = _3DFX_PCI_ID; /* 3Dfx Vendor ID */
|
|
FxU32 deviceID = 1; /* Find only sst1 boards */
|
|
|
|
#ifndef DIRECTX
|
|
sst = pciMapCardMulti(vendorID, deviceID, sizeOfCard,
|
|
&sst1InitDeviceNumber, j, 0);
|
|
#else
|
|
sst = pciMapCardMulti(vendorID, deviceID, sizeOfCard,
|
|
&sst1InitDeviceNumber, j, 0);
|
|
#endif /* DIRECTX */
|
|
if(sst) {
|
|
sst1BoardInfo[j].virtAddr = sst;
|
|
PCICFG_RD(PCI_BASE_ADDRESS_0, sst1BoardInfo[j].physAddr);
|
|
sst1BoardInfo[j].deviceNumber = sst1InitDeviceNumber;
|
|
sst1BoardInfo[j].numBoardInsystem = j;
|
|
PCICFG_RD(PCI_REVISION_ID, sst1BoardInfo[j].fbiRevision);
|
|
PCICFG_RD(PCI_DEVICE_ID, sst1BoardInfo[j].deviceID);
|
|
PCICFG_RD(PCI_VENDOR_ID, sst1BoardInfo[j].vendorID);
|
|
|
|
/* Enable Memory accesses to SST-1 */
|
|
/* Must be set for PnP BIOS which do not enable memory mapped */
|
|
/* accesses (sst1InitSliDetect reads memory mapped regs) */
|
|
PCICFG_WR(PCI_COMMAND, SST_PCIMEM_ACCESS_EN);
|
|
sstptr = (Sstregs *) sst;
|
|
/* Check SLI not enabled... */
|
|
if((IGET(sstptr->fbiInit1) & SST_EN_SCANLINE_INTERLEAVE) &&
|
|
sst1InitSliDetect(sst)) {
|
|
INIT_PRINTF(("sst1InitMapBoard(): Scanline Interleave detected at startup for board=%d\n", j));
|
|
INIT_PRINTF((" System reboot required...\n"));
|
|
return(NULL);
|
|
}
|
|
} else {
|
|
FxU32 code = pciGetErrorCode();
|
|
if (code == PCI_ERR_WRONGVXD) {
|
|
#ifdef __WIN32__
|
|
MessageBox(NULL, pciGetErrorString(), NULL, MB_OK);
|
|
#endif /* __WIN32__ */
|
|
exit(1);
|
|
}
|
|
sst1BoardInfo[j].virtAddr = (FxU32 *) NULL;
|
|
sst1BoardInfo[j].physAddr = (FxU32) NULL;
|
|
sst1BoardInfo[j].deviceNumber = 0xdead;
|
|
sst1BoardInfo[j].numBoardInsystem = 0xdead;
|
|
sst1BoardInfo[j].fbiRevision = 0xdead;
|
|
sst1BoardInfo[j].deviceID = 0xdead;
|
|
sst1BoardInfo[j].vendorID = 0xdead;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Max number of supported boards in system */
|
|
if(BoardNumber > SST1INIT_MAX_BOARDS) return(NULL);
|
|
|
|
if(!(sst = sst1BoardInfo[BoardNumber].virtAddr))
|
|
return (NULL);
|
|
|
|
INIT_PRINTF(("sst1InitMapBoard(): vAddr:0x%x pAddr:0x%x Dev:0x%x Board:%d\n",
|
|
(FxU32) sst1BoardInfo[BoardNumber].virtAddr,
|
|
(FxU32) sst1BoardInfo[BoardNumber].physAddr,
|
|
(FxU32) sst1BoardInfo[BoardNumber].deviceNumber, BoardNumber));
|
|
|
|
sstptr = (Sstregs *) sst;
|
|
|
|
/* Default settings */
|
|
if((IGET(sstptr->fbiInit3) & SST_FBI_VGA_PASS_POWERON) &&
|
|
(sst1BoardInfo[BoardNumber].fbiRevision > 0)) {
|
|
sst1BoardInfo[BoardNumber].vgaPassthruDisable = 0x0;
|
|
sst1BoardInfo[BoardNumber].vgaPassthruEnable = SST_EN_VGA_PASSTHRU;
|
|
sst1BoardInfo[BoardNumber].fbiRegulatorPresent = 0x1;
|
|
} else {
|
|
sst1BoardInfo[BoardNumber].vgaPassthruDisable = SST_EN_VGA_PASSTHRU;
|
|
sst1BoardInfo[BoardNumber].vgaPassthruEnable = 0x0;
|
|
sst1BoardInfo[BoardNumber].fbiRegulatorPresent = 0x0;
|
|
}
|
|
sst1BoardInfo[BoardNumber].fbiVideo16BPP = 0;
|
|
|
|
if(GETENV(("SST_VGA_PASS"))) {
|
|
INIT_PRINTF(("sst1InitMapBoard(): Using SST_VGA_PASS=%d\n",
|
|
ATOI(GETENV(("SST_VGA_PASS")))));
|
|
if(ATOI(GETENV(("SST_VGA_PASS")))) {
|
|
sst1BoardInfo[BoardNumber].vgaPassthruEnable = SST_EN_VGA_PASSTHRU;
|
|
sst1BoardInfo[BoardNumber].vgaPassthruDisable = 0x0;
|
|
} else {
|
|
sst1BoardInfo[BoardNumber].vgaPassthruDisable = SST_EN_VGA_PASSTHRU;
|
|
sst1BoardInfo[BoardNumber].vgaPassthruEnable = 0x0;
|
|
}
|
|
}
|
|
return(sst);
|
|
}
|
|
|
|
/*
|
|
** sst1InitRegisters():
|
|
** Initialize registers and memory and return to power-on state
|
|
**
|
|
** Returns:
|
|
** FXTRUE if successfully initializes SST-1
|
|
** FXFALSE if cannot initialize SST-1
|
|
**
|
|
*/
|
|
FX_EXPORT FxBool FX_CSTYLE sst1InitRegisters(FxU32 *sstbase)
|
|
{
|
|
FxU32 n, tf_fifo_thresh;
|
|
FxU32 ft_clk_del, tf0_clk_del, tf1_clk_del, tf2_clk_del;
|
|
sst1ClkTimingStruct sstGrxClk;
|
|
volatile Sstregs *sst = (Sstregs *) sstbase;
|
|
|
|
if(!sst)
|
|
return(FXFALSE);
|
|
|
|
if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
|
return(FXFALSE);
|
|
|
|
if(GETENV(("SST_IGNORE_INIT_REGISTERS"))) {
|
|
INIT_PRINTF(("WARNING: Ignoring sst1InitRegisters()...\n"));
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
return(FXTRUE);
|
|
}
|
|
|
|
/* Disable video clock */
|
|
PCICFG_WR(SST1_PCI_VCLK_DISABLE, 0x0);
|
|
|
|
/* Enable writes to the FBIINIT registers */
|
|
/* Do not allow writes into the pci fifo until everything is reset */
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, SST_INITWR_EN);
|
|
|
|
/* Reset Snoop registers to default values */
|
|
#if 0
|
|
PCICFG_WR(SST1_PCI_BUS_SNOOP0, SST_PCI_BUS_SNOOP_DEFAULT);
|
|
PCICFG_WR(SST1_PCI_BUS_SNOOP1, SST_PCI_BUS_SNOOP_DEFAULT);
|
|
#else
|
|
PCICFG_WR(SST1_PCI_BUS_SNOOP_0, SST_PCI_BUS_SNOOP_DEFAULT);
|
|
PCICFG_WR(SST1_PCI_BUS_SNOOP_1, SST_PCI_BUS_SNOOP_DEFAULT);
|
|
#endif
|
|
sst1InitReturnStatus(sstbase); /* Stall - can't call IdleFbi because */
|
|
/* FBI could be hung at this stage */
|
|
sst1InitReturnStatus(sstbase);
|
|
sst1InitReturnStatus(sstbase);
|
|
|
|
/* Adjust Fbi-to-Trex clock delay value */
|
|
/* Adjust Trex-to-Fbi FIFO */
|
|
if(GETENV(("SST_TF_FIFO_THRESH")))
|
|
SSCANF(GETENV(("SST_TF_FIFO_THRESH")), "%i", &tf_fifo_thresh);
|
|
else
|
|
tf_fifo_thresh = 0x8;
|
|
INIT_PRINTF(("sst1InitRegisters(): Setting TREX-to-FBI FIFO THRESHOLD to 0x%x...\n",
|
|
tf_fifo_thresh));
|
|
/* Set ft_clk_del for 16 MHz bringup */
|
|
if(sst1CurrentBoard->fbiRevision == 2)
|
|
/* .5 micron */
|
|
ft_clk_del = 0x8; /* Okay for 16 MHz startup... */
|
|
else
|
|
/* .6 micron */
|
|
ft_clk_del = 0xa; /* Okay for 16 MHz startup... */
|
|
if(GETENV(("SST_PFT_CLK_DEL")))
|
|
SSCANF(GETENV(("SST_PFT_CLK_DEL")), "%i", &ft_clk_del);
|
|
INIT_PRINTF(("sst1InitRegisters(): Setting PRELIM FT-CLK delay to 0x%x...\n", ft_clk_del));
|
|
ISET(sst->fbiInit3,
|
|
(SST_FBIINIT3_DEFAULT & ~(SST_FT_CLK_DEL_ADJ | SST_TF_FIFO_THRESH)) |
|
|
(ft_clk_del << SST_FT_CLK_DEL_ADJ_SHIFT) |
|
|
(tf_fifo_thresh << SST_TF_FIFO_THRESH_SHIFT));
|
|
|
|
/* Wait for Fbi-to-Trex clock delay value to propogate */
|
|
sst1InitReturnStatus(sstbase); /* Stall - can't call IdleFbi because */
|
|
/* FBI could be hung at this stage */
|
|
|
|
sst1InitReturnStatus(sstbase);
|
|
sst1InitReturnStatus(sstbase);
|
|
|
|
/* Reset graphics and video units */
|
|
/* Must reset video unit before graphics unit, otherwise video unit could */
|
|
/* potentially hang waiting for the graphics unit to respond */
|
|
ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
|
|
|
|
/* don't wait for idle b/c grx could be hung */
|
|
sst1InitReturnStatus(sstbase);
|
|
sst1InitReturnStatus(sstbase);
|
|
sst1InitReturnStatus(sstbase);
|
|
ISET(sst->fbiInit0,
|
|
IGET(sst->fbiInit0) | (SST_GRX_RESET | SST_PCI_FIFO_RESET));
|
|
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* Unreset PCI FIFO... */
|
|
ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_PCI_FIFO_RESET);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* Unreset graphics subsystem */
|
|
/* THIS MUST BE PRESENT OTHERWISE THE PCI FIFO WILL NEVER DRAIN! */
|
|
ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_GRX_RESET);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* Reset all FBI and TREX Init registers */
|
|
ISET(sst->fbiInit0, SST_FBIINIT0_DEFAULT);
|
|
ISET(sst->fbiInit1, SST_FBIINIT1_DEFAULT);
|
|
ISET(sst->fbiInit2, SST_FBIINIT2_DEFAULT);
|
|
ISET(sst->fbiInit3,
|
|
(SST_FBIINIT3_DEFAULT & ~(SST_FT_CLK_DEL_ADJ | SST_TF_FIFO_THRESH)) |
|
|
(ft_clk_del << SST_FT_CLK_DEL_ADJ_SHIFT) |
|
|
(tf_fifo_thresh << SST_TF_FIFO_THRESH_SHIFT));
|
|
ISET(sst->fbiInit4, SST_FBIINIT4_DEFAULT);
|
|
sst1InitIdleFBINoNOP(sstbase); /* Wait until init regs are reset */
|
|
|
|
/* Enable writes to the FBIINIT registers and allow pushes onto PCI FIFO */
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, (SST_INITWR_EN | SST_PCI_FIFOWR_EN));
|
|
|
|
/* Determine DAC Type */
|
|
if(sst1InitDacDetect(sstbase) == FXFALSE) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Could not detect DAC...\n"));
|
|
return(FXFALSE);
|
|
}
|
|
|
|
/* set TREX0 init values */
|
|
if(GETENV(("SST_TREX0INIT0"))) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX0INIT0 environment variable\n"));
|
|
SSCANF(GETENV(("SST_TREX0INIT0")), "%i",
|
|
&sst1CurrentBoard->tmuInit0[0]);
|
|
} else
|
|
sst1CurrentBoard->tmuInit0[0] = SST_TREX0INIT0_DEFAULT;
|
|
|
|
INIT_PRINTF(("sst1InitRegisters(): Storing TREX0INIT0=0x%x\n",
|
|
sst1CurrentBoard->tmuInit0[0]));
|
|
if(GETENV(("SST_TREX0INIT1"))) {
|
|
|
|
INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX0INIT1 environment variable\n"));
|
|
SSCANF(GETENV(("SST_TREX0INIT1")), "%i",
|
|
&sst1CurrentBoard->tmuInit1[0]);
|
|
} else
|
|
sst1CurrentBoard->tmuInit1[0] = SST_TREX0INIT1_DEFAULT;
|
|
if(GETENV(("SST_PTF0_CLK_DEL"))) {
|
|
SSCANF(GETENV(("SST_PTF0_CLK_DEL")), "%i", &tf0_clk_del);
|
|
sst1CurrentBoard->tmuInit1[0] = (sst1CurrentBoard->tmuInit1[0] &
|
|
~SST_TEX_TF_CLK_DEL_ADJ) |
|
|
(tf0_clk_del<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
|
|
}
|
|
INIT_PRINTF(("sst1InitRegisters(): Storing TREX0INIT1=0x%x\n",
|
|
sst1CurrentBoard->tmuInit1[0]));
|
|
|
|
ISET(SST_TREX(sst,0)->trexInit0, sst1CurrentBoard->tmuInit0[0]);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
ISET(SST_TREX(sst,0)->trexInit1, sst1CurrentBoard->tmuInit1[0]);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* set TREX1 init values */
|
|
if(GETENV(("SST_TREX1INIT0"))) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX1INIT0 environment variable\n"));
|
|
SSCANF(GETENV(("SST_TREX1INIT0")), "%i",
|
|
&sst1CurrentBoard->tmuInit0[1]);
|
|
} else
|
|
sst1CurrentBoard->tmuInit0[1] = SST_TREX1INIT0_DEFAULT;
|
|
INIT_PRINTF(("sst1InitRegisters(): Storing TREX1INIT0=0x%x\n",
|
|
sst1CurrentBoard->tmuInit0[1]));
|
|
if(GETENV(("SST_TREX1INIT1"))) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX1INIT1 environment variable\n"));
|
|
SSCANF(GETENV(("SST_TREX1INIT1")), "%i",
|
|
&sst1CurrentBoard->tmuInit1[1]);
|
|
} else
|
|
sst1CurrentBoard->tmuInit1[1] = SST_TREX1INIT1_DEFAULT;
|
|
if(GETENV(("SST_PTF1_CLK_DEL"))) {
|
|
SSCANF(GETENV(("SST_PTF1_CLK_DEL")), "%i", &tf1_clk_del);
|
|
sst1CurrentBoard->tmuInit1[1] = (sst1CurrentBoard->tmuInit1[1] &
|
|
~SST_TEX_TF_CLK_DEL_ADJ) |
|
|
(tf1_clk_del<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
|
|
}
|
|
INIT_PRINTF(("sst1InitRegisters(): Storing TREX1INIT1=0x%x\n",
|
|
sst1CurrentBoard->tmuInit1[1]));
|
|
|
|
ISET(SST_TREX(sst,1)->trexInit0, sst1CurrentBoard->tmuInit0[1]);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
ISET(SST_TREX(sst,1)->trexInit1, sst1CurrentBoard->tmuInit1[1]);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* set TREX2 init values */
|
|
if(GETENV(("SST_TREX2INIT0"))) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX2INIT0 environment variable\n"));
|
|
SSCANF(GETENV(("SST_TREX2INIT0")), "%i",
|
|
&sst1CurrentBoard->tmuInit0[2]);
|
|
} else
|
|
sst1CurrentBoard->tmuInit0[2] = SST_TREX2INIT0_DEFAULT;
|
|
INIT_PRINTF(("sst1InitRegisters(): Storing TREX2INIT0=0x%x\n",
|
|
sst1CurrentBoard->tmuInit0[2]));
|
|
if(GETENV(("SST_TREX2INIT1"))) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX2INIT1 environment variable\n"));
|
|
SSCANF(GETENV(("SST_TREX2INIT1")), "%i",
|
|
&sst1CurrentBoard->tmuInit1[2]);
|
|
} else
|
|
sst1CurrentBoard->tmuInit1[2] = SST_TREX2INIT1_DEFAULT;
|
|
if(GETENV(("SST_PTF2_CLK_DEL"))) {
|
|
SSCANF(GETENV(("SST_PTF2_CLK_DEL")), "%i", &tf2_clk_del);
|
|
sst1CurrentBoard->tmuInit1[2] = (sst1CurrentBoard->tmuInit1[2] &
|
|
~SST_TEX_TF_CLK_DEL_ADJ) |
|
|
(tf2_clk_del<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
|
|
}
|
|
INIT_PRINTF(("sst1InitRegisters(): Storing TREX2INIT1=0x%x\n",
|
|
sst1CurrentBoard->tmuInit1[2]));
|
|
|
|
ISET(SST_TREX(sst,2)->trexInit0, sst1CurrentBoard->tmuInit0[2]);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
ISET(SST_TREX(sst,2)->trexInit1, sst1CurrentBoard->tmuInit1[2]);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* Set clock at 16 MHz to sense TREX configuration... */
|
|
if(sst1InitComputeClkParams((float) 16.0, &sstGrxClk) == FXFALSE)
|
|
return(FXFALSE);
|
|
if(sst1InitSetGrxClk(sstbase, &sstGrxClk) == FXFALSE)
|
|
return(FXFALSE);
|
|
|
|
/* Set PCI wait-states */
|
|
if(GETENV(("SST_SLOWPCIWR"))) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Setting up SLOW PCI Writes...\n"));
|
|
ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_PCI_WRWS_1);
|
|
} else
|
|
ISET(sst->fbiInit1, IGET(sst->fbiInit1) & ~SST_PCI_WRWS_1);
|
|
|
|
if(GETENV(("SST_FASTPCIRD"))) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Setting up FAST PCI Reads...\n"));
|
|
ISET(sst->fbiInit4, IGET(sst->fbiInit4) & ~SST_PCI_RDWS_2);
|
|
}
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* Enable Linear frame buffer reads */
|
|
ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_LFB_READ_EN);
|
|
|
|
/* Swapbuffer algorithm is based on VSync initially */
|
|
ISET(sst->fbiInit2, (IGET(sst->fbiInit2) & ~SST_SWAP_ALGORITHM) |
|
|
SST_SWAP_VSYNC);
|
|
|
|
/* Enable LFB read-aheads */
|
|
ISET(sst->fbiInit4, IGET(sst->fbiInit4) | SST_EN_LFB_RDAHEAD);
|
|
|
|
/* Enable triangle alternate register mapping */
|
|
ISET(sst->fbiInit3, IGET(sst->fbiInit3) | SST_ALT_REGMAPPING);
|
|
|
|
#if 0
|
|
/* Enable Endian Byte Swapping */
|
|
/* Do not enable byte swapping due to potential bug in FBI... */
|
|
ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_EN_ENDIAN_SWAPPING);
|
|
#endif
|
|
|
|
/* Setup DRAM Refresh */
|
|
ISET(sst->fbiInit2, (IGET(sst->fbiInit2) & ~SST_DRAM_REFRESH_CNTR) |
|
|
SST_DRAM_REFRESH_16MS);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
ISET(sst->fbiInit2, IGET(sst->fbiInit2) | SST_EN_DRAM_REFRESH);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
if(GETENV(("SST_FASTMEM")))
|
|
n = ATOI(GETENV(("SST_FASTMEM")));
|
|
else
|
|
n = 1;
|
|
|
|
if(n) {
|
|
INIT_PRINTF(("sst1InitRegisters(): Setting up FAST DRAM Configuration\n"));
|
|
ISET(sst->fbiInit2, IGET(sst->fbiInit2) | (SST_EN_FAST_RAS_READ |
|
|
SST_EN_DRAM_RD_AHEAD_FIFO | SST_EN_FAST_RD_AHEAD_WR));
|
|
} else
|
|
ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_DISEN_RD_AHEAD_WR_RD);
|
|
|
|
/* Return all other registers to their power-on state */
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
sst1InitSetResolution(sstbase, &SST_VREZ_640X480_60, 0);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* Get DRAMs up and running (refresh is already enabled)... */
|
|
ISET(sst->c1, 0x0);
|
|
ISET(sst->c0, 0x0);
|
|
ISET(sst->zaColor, 0x0);
|
|
ISET(sst->clipLeftRight, 100); /* draw into 50x50 area */
|
|
ISET(sst->clipBottomTop, 100);
|
|
ISET(sst->fbzMode, SST_RGBWRMASK | SST_ZAWRMASK);
|
|
ISET(sst->fastfillCMD, 0x0); /* Frontbuffer & Z/A */
|
|
ISET(sst->nopCMD, 0x1); /* Clear fbistat registers after clearing screen */
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
sst1InitRenderingRegisters(sstbase);
|
|
if(sst1InitFillDeviceInfo(sstbase, sst1CurrentBoard) == FXFALSE) {
|
|
INIT_PRINTF(("sst1InitRegisters(): ERROR filling DeviceInfo...\n"));
|
|
return(FXFALSE);
|
|
}
|
|
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
sst1InitRenderingRegisters(sstbase);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
|
|
/* LFB writes stored in memory FIFO? */
|
|
if(GETENV(("SST_MEMFIFO_LFB")))
|
|
n = ATOI(GETENV(("SST_MEMFIFO_LFB")));
|
|
else
|
|
n = 1;
|
|
if(n) {
|
|
INIT_PRINTF(("sst1InitRegisters(): LFB Writes go through memory FIFO...\n"));
|
|
ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_EN_LFB_MEMFIFO);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
}
|
|
|
|
/* Texture memory writes stored in memory FIFO? */
|
|
if(GETENV(("SST_MEMFIFO_TEX")))
|
|
n = ATOI(GETENV(("SST_MEMFIFO_TEX")));
|
|
else
|
|
n = 1;
|
|
if(n) {
|
|
INIT_PRINTF(("sst1InitRegisters(): TEXTURE Writes go through memory FIFO...\n"));
|
|
ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_EN_TEX_MEMFIFO);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
}
|
|
|
|
ISET(sst->vRetrace, 0x0);
|
|
ISET(sst->backPorch, 0x0);
|
|
ISET(sst->videoDimensions, 0x0);
|
|
ISET(sst->hSync, 0x0);
|
|
ISET(sst->vSync, 0x0);
|
|
ISET(sst->videoFilterRgbThreshold, 0x0);
|
|
|
|
sst1InitIdleFBINoNOP(sstbase); /* Wait until init regs are reset */
|
|
|
|
if(GETENV(("SST_TEXMAP_DISABLE"))) {
|
|
INIT_PRINTF(("sst1InitRegisters() WARNING: Disabling texture mapping\n"));
|
|
ISET(sst->fbiInit3, IGET(sst->fbiInit3) | SST_TEXMAP_DISABLE);
|
|
sst1InitIdleFBINoNOP(sstbase);
|
|
}
|
|
INIT_PRINTF(("sst1InitRegisters(): exiting with status %d...\n", FXTRUE));
|
|
return(FXTRUE);
|
|
}
|
|
|
|
FX_EXPORT void FX_CSTYLE sst1InitRenderingRegisters(FxU32 *sstbase)
|
|
{
|
|
FxU32 i;
|
|
volatile Sstregs *sst = (Sstregs *) sstbase;
|
|
|
|
ISET(sst->vA.x, 0x0); ISET(sst->vA.y, 0x0);
|
|
ISET(sst->vB.x, 0x0); ISET(sst->vB.y, 0x0);
|
|
ISET(sst->vC.x, 0x0); ISET(sst->vC.y, 0x0);
|
|
|
|
ISET(sst->r, 0x0); ISET(sst->g, 0x0);
|
|
ISET(sst->b, 0x0); ISET(sst->z, 0x0);
|
|
ISET(sst->a, 0x0); ISET(sst->s, 0x0);
|
|
ISET(sst->t, 0x0); ISET(sst->w, 0x0);
|
|
|
|
ISET(sst->drdx, 0x0); ISET(sst->dgdx, 0x0);
|
|
ISET(sst->dbdx, 0x0); ISET(sst->dzdx, 0x0);
|
|
ISET(sst->dadx, 0x0); ISET(sst->dsdx, 0x0);
|
|
ISET(sst->dtdx, 0x0); ISET(sst->dwdx, 0x0);
|
|
|
|
ISET(sst->drdy, 0x0); ISET(sst->dgdy, 0x0);
|
|
ISET(sst->dbdy, 0x0); ISET(sst->dzdy, 0x0);
|
|
ISET(sst->dady, 0x0); ISET(sst->dsdy, 0x0);
|
|
ISET(sst->dtdy, 0x0); ISET(sst->dwdy, 0x0);
|
|
|
|
ISET(sst->fbzColorPath, 0x0);
|
|
ISET(sst->fogMode, 0x0);
|
|
ISET(sst->alphaMode, 0x0);
|
|
ISET(sst->fbzMode, 0x0);
|
|
ISET(sst->lfbMode, 0x0);
|
|
ISET(sst->clipLeftRight, 0x0);
|
|
ISET(sst->clipBottomTop, 0x0);
|
|
|
|
ISET(sst->fogColor, 0x0);
|
|
ISET(sst->zaColor, 0x0);
|
|
ISET(sst->chromaKey, 0x0);
|
|
ISET(sst->stipple, 0x0);
|
|
ISET(sst->c0, 0x0);
|
|
ISET(sst->c1, 0x0);
|
|
|
|
ISET(sst->nopCMD, 0x1); /* Clear fbistat registers */
|
|
|
|
for(i=0; i<32; i++)
|
|
ISET(sst->fogTable[i], 0x0);
|
|
|
|
/* clear TMU registers */
|
|
ISET(sst->textureMode, 0x0);
|
|
ISET(sst->tLOD, 0x0);
|
|
ISET(sst->tDetail, 0x0);
|
|
ISET(sst->texBaseAddr, 0x0);
|
|
ISET(sst->texBaseAddr1, 0x0);
|
|
ISET(sst->texBaseAddr2, 0x0);
|
|
ISET(sst->texBaseAddr38, 0x0);
|
|
|
|
for(i=0; i<12; i++) {
|
|
ISET(sst->nccTable0[i], 0x0);
|
|
ISET(sst->nccTable1[i], 0x0);
|
|
}
|
|
sst1InitIdle(sstbase);
|
|
}
|
|
|
|
/*
|
|
** sst1InitShutdown():
|
|
** Shutdown SST-1
|
|
** Resets state of VGA_PASS to return monitor control back to the VGA
|
|
** Powers-down the DAC
|
|
** Resets the graphics clock in FBI to conserve power
|
|
**
|
|
** Returns:
|
|
** FXTRUE if successfully shuts down SST-1
|
|
** FXFALSE if cannot shut down the SST-1
|
|
**
|
|
*/
|
|
FX_EXPORT FxBool FX_CSTYLE sst1InitShutdown(FxU32 *sstbase)
|
|
{
|
|
volatile Sstregs *sstMaster = (Sstregs *) sstbase;
|
|
volatile Sstregs *sstSlave = (Sstregs *) sst1InitSliSlaveVirtAddr;
|
|
volatile Sstregs *sstPtr;
|
|
FxU32 n;
|
|
FxU32 SliEnable = sst1InitSliEnabled;
|
|
sst1ClkTimingStruct sstGrxClk;
|
|
|
|
if(!sstbase)
|
|
return(FXFALSE);
|
|
|
|
/* Wait for the SST-1 to finish rendering... */
|
|
sst1InitIdle(sstbase);
|
|
|
|
if(sst1InitSliEnabled) {
|
|
if(sst1InitShutdownSli(sstbase) == FXFALSE)
|
|
return(FXFALSE);
|
|
}
|
|
#ifdef __DOS32__
|
|
/*
|
|
* HACK alert. -MS
|
|
*
|
|
* There's a pciClose(), but nobody calls it. This is needed by the
|
|
* DOS DPMI services to close fxmemmap.vxd.
|
|
*
|
|
* We need to move this to the "appropriate" place, wherever that may be.
|
|
*/
|
|
/*pciClose(); [dBorca] not just yet! We still need PCI to shutdown */
|
|
#endif
|
|
|
|
if(GETENV(("SST_NOSHUTDOWN")))
|
|
INIT_PRINTF(("sst1InitShutdown(): Bypassing shutdown with SST_NOSHUTDOWN\n", n));
|
|
|
|
n = 0;
|
|
while(!GETENV(("SST_NOSHUTDOWN"))) {
|
|
if(!n)
|
|
sstPtr = sstMaster;
|
|
else
|
|
sstPtr = sstSlave;
|
|
|
|
if(sst1InitCheckBoard((FxU32 *) sstPtr) == FXFALSE)
|
|
return(FXFALSE);
|
|
|
|
INIT_PRINTF(("sst1InitShutdown(): Shutting down SST-1 #%d...\n", n));
|
|
|
|
/* Reset video unit to guarantee no contentions on the memory bus */
|
|
/* Blank DAC so VGA Passthru works properly */
|
|
ISET(sstPtr->fbiInit1,
|
|
IGET(sstPtr->fbiInit1) | (SST_VIDEO_RESET | SST_VIDEO_BLANK_EN));
|
|
/* Turn off dram refresh to guarantee no contentions on the
|
|
memory bus */
|
|
ISET(sstPtr->fbiInit2, IGET(sstPtr->fbiInit2) & ~SST_EN_DRAM_REFRESH);
|
|
|
|
/* Reset graphics subsystem */
|
|
ISET(sstPtr->fbiInit0,
|
|
IGET(sstPtr->fbiInit0) | (SST_GRX_RESET | SST_PCI_FIFO_RESET));
|
|
sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
|
|
ISET(sstPtr->fbiInit0, IGET(sstPtr->fbiInit0) & ~SST_PCI_FIFO_RESET);
|
|
sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
|
|
ISET(sstPtr->fbiInit0, IGET(sstPtr->fbiInit0) & ~SST_GRX_RESET);
|
|
sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
|
|
|
|
/* Turnaround VGA_PASS to allow VGA monitor */
|
|
sst1InitVgaPassCtrl((FxU32 *) sstPtr, 1);
|
|
|
|
sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
|
|
|
|
/* Set clock at 30 MHz to reduce power consumption... */
|
|
sst1InitComputeClkParams((float) 30.0, &sstGrxClk);
|
|
if(sst1InitSetGrxClk((FxU32 *) sstPtr, &sstGrxClk) == FXFALSE)
|
|
return(FXFALSE);
|
|
sst1CurrentBoard->initGrxClkDone = 0;
|
|
|
|
if((++n > 1) || !SliEnable)
|
|
break;
|
|
}
|
|
sst1InitIdle(sstbase);
|
|
INIT_PRINTF(("sst1InitShutdown(): Returning with status %d...\n", FXTRUE));
|
|
#ifdef INIT_OUTPUT
|
|
if ( sst1InitMsgFile != stdout && sst1InitMsgFile )
|
|
fclose(sst1InitMsgFile);
|
|
#endif
|
|
return(FXTRUE);
|
|
}
|
|
|
|
/*
|
|
** sst1InitCheckBoard():
|
|
** Set internal global variables for multiple SST-1 support
|
|
**
|
|
*/
|
|
FX_EXPORT FxBool FX_CSTYLE sst1InitCheckBoard(FxU32 *sstbase)
|
|
{
|
|
FxU32 n;
|
|
FxBool return_val = FXFALSE;
|
|
|
|
for(n=0; n<boardsInSystem; n++) {
|
|
if(sst1BoardInfo[n].virtAddr == sstbase) {
|
|
sst1InitDeviceNumber = sst1BoardInfo[n].deviceNumber;
|
|
sst1CurrentBoard = &sst1BoardInfo[n];
|
|
return_val = FXTRUE;
|
|
n = boardsInSystem;
|
|
}
|
|
}
|
|
return(return_val);
|
|
}
|
|
|
|
/*
|
|
** sst1InitGetBaseAddr():
|
|
** Return virtual base address to hardware
|
|
** Returns NULL if board requested has not been mapped
|
|
**
|
|
*/
|
|
FX_EXPORT FxU32 * FX_CSTYLE sst1InitGetBaseAddr(FxU32 boardNum)
|
|
{
|
|
return(sst1BoardInfo[boardNum].virtAddr);
|
|
}
|
|
|
|
/*
|
|
** sst1InitClearBoardInfo():
|
|
** Clear board configuration information
|
|
**
|
|
*/
|
|
void sst1InitClearBoardInfo(void)
|
|
{
|
|
FxU32 n, j;
|
|
|
|
for(n=0; n<SST1INIT_MAX_BOARDS; n++) {
|
|
//sst1BoardInfo[n].virtAddr = (FxU32 *) NULL;
|
|
//sst1BoardInfo[n].physAddr = (FxU32) NULL;
|
|
//sst1BoardInfo[n].deviceNumber = 0xdead;
|
|
//sst1BoardInfo[n].vendorID = 0xdead;
|
|
//sst1BoardInfo[n].deviceID = 0xdead;
|
|
//sst1BoardInfo[n].fbiRevision = 0xdead;
|
|
sst1BoardInfo[n].fbiBoardID = 0xdead;
|
|
sst1BoardInfo[n].fbiVideo16BPP = 0xdead;
|
|
sst1BoardInfo[n].fbiVideoWidth = 0xdead;
|
|
sst1BoardInfo[n].fbiVideoHeight = 0xdead;
|
|
sst1BoardInfo[n].fbiVideoRefresh = 0xdead;
|
|
sst1BoardInfo[n].fbiMemoryFifoEn = 0x0;
|
|
sst1BoardInfo[n].sstSliDetect = 0;
|
|
sst1BoardInfo[n].tmuRevision = 0xdead;
|
|
sst1BoardInfo[n].numberTmus = 0xdead;
|
|
sst1BoardInfo[n].tmuConfig = 0xdead;
|
|
sst1BoardInfo[n].fbiMemSize = 0x0;
|
|
for(j=0; j<MAX_NUM_TMUS; j++) {
|
|
sst1BoardInfo[n].tmuMemSize[j] = 0x0;
|
|
sst1BoardInfo[n].tmuInit0[j] = 0xdead;
|
|
sst1BoardInfo[n].tmuInit1[j] = 0xdead;
|
|
}
|
|
sst1BoardInfo[n].initGrxClkDone = 0;
|
|
sst1BoardInfo[n].vgaPassthruDisable = 0;
|
|
sst1BoardInfo[n].vgaPassthruEnable = 0;
|
|
sst1BoardInfo[n].fbiDacType = 0xdead;
|
|
sst1BoardInfo[n].memFifoStatusLwm = 0xdead;
|
|
//sst1BoardInfo[n].numBoardInsystem = 0xdead;
|
|
sst1BoardInfo[n].grxClkFreq = 0xdead;
|
|
sst1BoardInfo[n].fbiMemSpeed = 50;
|
|
sst1BoardInfo[n].tmuMemSpeed = 50;
|
|
sst1BoardInfo[n].tmuClkFixed = 0;
|
|
sst1BoardInfo[n].fbiRegulatorPresent = 0;
|
|
sst1BoardInfo[n].fbiTripleBufferingEnabled = FXFALSE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** sst1InitNumBoardsInSystem():
|
|
** Returns the number of SST-1 boards in the system
|
|
**
|
|
*/
|
|
FX_ENTRY FxU32 FX_CSTYLE sst1InitNumBoardsInSystem(void)
|
|
{
|
|
FxU32 vendorID = _3DFX_PCI_ID; /* 3Dfx Vendor ID */
|
|
FxU32 deviceID = 1; /* Find only sst1 boards */
|
|
FxU32 numBoards, j, n;
|
|
|
|
if(GETENV(("SST_BOARDS")))
|
|
numBoards = ATOI(GETENV(("SST_BOARDS")));
|
|
else {
|
|
numBoards = 0;
|
|
for(j=0; j<SST1INIT_MAX_BOARDS; j++) {
|
|
if(pciFindCardMulti(vendorID, deviceID, &n, j))
|
|
numBoards++;
|
|
}
|
|
}
|
|
return(numBoards);
|
|
}
|
|
|
|
static FxU32
|
|
mtrr;
|
|
|
|
/*
|
|
** sst1InitCachingOn
|
|
**
|
|
** Sets up memory caching on P6 systems.
|
|
**
|
|
*/
|
|
FX_EXPORT void FX_CSTYLE
|
|
sst1InitCachingOn(void)
|
|
{
|
|
FxU32
|
|
physAddr;
|
|
FxBool
|
|
res;
|
|
|
|
/* Turn on Write combining for wrap 1-n */
|
|
pciGetConfigData(PCI_BASE_ADDRESS_0, sst1InitDeviceNumber, &physAddr);
|
|
|
|
/* For some reason, there sometimes is a 008 at the end of the
|
|
physical address, so mask that puppy RTF out */
|
|
physAddr &= 0xfffff000;
|
|
|
|
/* Set up USWC MTRR */
|
|
res = pciFindMTRRMatch(physAddr, 0x1000000,
|
|
PciMemTypeWriteCombining, &mtrr);
|
|
|
|
if (!res)
|
|
res = pciFindFreeMTRR(&mtrr);
|
|
else
|
|
return; /* It's already there. We're done. */
|
|
|
|
if (res)
|
|
pciSetMTRR(mtrr, physAddr, 0x1000000, PciMemTypeWriteCombining);
|
|
|
|
} /* sst1InitSetCacheType */
|
|
|
|
|
|
#pragma optimize ("",on)
|