557 lines
22 KiB
C
557 lines
22 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 initializing scanline interleaving
|
|
**
|
|
*/
|
|
#ifndef __GNUC__
|
|
#pragma optimize ("",off)
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <sst.h>
|
|
#define FX_DLL_DEFINITION
|
|
#include <fxdll.h>
|
|
#include <sst1vid.h>
|
|
#include <sst1init.h>
|
|
|
|
/*
|
|
** sst1InitSli():
|
|
** Setup Multiple SST-1 subsystems for Scanline Interleaving
|
|
** sstbase0 defined to be the SLI Master
|
|
** sstbase1 defined to be the SLI Slave
|
|
**
|
|
*/
|
|
FX_EXPORT FxBool FX_CSTYLE sst1InitSli(FxU32 *sstbase0, FxU32 *sstbase1)
|
|
{
|
|
FxU32 j, n, MasterPhysAddr, cntr;
|
|
volatile Sstregs *sstMaster = (Sstregs *) sstbase0;
|
|
volatile Sstregs *sstSlave = (Sstregs *) sstbase1;
|
|
FxU32 MasterInit1, SlaveInit1;
|
|
FxU32 memOffset;
|
|
FxU32 masterVInClkDel, masterVOutClkDel;
|
|
FxU32 slaveVInClkDel, slaveVOutClkDel;
|
|
FxU32 masterPVOutClkDel, slavePVOutClkDel;
|
|
FxU32 pciFifoLwm, memFifoLwm;
|
|
FxU32 clkFreqMaster;
|
|
int i;
|
|
|
|
/* Check to make sure master and slave are installed properly */
|
|
/* Master should have a clock frequency setting of 54 MHz */
|
|
/* Slave should have a clock frequency setting of 50 MHz */
|
|
/* sst1InitCalcGrxClk() will actually setup the master to run at 54 MHz, */
|
|
/* even though the default strapping is 54 MHz. The 54 MHz strapping is */
|
|
/* implemented to allow software detection of which SLI board is the */
|
|
/* SLI Master */
|
|
if(sst1InitCheckBoard(sstbase0) == FXFALSE)
|
|
return(FXFALSE);
|
|
clkFreqMaster = 40 + (((sst1CurrentBoard->tmuConfig >> 3) & 0x7) << 2) +
|
|
(sst1CurrentBoard->fbiConfig & 0x3);
|
|
if(!(GETENV(("SST_IGNORE_SLI_CHECK")))) {
|
|
if(clkFreqMaster != 54) {
|
|
INIT_PRINTF(("sst1InitSli(): SLI Slave board installed as SLI Master.\n"));
|
|
INIT_PRINTF((" Please power-down, swap SLI boards and re-boot.\n"));
|
|
return(FXFALSE);
|
|
}
|
|
} else
|
|
INIT_PRINTF(("sst1InitSli(): WARNING: Bypassing check for proper SLI installation...\n"));
|
|
|
|
INIT_PRINTF(("sst1InitSli(): Enabling Scanline Interleaving...\n"));
|
|
|
|
/* Setup SLI Slave... */
|
|
cntr = 0;
|
|
while(1) {
|
|
if(sst1InitCheckBoard(sstbase1) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE,
|
|
(j | SST_SCANLINE_SLV_OWNPCI | SST_SCANLINE_SLI_SLV));
|
|
ISET(sstSlave->fbiInit1, IGET(sstSlave->fbiInit1) |
|
|
(SST_VIDEO_RESET | SST_EN_SCANLINE_INTERLEAVE));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
PCICFG_WR(SST1_PCI_VCLK_DISABLE, 0x0); /* Disable video clock */
|
|
ISET(SST_TREX(sstSlave,0)->trexInit1, sst1CurrentBoard->tmuInit1[0] |
|
|
SST_EN_TEX_SCANLINE_INTERLEAVE | SST_TEX_SCANLINE_INTERLEAVE_SLAVE);
|
|
sst1InitIdle(sstbase1);
|
|
ISET(SST_TREX(sstSlave,1)->trexInit1, sst1CurrentBoard->tmuInit1[1] |
|
|
SST_EN_TEX_SCANLINE_INTERLEAVE | SST_TEX_SCANLINE_INTERLEAVE_SLAVE);
|
|
sst1InitIdle(sstbase1);
|
|
ISET(SST_TREX(sstSlave,2)->trexInit1, sst1CurrentBoard->tmuInit1[2] |
|
|
SST_EN_TEX_SCANLINE_INTERLEAVE | SST_TEX_SCANLINE_INTERLEAVE_SLAVE);
|
|
sst1InitIdle(sstbase1);
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
ISET(sstSlave->fbiInit2, (IGET(sstSlave->fbiInit2) &
|
|
~(SST_EN_DRAM_BANKED | SST_SWAP_ALGORITHM)) | SST_SWAP_DACDATA0);
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
/* Initialize Y-Origin */
|
|
ISET(sstSlave->fbiInit3, (IGET(sstSlave->fbiInit3) & ~SST_YORIGIN_TOP) |
|
|
((sst1CurrentBoard->fbiVideoHeight - 1) << SST_YORIGIN_TOP_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
memOffset = ((IGET(sstSlave->fbiInit2) & SST_VIDEO_BUFFER_OFFSET) >>
|
|
SST_VIDEO_BUFFER_OFFSET_SHIFT) + 16;
|
|
if(memOffset & 0x1) {
|
|
if((memOffset + 1) & 0x3) /* not divisible by 4... */
|
|
memOffset = (memOffset + 1) >> 1;
|
|
else
|
|
memOffset = (memOffset + 3) >> 1;
|
|
} else {
|
|
if(memOffset & 0x3) /* not divisible by 4... */
|
|
memOffset = (memOffset + 2) >> 1;
|
|
else
|
|
memOffset = memOffset >> 1;
|
|
}
|
|
if(sst1CurrentBoard->fbiVideoWidth == 960) {
|
|
memOffset = 170;
|
|
ISET(sstSlave->fbiInit0, IGET(sstSlave->fbiInit0) &
|
|
~SST_MEM_FIFO_EN);
|
|
INIT_PRINTF(("sst1InitSli(): Disabling memory fifo...\n"));
|
|
}
|
|
ISET(sstSlave->fbiInit2, (IGET(sstSlave->fbiInit2) &
|
|
~SST_VIDEO_BUFFER_OFFSET) |
|
|
(memOffset << SST_VIDEO_BUFFER_OFFSET_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
ISET(sstSlave->fbiInit0, (IGET(sstSlave->fbiInit0) &
|
|
~SST_MEM_FIFO_HWM) | (0x100 << SST_MEM_FIFO_HWM_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
ISET(sstSlave->fbiInit4, (IGET(sstSlave->fbiInit4) &
|
|
~SST_MEM_FIFO_ROW_BASE) |
|
|
((3*memOffset) << SST_MEM_FIFO_ROW_BASE_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
//slaveVInClkDel = 0;
|
|
//slaveVOutClkDel = 1;
|
|
//slavePVOutClkDel = 1;
|
|
slaveVInClkDel = 2;
|
|
slaveVOutClkDel = 0;
|
|
slavePVOutClkDel = 3;
|
|
if(GETENV(("SST_SLIS_VOUT_CLKDEL")) &&
|
|
(SSCANF(GETENV(("SST_SLIS_VOUT_CLKDEL")), "%i", &i) == 1))
|
|
slaveVOutClkDel = i;
|
|
if(GETENV(("SST_SLIS_PVOUT_CLKDEL")) &&
|
|
(SSCANF(GETENV(("SST_SLIS_PVOUT_CLKDEL")), "%i", &i) == 1))
|
|
slavePVOutClkDel = i;
|
|
if(GETENV(("SST_SLIS_VIN_CLKDEL")) &&
|
|
(SSCANF(GETENV(("SST_SLIS_VIN_CLKDEL")), "%i", &i) == 1))
|
|
slaveVInClkDel = i;
|
|
INIT_PRINTF(("sst1InitSli(): slaveVinClkdel=0x%x, slaveVOutClkDel=0x%x, slavePVOutClkDel=0x%x\n",
|
|
slaveVInClkDel, slaveVOutClkDel, slavePVOutClkDel));
|
|
if(sst1CurrentBoard->fbiVideo16BPP)
|
|
/* 16-bit Video Output */
|
|
ISET(sstSlave->fbiInit1, (IGET(sstSlave->fbiInit1) &
|
|
~(SST_VIDEO_VCLK_2X_OUTPUT_DEL | SST_VIDEO_VCLK_DEL)) |
|
|
SST_EN_SCANLINE_INTERLEAVE |
|
|
/* SST_VIDEO_VID_CLK_SLAVE | */
|
|
SST_VIDEO_VID_CLK_2X |
|
|
/* SST_VIDEO_INVERT_VID_CLK_2X | */
|
|
SST_PCI_WRWS_1 |
|
|
(slaveVInClkDel << SST_VIDEO_VCLK_DEL_SHIFT) |
|
|
(slaveVOutClkDel << SST_VIDEO_VCLK_2X_OUTPUT_DEL_SHIFT) |
|
|
(slavePVOutClkDel << SST_VIDEO_VCLK_2X_INPUT_DEL_SHIFT));
|
|
else
|
|
/* 24-bit Video Output */
|
|
ISET(sstSlave->fbiInit1, (IGET(sstSlave->fbiInit1) &
|
|
~(SST_VIDEO_VCLK_2X_OUTPUT_DEL | SST_VIDEO_VCLK_DEL |
|
|
SST_VIDEO_VCLK_SEL | SST_VIDEO_VCLK_2X_INPUT_DEL)) |
|
|
SST_EN_SCANLINE_INTERLEAVE |
|
|
/* SST_VIDEO_VID_CLK_SLAVE | */
|
|
SST_VIDEO_VID_CLK_2X |
|
|
/* SST_VIDEO_INVERT_VID_CLK_2X | */
|
|
(0x0 << SST_VIDEO_VCLK_SEL_SHIFT) |
|
|
SST_PCI_WRWS_1 |
|
|
(slaveVInClkDel << SST_VIDEO_VCLK_DEL_SHIFT) |
|
|
(slaveVOutClkDel << SST_VIDEO_VCLK_2X_OUTPUT_DEL_SHIFT) |
|
|
(slavePVOutClkDel << SST_VIDEO_VCLK_2X_INPUT_DEL_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
ISET(sstSlave->fbiInit1, IGET(sstSlave->fbiInit1) &
|
|
~(SST_VIDEO_DATA_OE_EN |
|
|
SST_VIDEO_BLANK_OE_EN |
|
|
SST_VIDEO_DCLK_OE_EN |
|
|
SST_VIDEO_HVSYNC_OE_EN));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
/* Initialize pci and memory fifos... */
|
|
pciFifoLwm = 16;
|
|
memFifoLwm = 26;
|
|
if(!GETENV(("SST_PCIFIFO_LWM")))
|
|
ISET(sstSlave->fbiInit0, (IGET(sstSlave->fbiInit0) &
|
|
~SST_PCI_FIFO_LWM) | (pciFifoLwm << SST_PCI_FIFO_LWM_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
if(!GETENV(("SST_MEMFIFO_LWM")))
|
|
ISET(sstSlave->fbiInit4, (IGET(sstSlave->fbiInit4) &
|
|
~SST_MEM_FIFO_LWM) | (memFifoLwm << SST_MEM_FIFO_LWM_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
INIT_PRINTF(("sst1InitSli(): Slave pciFifoLwm:%d, memFifoLwm:%d\n",
|
|
((IGET(sstSlave->fbiInit0) & SST_PCI_FIFO_LWM) >>
|
|
SST_PCI_FIFO_LWM_SHIFT),
|
|
((IGET(sstSlave->fbiInit4) & SST_MEM_FIFO_LWM) >>
|
|
SST_MEM_FIFO_LWM_SHIFT)));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
ISET(sstSlave->fbiInit1, IGET(sstSlave->fbiInit1) |
|
|
(SST_EN_SCANLINE_INTERLEAVE | SST_VIDEO_RESET));
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
ISET(sstSlave->fbiInit1, IGET(sstSlave->fbiInit1) & ~SST_VIDEO_RESET);
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
sst1InitIdleFBINoNOP(sstbase1);
|
|
if(IGET(sstSlave->fbiInit1) & SST_VIDEO_RESET) {
|
|
INIT_PRINTF(("sst1InitSli(): Could not unReset Slave Video...\n"));
|
|
if(++cntr < 10)
|
|
continue;
|
|
else
|
|
return(FXFALSE);
|
|
}
|
|
if(!(IGET(sstSlave->fbiInit1) & SST_EN_SCANLINE_INTERLEAVE)) {
|
|
INIT_PRINTF(("sst1InitSli(): Could not setup SLI Slave...\n"));
|
|
if(++cntr < 10)
|
|
continue;
|
|
else
|
|
return(FXFALSE);
|
|
}
|
|
SlaveInit1 = IGET(sstSlave->fbiInit1);
|
|
break;
|
|
}
|
|
|
|
/* Setup SLI Master... */
|
|
ISET(sstMaster->fbiInit1, IGET(sstMaster->fbiInit1) | SST_VIDEO_RESET);
|
|
ISET(SST_TREX(sstMaster,0)->trexInit1, sst1CurrentBoard->tmuInit1[0] |
|
|
SST_EN_TEX_SCANLINE_INTERLEAVE);
|
|
sst1InitIdle(sstbase0);
|
|
ISET(SST_TREX(sstMaster,1)->trexInit1, sst1CurrentBoard->tmuInit1[1] |
|
|
SST_EN_TEX_SCANLINE_INTERLEAVE);
|
|
sst1InitIdle(sstbase0);
|
|
ISET(SST_TREX(sstMaster,2)->trexInit1, sst1CurrentBoard->tmuInit1[2] |
|
|
SST_EN_TEX_SCANLINE_INTERLEAVE);
|
|
sst1InitIdle(sstbase0);
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
ISET(sstMaster->fbiInit2, (IGET(sstMaster->fbiInit2) &
|
|
~(SST_EN_DRAM_BANKED | SST_SWAP_ALGORITHM)) | SST_SWAP_DACDATA0);
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
/* Initialize Y-Origin */
|
|
ISET(sstMaster->fbiInit3, (IGET(sstMaster->fbiInit3) & ~SST_YORIGIN_TOP) |
|
|
((sst1CurrentBoard->fbiVideoHeight) << SST_YORIGIN_TOP_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
if(sst1CurrentBoard->fbiVideoWidth == 960)
|
|
ISET(sstMaster->fbiInit0, IGET(sstMaster->fbiInit0) & ~SST_MEM_FIFO_EN);
|
|
ISET(sstMaster->fbiInit2, (IGET(sstMaster->fbiInit2) &
|
|
~SST_VIDEO_BUFFER_OFFSET) | (memOffset << SST_VIDEO_BUFFER_OFFSET_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
ISET(sstMaster->fbiInit0, (IGET(sstMaster->fbiInit0) & ~SST_MEM_FIFO_HWM) |
|
|
(0x100 << SST_MEM_FIFO_HWM_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
ISET(sstMaster->fbiInit4, (IGET(sstMaster->fbiInit4) &
|
|
~SST_MEM_FIFO_ROW_BASE) | ((3*memOffset) << SST_MEM_FIFO_ROW_BASE_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
//masterVInClkDel = 1;
|
|
//masterVOutClkDel = 1;
|
|
//masterPVOutClkDel = 1;
|
|
masterVInClkDel = 2;
|
|
masterVOutClkDel = 0;
|
|
masterPVOutClkDel = 3;
|
|
if(GETENV(("SST_SLIM_VOUT_CLKDEL")) &&
|
|
(SSCANF(GETENV(("SST_SLIM_VOUT_CLKDEL")), "%i", &i) == 1))
|
|
masterVOutClkDel = i;
|
|
if(GETENV(("SST_SLIM_PVOUT_CLKDEL")) &&
|
|
(SSCANF(GETENV(("SST_SLIM_PVOUT_CLKDEL")), "%i", &i) == 1))
|
|
masterPVOutClkDel = i;
|
|
if(GETENV(("SST_SLIM_VIN_CLKDEL")) &&
|
|
(SSCANF(GETENV(("SST_SLIM_VIN_CLKDEL")), "%i", &i) == 1))
|
|
masterVInClkDel = i;
|
|
INIT_PRINTF(("sst1InitSli(): masterVinClkdel=0x%x, masterVOutClkDel=0x%x, masterPVOutClkDel=0x%x\n",
|
|
masterVInClkDel, masterVOutClkDel, masterPVOutClkDel));
|
|
if(sst1CurrentBoard->fbiVideo16BPP)
|
|
/* 16-bit Video Output */
|
|
ISET(sstMaster->fbiInit1, (IGET(sstMaster->fbiInit1) &
|
|
~(SST_VIDEO_VCLK_2X_OUTPUT_DEL | SST_VIDEO_VCLK_DEL)) |
|
|
SST_EN_SCANLINE_INTERLEAVE |
|
|
SST_VIDEO_VID_CLK_2X |
|
|
/* SST_VIDEO_INVERT_VID_CLK_2X | */
|
|
SST_PCI_WRWS_1 |
|
|
(masterVInClkDel << SST_VIDEO_VCLK_DEL_SHIFT) |
|
|
(masterVOutClkDel << SST_VIDEO_VCLK_2X_OUTPUT_DEL_SHIFT) |
|
|
(masterPVOutClkDel << SST_VIDEO_VCLK_2X_INPUT_DEL_SHIFT));
|
|
else
|
|
/* 24-bit Video Output */
|
|
ISET(sstMaster->fbiInit1, (IGET(sstMaster->fbiInit1) &
|
|
~(SST_VIDEO_VCLK_2X_OUTPUT_DEL | SST_VIDEO_VCLK_DEL |
|
|
SST_VIDEO_VCLK_SEL | SST_VIDEO_VCLK_2X_INPUT_DEL)) |
|
|
SST_EN_SCANLINE_INTERLEAVE |
|
|
SST_VIDEO_VID_CLK_2X |
|
|
/*SST_VIDEO_INVERT_VID_CLK_2X | */
|
|
(0x0 << SST_VIDEO_VCLK_SEL_SHIFT) |
|
|
SST_PCI_WRWS_1 |
|
|
(masterVInClkDel << SST_VIDEO_VCLK_DEL_SHIFT) |
|
|
(masterVOutClkDel << SST_VIDEO_VCLK_2X_OUTPUT_DEL_SHIFT) |
|
|
(masterPVOutClkDel << SST_VIDEO_VCLK_2X_INPUT_DEL_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
/* Initialize pci and memory fifos... */
|
|
pciFifoLwm = 16;
|
|
memFifoLwm = 26;
|
|
if(!GETENV(("SST_PCIFIFO_LWM")))
|
|
ISET(sstMaster->fbiInit0, (IGET(sstMaster->fbiInit0) &
|
|
~SST_PCI_FIFO_LWM) | (pciFifoLwm << SST_PCI_FIFO_LWM_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
if(!GETENV(("SST_MEMFIFO_LWM")))
|
|
ISET(sstMaster->fbiInit4, (IGET(sstMaster->fbiInit4) &
|
|
~SST_MEM_FIFO_LWM) | (memFifoLwm << SST_MEM_FIFO_LWM_SHIFT));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
INIT_PRINTF(("sst1InitSli(): Master pciFifoLwm:%d, memFifoLwm:%d\n",
|
|
((IGET(sstMaster->fbiInit0) & SST_PCI_FIFO_LWM) >>
|
|
SST_PCI_FIFO_LWM_SHIFT),
|
|
((IGET(sstMaster->fbiInit4) & SST_MEM_FIFO_LWM) >>
|
|
SST_MEM_FIFO_LWM_SHIFT)));
|
|
ISET(sstMaster->fbiInit1, IGET(sstMaster->fbiInit1) & ~SST_VIDEO_RESET);
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
MasterInit1 = IGET(sstMaster->fbiInit1);
|
|
|
|
/* Master */
|
|
if(sst1InitCheckBoard(sstbase0) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE,
|
|
(j & ~(SST_SCANLINE_SLV_OWNPCI | SST_SCANLINE_SLI_SLV)));
|
|
MasterPhysAddr = sst1CurrentBoard->physAddr;
|
|
sst1InitReturnStatus(sstbase0); /* flush pci packer with reads */
|
|
sst1InitReturnStatus(sstbase0);
|
|
sst1InitReturnStatus(sstbase0);
|
|
|
|
/* Slave */
|
|
if(sst1InitCheckBoard(sstbase1) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE,
|
|
((j & ~(SST_SCANLINE_SLV_OWNPCI)) | SST_SCANLINE_SLI_SLV));
|
|
/* Map both boards to same Master physical address */
|
|
PCICFG_WR(PCI_BASE_ADDRESS_0, MasterPhysAddr);
|
|
sst1InitReturnStatus(sstbase0); /* flush pci packer with reads */
|
|
sst1InitReturnStatus(sstbase0);
|
|
sst1InitReturnStatus(sstbase0);
|
|
|
|
/* Reset Video units simultaneously */
|
|
ISET(sstMaster->fbiInit1, MasterInit1 | SST_VIDEO_RESET);
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
ISET(sstMaster->fbiInit1, MasterInit1);
|
|
if(sst1InitCheckBoard(sstbase0) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, 0x0); /* Disable writes to init regs */
|
|
sst1InitReturnStatus(sstbase0);
|
|
ISET(sstMaster->fbiInit1, SlaveInit1);
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
/* Enable writes to init regs */
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, (SST_INITWR_EN | SST_PCI_FIFOWR_EN));
|
|
sst1InitIdleFBINoNOP(sstbase0);
|
|
|
|
if(sst1InitCheckBoard(sstbase1) == FXFALSE)
|
|
return(FXFALSE);
|
|
/* Disable writes to slave Init Registers */
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, (j & ~SST_INITWR_EN));
|
|
|
|
if(sst1InitCheckBoard(sstbase0) == FXFALSE)
|
|
return(FXFALSE);
|
|
|
|
/* Clear buffers as a result of new buffer offsets... */
|
|
if(!GETENV(("SST_VIDEO_NOCLEAR"))) {
|
|
/* Clear Screen */
|
|
FxU32 clearColor = 0x0;
|
|
|
|
if(GETENV(("SST_VIDEO_CLEARCOLOR")) &&
|
|
(SSCANF(GETENV(("SST_VIDEO_CLEARCOLOR")), "%i", &i) == 1))
|
|
clearColor = i;
|
|
ISET(sstMaster->c1, clearColor);
|
|
ISET(sstMaster->c0, clearColor);
|
|
ISET(sstMaster->zaColor, 0x0);
|
|
ISET(sstMaster->clipLeftRight, sst1CurrentBoard->fbiVideoWidth);
|
|
ISET(sstMaster->clipBottomTop, sst1CurrentBoard->fbiVideoHeight);
|
|
ISET(sstMaster->fbzMode, SST_RGBWRMASK | SST_ZAWRMASK);
|
|
ISET(sstMaster->fastfillCMD, 0x0); /* Frontbuffer & Z/A */
|
|
ISET(sstMaster->fbzMode, SST_RGBWRMASK | SST_DRAWBUFFER_BACK);
|
|
ISET(sstMaster->fastfillCMD, 0x0);
|
|
ISET(sstMaster->nopCMD, 0x1);
|
|
}
|
|
sst1InitSliEnabled = 1;
|
|
sst1InitSliSlaveVirtAddr = sstbase1;
|
|
|
|
sst1InitIdle(sstbase0);
|
|
|
|
/* Synchronize Boards */
|
|
for(j=0; j<3; j++) {
|
|
while(!(sst1InitReturnStatus(sstbase0) & SST_VRETRACE))
|
|
;
|
|
IGET(sstMaster->status);
|
|
ISET(sstMaster->swapbufferCMD, 0x0);
|
|
IGET(sstMaster->status);
|
|
sst1InitIdle(sstbase0);
|
|
}
|
|
while(!(sst1InitReturnStatus(sstbase0) & SST_VRETRACE))
|
|
;
|
|
IGET(sstMaster->status);
|
|
ISET(sstMaster->swapbufferCMD, 0x1);
|
|
IGET(sstMaster->status);
|
|
sst1InitIdle(sstbase0);
|
|
|
|
return(FXTRUE);
|
|
}
|
|
|
|
/*
|
|
** sst1InitShutdownSli():
|
|
** Shutdown SLI configuration
|
|
**
|
|
*/
|
|
FX_EXPORT FxBool FX_CSTYLE sst1InitShutdownSli(FxU32 *sstbase)
|
|
{
|
|
volatile Sstregs *sstMaster = (Sstregs *) sstbase;
|
|
volatile Sstregs *sstSlave = (Sstregs *) sst1InitSliSlaveVirtAddr;
|
|
FxU32 n, j, cntr;
|
|
|
|
if(sst1InitSliEnabled) {
|
|
INIT_PRINTF(("sst1InitShutdownSli(): Disabling Scanline Interleaving...\n"));
|
|
sst1InitSliEnabled = 0;
|
|
|
|
cntr = 0;
|
|
while(1) {
|
|
if(sst1InitCheckBoard(sst1InitSliSlaveVirtAddr) == FXFALSE)
|
|
return(FXFALSE);
|
|
/* Remap slave to original physical address */
|
|
PCICFG_WR(PCI_BASE_ADDRESS_0, sst1CurrentBoard->physAddr);
|
|
/* Turn off scanline interleaving in slave */
|
|
/* Enable writes to init registers in slave */
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE,
|
|
(j | SST_SCANLINE_SLV_OWNPCI | SST_SCANLINE_SLI_SLV |
|
|
SST_INITWR_EN | SST_PCI_FIFOWR_EN));
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j); /* delay */
|
|
ISET(sstSlave->fbiInit1, IGET(sstSlave->fbiInit1) &
|
|
~SST_EN_SCANLINE_INTERLEAVE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE,
|
|
(j & ~(SST_SCANLINE_SLV_OWNPCI | SST_SCANLINE_SLI_SLV)));
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j); /* delay */
|
|
sst1InitIdle((FxU32 *) sstSlave);
|
|
|
|
|
|
if(IGET(sstSlave->fbiInit1) & SST_EN_SCANLINE_INTERLEAVE) {
|
|
if(++cntr < 10)
|
|
continue;
|
|
else {
|
|
INIT_PRINTF(("sst1InitShutdown(): Could not disable Slave SLI...\n"));
|
|
return(FXFALSE);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
ISET(sstMaster->fbiInit1, IGET(sstMaster->fbiInit1) &
|
|
~SST_EN_SCANLINE_INTERLEAVE);
|
|
sst1InitIdle((FxU32 *) sstMaster);
|
|
}
|
|
return(FXTRUE);
|
|
}
|
|
|
|
/*
|
|
** sst1InitSliPciOwner():
|
|
** Specify which SLI card owns PCI bus control
|
|
**
|
|
*/
|
|
FX_EXPORT FxBool FX_CSTYLE sst1InitSliPciOwner(FxU32 *sstbase, FxU32 owner)
|
|
{
|
|
FxU32 j, n;
|
|
static FxU32 masterIsOwner = 1;
|
|
|
|
if(!sst1InitSliEnabled)
|
|
return(FXTRUE);
|
|
|
|
/* Flush PCI packers... */
|
|
sst1InitReturnStatus(sstbase);
|
|
sst1InitReturnStatus(sstbase);
|
|
sst1InitReturnStatus(sstbase);
|
|
|
|
if(masterIsOwner) {
|
|
if(owner == SST_SLI_SLAVE_OWNPCI) {
|
|
masterIsOwner = 0;
|
|
if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, ((j & ~SST_SLI_OWNPCI) |
|
|
SST_SLI_SLAVE_OWNPCI));
|
|
if(sst1InitCheckBoard(sst1InitSliSlaveVirtAddr) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, ((j & ~SST_SLI_OWNPCI) |
|
|
SST_SLI_SLAVE_OWNPCI));
|
|
} else
|
|
return(FXTRUE);
|
|
} else {
|
|
if(owner == SST_SLI_MASTER_OWNPCI) {
|
|
masterIsOwner = 1;
|
|
if(sst1InitCheckBoard(sst1InitSliSlaveVirtAddr) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, ((j & ~SST_SLI_OWNPCI) |
|
|
SST_SLI_MASTER_OWNPCI));
|
|
if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
|
return(FXFALSE);
|
|
PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
|
|
PCICFG_WR(SST1_PCI_INIT_ENABLE, ((j & ~SST_SLI_OWNPCI) |
|
|
SST_SLI_MASTER_OWNPCI));
|
|
} else
|
|
return(FXTRUE);
|
|
}
|
|
return(FXTRUE);
|
|
}
|
|
|
|
/*
|
|
** sst1InitSliDetect():
|
|
** Determine if scanline interleave has been detected (either through
|
|
** power-up settings or through SST_SLIDETECT)
|
|
**
|
|
*/
|
|
FX_ENTRY FxU32 FX_CALL sst1InitSliDetect(FxU32 *sstbase)
|
|
{
|
|
static int firstTime = 1;
|
|
static FxU32 sliDetected = 0;
|
|
FxU32 fbiRev;
|
|
volatile Sstregs *sst;
|
|
|
|
if(firstTime) {
|
|
firstTime = 0;
|
|
if(GETENV(("SST_SLIDETECT")))
|
|
sliDetected = ATOI(GETENV(("SST_SLIDETECT")));
|
|
else {
|
|
PCICFG_RD(PCI_REVISION_ID, fbiRev);
|
|
sst = (Sstregs *) sstbase;
|
|
if((IGET(sst->fbiInit1) & SST_SLI_DETECT) && (fbiRev > 1) &&
|
|
(boardsInSystem) > 1 &&
|
|
((IGET(sst->fbiInit3) & SST_FBI_MEM_TYPE) >>
|
|
(SST_FBI_MEM_TYPE_SHIFT + 2)))
|
|
sliDetected = 1;
|
|
}
|
|
}
|
|
return(sliDetected);
|
|
}
|
|
|
|
#ifndef __GNUC__
|
|
#pragma optimize ("",on)
|
|
#endif
|