source: trunk/src/opengl/glide/cvg/init/sst1init.c

Last change on this file was 6653, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 45.1 KB
Line 
1/*-*-c++-*-*/
2/* $Id: sst1init.c,v 1.2 2001-09-05 14:30:42 bird Exp $ */
3/*
4** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
5** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
6** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
7** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
8** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
9** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
10** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
11** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
12**
13** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
14** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
15** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
16** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
17** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
18** THE UNITED STATES.
19**
20** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
21**
22** $Revision: 1.2 $
23** $Date: 2001-09-05 14:30:42 $
24**
25*/
26
27/*
28** Initialization code for SST-1 board.
29**
30** NOTE: This code must compiled with optimizations DISABLED!!
31**
32** The following environment variables can optionally be used to alter
33** functionality (A value of X is a "don't care"):
34**
35** Variable Value Description
36** -------- ----- -----------
37** SSTV2_ARCADE X Allow special configs for arcade use
38** SSTV2_ALLOC_AUX {0,1} Number of aux. buffers to allocate
39** SSTV2_ALLOC_COLOR {2,3} Number of color buffers to allocate
40** SSTV2_BACKPORCH hex Specify value of backPorch video register
41** SSTV2_BOARDS val Specify number of SST-1 boards in system
42** SSTV2_CMDFIFO_DIRECT X Enable Direct Execution of CMDFIFO
43** SSTV2_CMDFIFO_NOHOLES X Disable hole counting feature in CMDFIFO
44** SSTV2_DEBUGDAC X Print out debug information for DAC
45** reads and writes
46** SSTV2_DEVICEID X Specify the device ID value passed to
47** the PCI library
48** SSTV2_DIMENSIONS hex Specify value of videoDimensions register
49** SSTV2_FASTMEM_RAS_READS X Allow fast ras reads
50** SSTV2_FASTPCIRD X Enable fast PCI reads
51** SSTV2_FBICFG hex Specify FBI configuration strapping bits
52** SSTV2_FBI_MEMSIZE val Specify amount of frame buffer memory
53** SSTV2_FT_CLKDEL hex Fbi-to-Trex clock delay value
54** SSTV2_GAMMA float Floating point value for gamma correction
55** SSTV2_GRXCLK val 16 <= Frequency < 80 (50 is default)
56** SSTV2_HSYNC hex Specify value of hSync video register
57** SSTV2_IGNORE_CLKDELAYS X Ignore calls to sst1InitSetClkDelays()
58** SSTV2_IGNORE_IDLE X Ignore calls to sst1InitIdle*()
59** SSTV2_IGNORE_INIT_GAMMA X Bypass sst1InitGamma call and return
60** SSTV2_IGNORE_INIT_REGISTERS X Bypass sst1InitRegisters call and return
61** SSTV2_IGNORE_INIT_VIDEO X Bypass sst1InitVideo call and return
62** SSTV2_INITDEBUG X Enable debug output
63** SSTV2_INITDEBUG_FILE file File to direct all debug output
64** SSTV2_MEMFIFO 0 Disable FBI Memory FIFO
65** SSTV2_MEMFIFO 1 Enable FBI Memory FIFO
66** SSTV2_MEMFIFO_ENTRIES hex Set number of entries in memory fifo
67** SSTV2_MEMFIFO_HWM hex Set memory fifo high water mark
68** SSTV2_MEMFIFO_LFB {0,1} Specify LFB writes through Memory FIFO
69** SSTV2_MEMFIFO_LWM hex Set memory fifo low water mark
70** SSTV2_MEMFIFO_TEX {0,1} Specify Texture writes through Mem FIFO
71** SSTV2_MEMOFFSET hex Specify value of memoffset video register
72** SSTV2_NOCHECKHANG X Do not Check for FBI Hangs for texturing
73** SSTV2_NODEVICEINFO X Ignore calls to sst1InitFillDeviceInfo()
74** SSTV2_NOSHUTDOWN X Do not turn off monitor refresh on call
75** to sst1InitShutdown()
76** SSTV2_NUM_TMUS {1,2,3} Specify number of TMUs detected
77** SSTV2_PCIFIFO_LWM hex Set pci fifo low water mark
78** SSTV2_PFT_CLKDEL hex Preliminary Fbi-to-Trex clock delay value
79** SSTV2_PTF0_CLKDEL hex Prelim TMU2Fbi clock delay value (TMU #0)
80** SSTV2_PTF1_CLKDEL hex Prelim TMU2Fbi clock delay value (TMU #1)
81** SSTV2_PTF2_CLKDEL hex Prelim TMU2Fbi clock delay value (TMU #2)
82** SSTV2_SIPROCESS_CNTR hex Silicon process monitor PCI counter load
83** SSTV2_SLIDETECT {0,1} Specify Scanline Interleaving detection
84** SSTV2_SLIM_VIN_CLKDEL hex Specify FBI internal video clock delay
85** (SLI Master)
86** SSTV2_SLIM_VOUT_CLKDEL hex Specify FBI external video clock delay
87** (SLI Master)
88** SSTV2_SLIS_VIN_CLKDEL hex Specify FBI internal video clock delay
89** (SLI Slave)
90** SSTV2_SLIS_VOUT_CLKDEL hex Specify FBI external video clock delay
91** (SLI Slave)
92** SSTV2_SCREENREFRESH {60,75, Select monitor refresh rate
93** 85,120}
94** SSTV2_SCREENREZ {512, Select monitor resolution (512x384)
95** 512256, (512x256)
96** 640400, (640x400)
97** 640, (640x480)
98** 800, (800x600)
99** 856, (856x600)
100** 960, (960x720)
101** 1024} (1024x768)
102** SSTV2_SLOWMEM_RTW X Insert wait state for read-to-write
103** transitions
104** SSTV2_SLOWMEM_WTR X Insert wait state for write-to-read
105** transitions
106** SSTV2_SLOWPCIWR X Enable 1 wait-state PCI writes
107** SSTV2_SLISWAP 1 Use dac_data[0] for SLI swapping
108** SSTV2_SWAPBOARDS X Swap order of mapping boards
109** SSTV2_TEXMAP_DISABLE X Disable texture mapping
110** SSTV2_TF0_CLKDEL hex Trex-to-Fbi clock delay value (TMU #0)
111** SSTV2_TF1_CLKDEL hex Trex-to-Fbi clock delay value (TMU #1)
112** SSTV2_TF2_CLKDEL hex Trex-to-Fbi clock delay value (TMU #2)
113** SSTV2_TF_FIFO_THRESH hex Set TREX-to-FBI FIFO threshold
114** SSTV2_TILESINX hex Specify value of tilesInX video register
115** SSTV2_TMUCFG hex Specify TMU configuration strapping bits
116** SSTV2_TMUMEM X Enable accurate determination of TMU mem
117** SSTV2_TMU_MEMSIZE val Specify amount of texture memory
118** SSTV2_TREX0INIT0 hex Set trexInit0 register value - TMU #0
119** SSTV2_TREX0INIT1 hex Set trexInit1 register value - TMU #0
120** SSTV2_TREX1INIT0 hex Set trexInit0 register value - TMU #1
121** SSTV2_TREX1INIT1 hex Set trexInit1 register value - TMU #1
122** SSTV2_TREX2INIT0 hex Set trexInit0 register value - TMU #2
123** SSTV2_TREX2INIT1 hex Set trexInit1 register value - TMU #2
124** SSTV2_VIN_CLKDEL hex Specify FBI internal video clock delay
125** SSTV2_VOUT_CLKDEL hex Specify FBI external video clock delay
126** SSTV2_VGA_PASS {0,1} Force VGA_PASS output to {0,1}
127** SSTV2_VIDCLK2X val Video clock frequency (2x dot clock)
128** SSTV2_VIDEO_24BPP 0 Select 16-bit video output
129** SSTV2_VIDEO_24BPP 1 Select 24-bit video output
130** SSTV2_VIDEO_DISABLE X Turn off Video/Monitor refresh in FBI
131** SSTV2_VIDEO_FILTER_DISABLE X Disable video filtering
132** SSTV2_VIDEO_FILTER_THRESHOLD hex Set video filtering threshold
133** SSTV2_VIDEO_NOCLEAR X Do not clear buffers in sst1InitVideo()
134** SSTV2_VIDEO_CLEARCOLOR hex Clear screen color
135** SSTV2_VFIFO_THRESH {0-31} Select video fifo threshold
136** SSTV2_VSYNC hex Specify value of vSync video register
137**
138** VOODOO2_FILE name Filename used in place of "voodoo2.ini"
139** VOODOO2_PATH path Path used to locate "voodoo2.ini" file
140**
141*/
142
143#pragma optimize ("",off)
144#include <stdio.h>
145#include <stdlib.h>
146#include <math.h>
147#ifdef BUILD_FOR_SST1
148#include <sst.h>
149#else
150#include <3dfx.h>
151#include <cvgregs.h>
152#include <cvgdefs.h>
153#endif
154#include <fxpci.h>
155#define SST1INIT_ALLOCATE // Allocate variables in sst1init.h
156#define FX_DLL_DEFINITION
157#include <fxdll.h>
158#include <sst1vid.h>
159#include <sst1init.h>
160#include "rcver.h"
161
162#ifdef __WIN32__
163#include <windows.h>
164#endif
165
166// Allow SourceSafe to track Revision
167static char codeIdent[] = "@#%" VERSIONSTR ;
168
169/*
170** sst1InitMapBoard():
171** Find and map SST-1 board into virtual memory
172**
173** Returns:
174** FxU32 pointer to base of SST-1 board if successful mapping occurs
175** FXFALSE if cannot map or find SST-1 board
176**
177*/
178FX_EXPORT FxU32 * FX_CSTYLE sst1InitMapBoard(FxU32 BoardNumber)
179{
180 return(sst1InitMapBoardDirect(BoardNumber, FXTRUE));
181}
182
183// Use this flag to force a info clear when doing a
184// sst1InitMapBoard() for the first time. sst1InitShutdown()
185// will also set this flag to TRUE to force a clear
186// next time around.
187static FxU32 clearBoardInfo = FXTRUE;
188
189FX_EXPORT FxU32 * FX_CSTYLE sst1InitMapBoardDirect(FxU32 BoardNumber,
190 FxBool resetSLI)
191{
192 static FxU32 firstTime = 1;
193 FxU32 vendorID = _3DFX_PCI_ID; // 3Dfx Vendor ID
194 FxU32 deviceID; // 0x0002 - Look for a Voodoo2 board (0xFFFF - Find any 3Dfx board)
195 FxU32 sizeOfCard = 0x1000000; // 16 MBytes of addr space for SST-1
196 FxU32 *sstbase;
197 FxU32 n;
198 FxU32 j;
199
200 if( GETENV( ("SSTV2_DEVICEID") ) )
201 SSCANF(GETENV(("SSTV2_DEVICEID")), "%i", &deviceID);
202 else
203 deviceID = 0x0002;
204
205 // Open PCI library (necessary for multiple calls to init routines, after
206 // PCI library is closed by pciClose() call in sst1InitShutdown().
207 //
208 // NB: It is safe to do this even if we never called pciClose.
209 pciOpen();
210
211 if(firstTime) {
212 // Make Watcom happy
213 codeIdent[0] = '@';
214 headersIdent[0] = '@';
215
216 // Find "voodoo2.ini" file if it exists...
217 sst1InitUseVoodooFile = sst1InitVoodooFile();
218
219 if(!(boardsInSystem = sst1InitNumBoardsInSystem()))
220 return(NULL);
221 }
222
223 if( clearBoardInfo ) {
224 INIT_PRINTF(("sst1Init Routines"));
225#ifdef FX_DLL_ENABLE
226 INIT_PRINTF(("(DLL)"));
227#endif
228 INIT_PRINTF((": %s\n", VERSIONSTR));
229 INIT_PRINTF(("sst1InitMapBoard(): BoardsInSystem = %d\n",
230 boardsInSystem));
231
232 // Clear board info structure
233 sst1InitClearBoardInfo();
234
235 clearBoardInfo = FXFALSE;
236
237#if !DIRECTX
238 /* dpc - 26 feb 1998
239 * If glide is running on windows the a pciClose will close
240 * the vxd etc. This is not functionally longer fatal, but w/o
241 * it we will not be able to do things like set the caching on
242 * the board's memory etc. This is bad.
243 *
244 * The actual cost of doing the re-mapping again is pretty low
245 * because both the pci library and the init code are caching the
246 * addresses of the board. However, the call to the pciLibrary
247 * to map the board has the side affect of causing the vxd to be
248 * loaded. It is this that is responsible for setting up caching.
249 */
250 firstTime = FXTRUE;
251#endif /* !DIRECTX */
252 }
253
254 if(firstTime) {
255 int boardLoopStart = 0;
256 int boardLoopStop = SST1INIT_MAX_BOARDS;
257 int boardLoopInc = 1;
258 int index = 0;
259
260 sst1InitClearBoardInfo();
261 if(GETENV(("SSTV2_SWAPBOARDS"))) {
262 boardLoopStart = SST1INIT_MAX_BOARDS-1;
263 boardLoopStop = -1;
264 boardLoopInc = -1;
265 }
266
267 for(j=0; j<SST1INIT_MAX_BOARDS; j++) {
268 sst1BoardInfo[j].virtAddr[0] = (SstRegs *) NULL;
269 sst1BoardInfo[j].physAddr[0] = (FxU32) NULL;
270 sst1BoardInfo[j].deviceNumber = 0xdead;
271 sst1BoardInfo[j].fbiRevision = 0xdead;
272 sst1BoardInfo[j].deviceID = 0xdead;
273 sst1BoardInfo[j].vendorID = 0xdead;
274 }
275
276
277 // Map all boards in the system
278 // Check that scanline interleaving is not enabled...
279 for(j = boardLoopStart; j != (FxU32)boardLoopStop; j += boardLoopInc) {
280 sstbase = pciMapCardMulti(vendorID, deviceID, sizeOfCard,
281 &sst1InitDeviceNumber, j, 0);
282 if(sstbase) {
283 sst1BoardInfo[index].virtAddr[0] = (SstRegs *) sstbase;
284 PCICFG_RD(PCI_BASE_ADDRESS_0, sst1BoardInfo[index].physAddr[0]);
285 sst1BoardInfo[index].deviceNumber = sst1InitDeviceNumber;
286 {
287 FxU32 oldFbiRevision, newFbiRevision;
288
289 PCICFG_RD(PCI_REVISION_ID, oldFbiRevision);
290 PCICFG_RD(SST1_PCI_INIT_ENABLE, newFbiRevision);
291 sst1BoardInfo[index].fbiFab =
292 (newFbiRevision & SST_CHUCK_MFTG_ID) >>
293 SST_CHUCK_MFTG_ID_SHIFT;
294 newFbiRevision = (newFbiRevision & SST_CHUCK_REVISION_ID) >>
295 SST_CHUCK_REVISION_ID_SHIFT;
296 if(oldFbiRevision != 0x2 && newFbiRevision < 4)
297 return(NULL);
298 sst1BoardInfo[index].fbiRevision = newFbiRevision;
299 }
300 PCICFG_RD(PCI_DEVICE_ID, sst1BoardInfo[index].deviceID);
301 PCICFG_RD(PCI_VENDOR_ID, sst1BoardInfo[index].vendorID);
302
303 // Enable Memory accesses to SST-1
304 // Must be set for PnP BIOS which do not enable memory mapped
305 // accesses (sst1InitSliDetect reads memory mapped regs)
306 PCICFG_WR(PCI_COMMAND, SST_PCIMEM_ACCESS_EN);
307 index++;
308 } else {
309 FxU32 code = pciGetErrorCode();
310 if (code != PCI_ERR_NOERR) {
311#ifdef __WIN32__
312 MessageBox(NULL, pciGetErrorString(), NULL, MB_OK);
313#endif // __WIN32__
314
315 INIT_PRINTF(("pciError(): %s", pciGetErrorString()));
316 exit(-1);
317 }
318 }
319 }
320 }
321
322 if(resetSLI) {
323 // Search through all known boards for SLI enabled...
324 FxU32 k;
325 SstRegs *sst;
326
327 for(k=0; k<boardsInSystemReally; k++) {
328 // Disable SLI if detected...
329 if(!(sstbase = (FxU32 *) sst1BoardInfo[k].virtAddr[0]))
330 return(NULL);
331 sst1InitDeviceNumber = sst1BoardInfo[k].deviceNumber;
332 sst1CurrentBoard = &sst1BoardInfo[k];
333 sst = (SstRegs *) sstbase;
334
335 if(IGET(sst->fbiInit1) & SST_EN_SCANLINE_INTERLEAVE) {
336 INIT_PRINTF(("sst1InitMapBoard(): Disabling Scanline Interleaving (board #%d)...\n", (k+1)));
337 // Disable SLI Snooping...
338 PCICFG_RD(SST1_PCI_INIT_ENABLE, j);
339 PCICFG_WR(SST1_PCI_INIT_ENABLE, j &
340 ~(SST_SCANLINE_SLV_OWNPCI | SST_SCANLINE_SLI_SLV |
341 SST_SLI_SNOOP_EN | SST_SLI_SNOOP_MEMBASE));
342 ISET(sst->fbiInit1, IGET(sst->fbiInit1) &
343 ~SST_EN_SCANLINE_INTERLEAVE);
344 sst1InitReturnStatus(sstbase);
345 }
346
347 // Tristate video output signals, so two boards connected as SLI
348 // do not have contention problems when SSTV2_SLIDETECT=0
349 if(firstTime)
350 sst1InitVideoShutdown(sstbase, FXFALSE);
351 }
352 }
353 firstTime = 0;
354
355 // Max number of supported boards in system
356 if(BoardNumber > SST1INIT_MAX_BOARDS) return(NULL);
357
358 if(!(sstbase = (FxU32 *) sst1BoardInfo[BoardNumber].virtAddr[0]))
359 return (NULL);
360
361 INIT_PRINTF(("sst1InitMapBoard(): vAddr:0x%x pAddr:0x%x Dev:0x%x Board:%d\n",
362 (FxU32) sst1BoardInfo[BoardNumber].virtAddr[0],
363 (FxU32) sst1BoardInfo[BoardNumber].physAddr[0],
364 (FxU32) sst1BoardInfo[BoardNumber].deviceNumber, BoardNumber));
365
366 // Default settings
367 sst1BoardInfo[BoardNumber].vgaPassthruDisable = SST_EN_VGA_PASSTHRU;
368 sst1BoardInfo[BoardNumber].vgaPassthruEnable = 0x0;
369 sst1BoardInfo[BoardNumber].fbiVideo16BPP = 0;
370
371 if(GETENV(("SSTV2_VGA_PASS"))) {
372 INIT_PRINTF(("sst1InitMapBoard(): Using SST_VGA_PASS=%d\n",
373 ATOI(GETENV(("SSTV2_VGA_PASS")))));
374 if(ATOI(GETENV(("SSTV2_VGA_PASS")))) {
375 sst1BoardInfo[BoardNumber].vgaPassthruEnable = SST_EN_VGA_PASSTHRU;
376 sst1BoardInfo[BoardNumber].vgaPassthruDisable = 0x0;
377 } else {
378 sst1BoardInfo[BoardNumber].vgaPassthruDisable = SST_EN_VGA_PASSTHRU;
379 sst1BoardInfo[BoardNumber].vgaPassthruEnable = 0x0;
380 }
381 }
382
383 return(sstbase);
384}
385
386/*
387** sst1InitRegisters():
388** Initialize registers and memory and return to power-on state
389**
390** Returns:
391** FXTRUE if successfully initializes SST-1
392** FXFALSE if cannot initialize SST-1
393**
394*/
395FX_EXPORT FxBool FX_CSTYLE sst1InitRegisters(FxU32 *sstbase)
396{
397 FxU32 n, tf_fifo_thresh;
398 FxU32 ft_clkdel, tf0_clkdel, tf1_clkdel, tf2_clkdel;
399 sst1ClkTimingStruct sstGrxClk;
400 SstRegs *sst = (SstRegs *) sstbase;
401
402 if(!sst)
403 return(FXFALSE);
404
405 if(sst1InitCheckBoard(sstbase) == FXFALSE)
406 return(FXFALSE);
407
408 if(GETENV(("SSTV2_IGNORE_INIT_REGISTERS"))) {
409 INIT_PRINTF(("WARNING: Ignoring sst1InitRegisters()...\n"));
410 sst1InitIdleFBINoNOP(sstbase);
411 return(FXTRUE);
412 }
413
414 if(GETENV(("SSTV2_TEXMAP_DISABLE")))
415 INIT_PRINTF(("sst1InitRegisters() WARNING: Disabling texture mapping\n"));
416 // Open PCI library (necessary for multiple calls to init routines, after
417 // PCI library is closed by pciClose() call in sst1InitShutdown()
418 pciOpen();
419
420 // Enable writes to the FBIINIT registers
421 // Do not allow writes into the pci fifo until everything is reset
422 PCICFG_WR(SST1_PCI_INIT_ENABLE, SST_INITWR_EN);
423
424 // Reset Snoop registers to default values
425 PCICFG_WR(SST1_PCI_BUS_SNOOP0, SST_PCI_BUS_SNOOP_DEFAULT);
426 PCICFG_WR(SST1_PCI_BUS_SNOOP1, SST_PCI_BUS_SNOOP_DEFAULT);
427 sst1InitReturnStatus(sstbase); // Stall - can't call IdleFbi because
428 sst1InitReturnStatus(sstbase); // FBI could be hung at this stage
429 sst1InitReturnStatus(sstbase);
430
431 // Adjust Trex-to-Fbi FIFO
432 if(GETENV(("SSTV2_TF_FIFO_THRESH")))
433 SSCANF(GETENV(("SSTV2_TF_FIFO_THRESH")), "%i", &tf_fifo_thresh);
434 else
435 tf_fifo_thresh = 0x8;
436 INIT_PRINTF(("sst1InitRegisters(): Setting TREX-to-FBI FIFO THRESHOLD to 0x%x...\n",
437 tf_fifo_thresh));
438
439 // Set ft_clkdel for 16 MHz bringup
440 ft_clkdel = 0x8; // Okay for 16 MHz startup...
441 if(GETENV(("SSTV2_PFT_CLKDEL")))
442 SSCANF(GETENV(("SSTV2_PFT_CLKDEL")), "%i", &ft_clkdel);
443 INIT_PRINTF(("sst1InitRegisters(): Setting PRELIM FT-CLK delay to 0x%x...\n", ft_clkdel));
444
445 // SST_FBIINIT3_DEFAULT is set to disable texture mapping, so if
446 // TMUs are hung, it will not affect FBI
447 ISET(sst->fbiInit3,
448 (SST_FBIINIT3_DEFAULT & ~(SST_FT_CLK_DEL_ADJ | SST_TF_FIFO_THRESH)) |
449 (ft_clkdel << SST_FT_CLK_DEL_ADJ_SHIFT) |
450 (tf_fifo_thresh << SST_TF_FIFO_THRESH_SHIFT));
451
452 // Wait for Fbi-to-Trex clock delay value to propogate
453 sst1InitReturnStatus(sstbase); // Stall - can't call IdleFbi because
454 sst1InitReturnStatus(sstbase); // FBI could be hung at this stage
455 sst1InitReturnStatus(sstbase);
456
457 // Reset graphics and video units
458 // Must reset video unit before graphics unit, otherwise video unit could
459 // potentially hang waiting for the graphics unit to respond
460 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
461
462 // Don't wait for idle because graphics could be hung...
463 sst1InitReturnStatus(sstbase);
464 sst1InitReturnStatus(sstbase);
465 sst1InitReturnStatus(sstbase);
466 ISET(sst->fbiInit0,
467 IGET(sst->fbiInit0) | (SST_GRX_RESET | SST_PCI_FIFO_RESET));
468
469 sst1InitIdleFBINoNOP(sstbase);
470
471 // Unreset PCI FIFO...
472 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_PCI_FIFO_RESET);
473 sst1InitIdleFBINoNOP(sstbase);
474
475 // Unreset graphics subsystem
476 // THIS MUST BE PRESENT OTHERWISE THE PCI FIFO WILL NEVER DRAIN!
477 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_GRX_RESET);
478 sst1InitIdleFBINoNOP(sstbase);
479
480 // Reset all FBI and TREX Init registers
481 ISET(sst->fbiInit0, SST_FBIINIT0_DEFAULT);
482 ISET(sst->fbiInit1, SST_FBIINIT1_DEFAULT);
483 ISET(sst->fbiInit2, SST_FBIINIT2_DEFAULT);
484 ISET(sst->fbiInit3,
485 (SST_FBIINIT3_DEFAULT & ~(SST_FT_CLK_DEL_ADJ | SST_TF_FIFO_THRESH)) |
486 (ft_clkdel << SST_FT_CLK_DEL_ADJ_SHIFT) |
487 (tf_fifo_thresh << SST_TF_FIFO_THRESH_SHIFT));
488 ISET(sst->fbiInit4, SST_FBIINIT4_DEFAULT);
489 ISET(sst->fbiInit5, SST_FBIINIT5_DEFAULT);
490 ISET(sst->fbiInit6, SST_FBIINIT6_DEFAULT);
491 sst1CurrentBoard->fbiInit6 = SST_FBIINIT6_DEFAULT;
492 ISET(sst->fbiInit7, SST_FBIINIT7_DEFAULT);
493 sst1InitIdleFBINoNOP(sstbase); // Wait until init regs are reset
494
495 // Enable writes to the FBIINIT registers and allow pushes onto PCI FIFO
496 PCICFG_WR(SST1_PCI_INIT_ENABLE, (SST_INITWR_EN | SST_PCI_FIFOWR_EN));
497
498 // Determine DAC Type
499 if(sst1InitDacDetect(sstbase) == FXFALSE) {
500 INIT_PRINTF(("sst1InitRegisters(): Could not detect DAC...\n"));
501 return(FXFALSE);
502 }
503
504 // set TREX0 init values
505 if(GETENV(("SSTV2_TREX0INIT0"))) {
506 INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX0INIT0 environment variable\n"));
507 SSCANF(GETENV(("SSTV2_TREX0INIT0")), "%i",
508 &sst1CurrentBoard->tmuInit0[0]);
509 } else
510 sst1CurrentBoard->tmuInit0[0] = SST_TREX0INIT0_DEFAULT;
511
512 INIT_PRINTF(("sst1InitRegisters(): Storing TREX0INIT0=0x%x\n",
513 sst1CurrentBoard->tmuInit0[0]));
514 if(GETENV(("SSTV2_TREX0INIT1"))) {
515
516 INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX0INIT1 environment variable\n"));
517 SSCANF(GETENV(("SSTV2_TREX0INIT1")), "%i",
518 &sst1CurrentBoard->tmuInit1[0]);
519 } else
520 sst1CurrentBoard->tmuInit1[0] = SST_TREX0INIT1_DEFAULT;
521 if(GETENV(("SSTV2_PTF0_CLKDEL"))) {
522 SSCANF(GETENV(("SSTV2_PTF0_CLKDEL")), "%i", &tf0_clkdel);
523 sst1CurrentBoard->tmuInit1[0] = (sst1CurrentBoard->tmuInit1[0] &
524 ~SST_TEX_TF_CLK_DEL_ADJ) |
525 (tf0_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
526 }
527 INIT_PRINTF(("sst1InitRegisters(): Storing TREX0INIT1=0x%x\n",
528 sst1CurrentBoard->tmuInit1[0]));
529
530 // set TREX1 init values
531 if(GETENV(("SSTV2_TREX1INIT0"))) {
532 INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX1INIT0 environment variable\n"));
533 SSCANF(GETENV(("SSTV2_TREX1INIT0")), "%i",
534 &sst1CurrentBoard->tmuInit0[1]);
535 } else
536 sst1CurrentBoard->tmuInit0[1] = SST_TREX1INIT0_DEFAULT;
537 INIT_PRINTF(("sst1InitRegisters(): Storing TREX1INIT0=0x%x\n",
538 sst1CurrentBoard->tmuInit0[1]));
539 if(GETENV(("SSTV2_TREX1INIT1"))) {
540 INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX1INIT1 environment variable\n"));
541 SSCANF(GETENV(("SSTV2_TREX1INIT1")), "%i",
542 &sst1CurrentBoard->tmuInit1[1]);
543 } else
544 sst1CurrentBoard->tmuInit1[1] = SST_TREX1INIT1_DEFAULT;
545 if(GETENV(("SSTV2_PTF1_CLKDEL"))) {
546 SSCANF(GETENV(("SSTV2_PTF1_CLKDEL")), "%i", &tf1_clkdel);
547 sst1CurrentBoard->tmuInit1[1] = (sst1CurrentBoard->tmuInit1[1] &
548 ~SST_TEX_TF_CLK_DEL_ADJ) |
549 (tf1_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
550 }
551 INIT_PRINTF(("sst1InitRegisters(): Storing TREX1INIT1=0x%x\n",
552 sst1CurrentBoard->tmuInit1[1]));
553
554
555 // set TREX2 init values
556 if(GETENV(("SSTV2_TREX2INIT0"))) {
557 INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX2INIT0 environment variable\n"));
558 SSCANF(GETENV(("SSTV2_TREX2INIT0")), "%i",
559 &sst1CurrentBoard->tmuInit0[2]);
560 } else
561 sst1CurrentBoard->tmuInit0[2] = SST_TREX2INIT0_DEFAULT;
562 INIT_PRINTF(("sst1InitRegisters(): Storing TREX2INIT0=0x%x\n",
563 sst1CurrentBoard->tmuInit0[2]));
564 if(GETENV(("SSTV2_TREX2INIT1"))) {
565 INIT_PRINTF(("sst1InitRegisters(): Using SST_TREX2INIT1 environment variable\n"));
566 SSCANF(GETENV(("SSTV2_TREX2INIT1")), "%i",
567 &sst1CurrentBoard->tmuInit1[2]);
568 } else
569 sst1CurrentBoard->tmuInit1[2] = SST_TREX2INIT1_DEFAULT;
570 if(GETENV(("SSTV2_PTF2_CLKDEL"))) {
571 SSCANF(GETENV(("SSTV2_PTF2_CLKDEL")), "%i", &tf2_clkdel);
572 sst1CurrentBoard->tmuInit1[2] = (sst1CurrentBoard->tmuInit1[2] &
573 ~SST_TEX_TF_CLK_DEL_ADJ) |
574 (tf2_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
575 }
576 INIT_PRINTF(("sst1InitRegisters(): Storing TREX2INIT1=0x%x\n",
577 sst1CurrentBoard->tmuInit1[2]));
578
579 // Set clock at 16 MHz to properly transmit TREX configuration registers
580 // Note that setting the clock will automatically reset the TMUs...
581 // sst1InitResetTmus() also will de-assert TEXMAP_DISABLE in fbiInit3
582 // unless SSTV2_TEXMAP_DISABLE is set
583 if(sst1InitComputeClkParams((float) 16.0, &sstGrxClk) == FXFALSE)
584 return(FXFALSE);
585 if(sst1InitSetGrxClk(sstbase, &sstGrxClk) == FXFALSE)
586 return(FXFALSE);
587 sst1CurrentBoard->initGrxClkDone = 0;
588
589 // Set PCI wait-states
590 if(GETENV(("SSTV2_SLOWPCIWR"))) {
591 INIT_PRINTF(("sst1InitRegisters(): Setting up SLOW PCI Writes...\n"));
592 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_PCI_WRWS_1);
593 } else
594 ISET(sst->fbiInit1, IGET(sst->fbiInit1) & ~SST_PCI_WRWS_1);
595
596 if(GETENV(("SSTV2_FASTPCIRD"))) {
597 INIT_PRINTF(("sst1InitRegisters(): Setting up FAST PCI Reads...\n"));
598 ISET(sst->fbiInit4, IGET(sst->fbiInit4) & ~SST_PCI_RDWS_2);
599 }
600 sst1InitIdleFBINoNOP(sstbase);
601
602 // Enable Linear frame buffer reads
603 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_LFB_READ_EN);
604
605 // Swapbuffer algorithm is based on VSync initially
606 ISET(sst->fbiInit2, (IGET(sst->fbiInit2) & ~SST_SWAP_ALGORITHM) |
607 SST_SWAP_VSYNC);
608
609 // Enable LFB read-aheads
610 ISET(sst->fbiInit4, IGET(sst->fbiInit4) | SST_EN_LFB_RDAHEAD);
611
612 // Enable triangle alternate register mapping
613 ISET(sst->fbiInit3, IGET(sst->fbiInit3) | SST_ALT_REGMAPPING);
614
615 // Enable Endian Byte Swapping
616 ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_EN_ENDIAN_SWAPPING);
617
618 // Setup DRAM Refresh
619 ISET(sst->fbiInit2, (IGET(sst->fbiInit2) & ~SST_DRAM_REFRESH_CNTR) |
620 SST_DRAM_REFRESH_16MS);
621 sst1InitIdleFBINoNOP(sstbase);
622 ISET(sst->fbiInit2, IGET(sst->fbiInit2) | SST_EN_DRAM_REFRESH);
623 sst1InitIdleFBINoNOP(sstbase);
624
625 {
626 // Setup memory timings...
627 FxU32 fbiInit1 = IGET(sst->fbiInit1);
628 FxU32 fbiInit2 = IGET(sst->fbiInit2) |
629 SST_EN_DRAM_RD_AHEAD_FIFO | SST_EN_FAST_RD_AHEAD_WR;
630
631 if(GETENV(("SSTV2_SLOWMEM_WTR"))) {
632 INIT_PRINTF(("sst1InitRegisters(): Running slow write-to-read memory timing...\n"));
633 fbiInit1 |= SST_DISEN_RD_AHEAD_WR_RD;
634 }
635 if(GETENV(("SSTV2_SLOWMEM_RTW"))) {
636 INIT_PRINTF(("sst1InitRegisters(): Running slow read-to-write memory timing...\n"));
637 fbiInit2 &= ~SST_EN_FAST_RD_AHEAD_WR;
638 }
639 if(GETENV(("SSTV2_FASTMEM_RAS_READS"))) {
640 INIT_PRINTF(("sst1InitRegisters(): Enabling fast RAS read memory timing...\n"));
641 fbiInit2 |= SST_EN_FAST_RAS_READ;
642 }
643 ISET(sst->fbiInit1, fbiInit1);
644 sst1InitReturnStatus(sstbase);
645 ISET(sst->fbiInit2, fbiInit2);
646 sst1InitReturnStatus(sstbase);
647 }
648
649 // Return all other registers to their power-on state
650 sst1InitIdleFBINoNOP(sstbase);
651 sst1InitSetResolution(sstbase, &SST_VREZ_640X480_60, 0);
652 sst1InitIdleFBINoNOP(sstbase);
653
654 // Get DRAMs up and running (refresh is already enabled)...
655 ISET(sst->c1, 0x0);
656 ISET(sst->c0, 0x0);
657 ISET(sst->zaColor, 0x0);
658 ISET(sst->clipLeftRight, 100); // draw into 50x50 area
659 ISET(sst->clipBottomTop, 100);
660 ISET(sst->fbzMode, SST_RGBWRMASK | SST_ZAWRMASK);
661 ISET(sst->fastfillCMD, 0x0); // Frontbuffer & Z/A
662 ISET(sst->nopCMD, 0x1); // Clear fbistat registers after clearing screen
663 sst1InitIdleFBINoNOP(sstbase);
664
665 sst1InitRenderingRegisters(sstbase);
666 sst1CurrentBoard->tmuRevision = 0xdead; // Force sst1InitFillDeviceInfo()
667 if(sst1InitFillDeviceInfo(sstbase, sst1CurrentBoard) == FXFALSE) {
668 INIT_PRINTF(("sst1InitRegisters(): ERROR filling DeviceInfo...\n"));
669
670 return(FXFALSE);
671 }
672
673 sst1InitIdleFBINoNOP(sstbase);
674 sst1InitRenderingRegisters(sstbase);
675 sst1InitIdleFBINoNOP(sstbase);
676
677 // LFB writes stored in memory FIFO?
678 if(GETENV(("SSTV2_MEMFIFO_LFB")))
679 n = ATOI(GETENV(("SSTV2_MEMFIFO_LFB")));
680 else
681 n = 1;
682 if(n) {
683 INIT_PRINTF(("sst1InitRegisters(): LFB Writes go through memory FIFO...\n"));
684 ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_EN_LFB_MEMFIFO);
685 sst1InitIdleFBINoNOP(sstbase);
686 }
687
688 // Texture memory writes stored in memory FIFO?
689 if(GETENV(("SSTV2_MEMFIFO_TEX")))
690 n = ATOI(GETENV(("SSTV2_MEMFIFO_TEX")));
691 else
692 n = 1;
693 if(n) {
694 INIT_PRINTF(("sst1InitRegisters(): TEXTURE Writes go through memory FIFO...\n"));
695 ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_EN_TEX_MEMFIFO);
696 sst1InitIdleFBINoNOP(sstbase);
697 }
698
699 ISET(sst->vRetrace, 0x0);
700 ISET(sst->backPorch, 0x0);
701 ISET(sst->videoDimensions, 0x0);
702 ISET(sst->hSync, 0x0);
703 ISET(sst->vSync, 0x0);
704 ISET(sst->videoFilterRgbThreshold, 0x0);
705
706 sst1InitIdleFBINoNOP(sstbase); // Wait until init regs are reset
707
708 // Update info structure for initEnable
709 PCICFG_RD(SST1_PCI_INIT_ENABLE, sst1CurrentBoard->fbiInitEnable);
710
711 INIT_PRINTF(("sst1InitRegisters(): exiting with status %d...\n", FXTRUE));
712 return(FXTRUE);
713}
714
715FX_EXPORT void FX_CSTYLE sst1InitRenderingRegisters(FxU32 *sstbase)
716{
717 FxU32 i;
718 SstRegs *sst = (SstRegs *) sstbase;
719
720 ISET(sst->vA.x, 0x0); ISET(sst->vA.y, 0x0);
721 ISET(sst->vB.x, 0x0); ISET(sst->vB.y, 0x0);
722 ISET(sst->vC.x, 0x0); ISET(sst->vC.y, 0x0);
723
724 ISET(sst->r, 0x0); ISET(sst->g, 0x0);
725 ISET(sst->b, 0x0); ISET(sst->z, 0x0);
726 ISET(sst->a, 0x0); ISET(sst->s, 0x0);
727 ISET(sst->t, 0x0); ISET(sst->w, 0x0);
728
729 ISET(sst->drdx, 0x0); ISET(sst->dgdx, 0x0);
730 ISET(sst->dbdx, 0x0); ISET(sst->dzdx, 0x0);
731 ISET(sst->dadx, 0x0); ISET(sst->dsdx, 0x0);
732 ISET(sst->dtdx, 0x0); ISET(sst->dwdx, 0x0);
733
734 ISET(sst->drdy, 0x0); ISET(sst->dgdy, 0x0);
735 ISET(sst->dbdy, 0x0); ISET(sst->dzdy, 0x0);
736 ISET(sst->dady, 0x0); ISET(sst->dsdy, 0x0);
737 ISET(sst->dtdy, 0x0); ISET(sst->dwdy, 0x0);
738
739 ISET(sst->fbzColorPath, 0x0);
740 ISET(sst->fogMode, 0x0);
741 ISET(sst->alphaMode, 0x0);
742 ISET(sst->fbzMode, 0x0);
743 ISET(sst->lfbMode, 0x0);
744 ISET(sst->clipLeftRight, 0x0);
745 ISET(sst->clipBottomTop, 0x0);
746
747 ISET(sst->fogColor, 0x0);
748 ISET(sst->zaColor, 0x0);
749 ISET(sst->chromaKey, 0x0);
750 ISET(sst->chromaRange, 0x0);
751 ISET(sst->stipple, 0x0);
752 ISET(sst->c0, 0x0);
753 ISET(sst->c1, 0x0);
754
755 ISET(sst->sSetupMode, 0x0);
756 ISET(sst->sVx, 0x0);
757 ISET(sst->sVy, 0x0);
758 ISET(sst->sARGB, 0x0);
759 ISET(sst->sRed, 0x0);
760 ISET(sst->sGreen, 0x0);
761 ISET(sst->sBlue, 0x0);
762 ISET(sst->sAlpha, 0x0);
763 ISET(sst->sVz, 0x0);
764 ISET(sst->sOowfbi, 0x0);
765 ISET(sst->sOow0, 0x0);
766 ISET(sst->sSow0, 0x0);
767 ISET(sst->sTow0, 0x0);
768 ISET(sst->sOow1, 0x0);
769 ISET(sst->sSow1, 0x0);
770 ISET(sst->sTow1, 0x0);
771
772 ISET(sst->nopCMD, 0x3); // Clear fbistat and trianglesOut registers
773
774 for(i=0; i<32; i++)
775 ISET(sst->fogTable[i], 0x0);
776
777 ISET(sst->bltSrcBaseAddr, 0x0);
778 ISET(sst->bltDstBaseAddr, 0x0);
779 ISET(sst->bltXYstrides, 0x0);
780 ISET(sst->bltSrcChromaRange, 0x0);
781 ISET(sst->bltDstChromaRange, 0x0);
782 ISET(sst->bltClipX, 0x0);
783 ISET(sst->bltClipY, 0x0);
784 ISET(sst->bltSrcXY, 0x0);
785 ISET(sst->bltDstXY, 0x0);
786 ISET(sst->bltSize, 0x0);
787 ISET(sst->bltRop, 0x0);
788 ISET(sst->bltColor, 0x0);
789 ISET(sst->bltCommand, 0x0);
790
791 // clear TMU registers
792 ISET(sst->textureMode, 0x0);
793 ISET(sst->tLOD, 0x0);
794 ISET(sst->tDetail, 0x0);
795 ISET(sst->texBaseAddr, 0x0);
796 ISET(sst->texBaseAddr1, 0x0);
797 ISET(sst->texBaseAddr2, 0x0);
798 ISET(sst->texBaseAddr38, 0x0);
799
800 for(i=0; i<12; i++)
801 ISET(sst->nccTable0[i], 0x0);
802 for(i=0; i<12; i++)
803 ISET(sst->nccTable1[i], 0x0);
804 sst1InitIdle(sstbase);
805
806 ISET(sst->tchromaKey, 0x0);
807 ISET(sst->tchromaRange, 0x0);
808
809}
810
811/*
812** sst1InitShutdown():
813** Shutdown SST-1
814** Resets state of VGA_PASS to return monitor control back to the VGA
815** Powers-down the DAC
816** Resets the graphics clock in FBI to conserve power
817**
818** Returns:
819** FXTRUE if successfully shuts down SST-1
820** FXFALSE if cannot shut down the SST-1
821**
822*/
823FX_EXPORT FxBool FX_CSTYLE sst1InitShutdown(FxU32 *sstbase)
824{
825 SstRegs *sstMaster = (SstRegs *) sstbase;
826 SstRegs *sstSlave;
827 SstRegs *sstPtr;
828 FxU32 n;
829 FxU32 sliEnabled;
830 sst1ClkTimingStruct sstGrxClk;
831
832 if(!sstbase)
833 return(FXFALSE);
834
835 if(sst1InitCheckBoard((FxU32 *) sstbase) == FXFALSE)
836 return(FXFALSE);
837
838 // sst1Initidle() routines must be properly executed...
839 initIdleEnabled = 1;
840
841 sliEnabled = (sst1CurrentBoard->sliSlaveVirtAddr != (FxU32 *) NULL) ? 1 : 0;
842 sstSlave = (SstRegs *) sst1CurrentBoard->sliSlaveVirtAddr;
843
844#if 0
845 // If the command fifo is enabled, we can't issue a NOP first, so wait
846 // until the PCI fifo is empty...
847 sst1InitPciFifoIdleLoop(sstbase);
848 if(sst1CurrentBoard->sliSlaveVirtAddr)
849 sst1InitPciFifoIdleLoop(sst1CurrentBoard->sliSlaveVirtAddr);
850#else
851 sst1InitIdle(sstbase);
852#endif
853
854 // Disable the command fifo if enabled...
855 if(sst1CurrentBoard->fbiCmdFifoEn ||
856 (sstMaster->fbiInit7 & SST_EN_CMDFIFO))
857 sst1InitCmdFifo(sstbase, FXFALSE, (void *) NULL, (void *) NULL,
858 (void *) NULL, NULL);
859
860 sst1InitIdle(sstbase);
861
862 if(sliEnabled && !GETENV(("SSTV2_NOSHUTDOWN"))) {
863 if(sst1InitShutdownSli(sstbase) == FXFALSE)
864 return(FXFALSE);
865 }
866
867 if(GETENV(("SSTV2_NOSHUTDOWN")))
868 INIT_PRINTF(("sst1InitShutdown(): Bypassing shutdown with SSTV2_NOSHUTDOWN\n"));
869
870 n = 0;
871 while(!GETENV(("SSTV2_NOSHUTDOWN"))) {
872 if(!n)
873 sstPtr = sstMaster;
874 else
875 sstPtr = sstSlave;
876
877 if(sst1InitCheckBoard((FxU32 *) sstPtr) == FXFALSE)
878 return(FXFALSE);
879
880 INIT_PRINTF(("sst1InitShutdown(): Shutting down SST-1 #%d...\n", n));
881
882 // Reset video unit to guarantee no contentions on the memory bus
883 // Blank DAC so VGA Passthru works properly
884 ISET(sstPtr->fbiInit1,
885 IGET(sstPtr->fbiInit1) | (SST_VIDEO_RESET | SST_VIDEO_BLANK_EN));
886 // Turn off dram refresh to guarantee no contentions on the
887 // memory bus
888 ISET(sstPtr->fbiInit2, IGET(sstPtr->fbiInit2) & ~SST_EN_DRAM_REFRESH);
889
890 // Reset graphics subsystem
891 ISET(sstPtr->fbiInit0,
892 IGET(sstPtr->fbiInit0) | (SST_GRX_RESET | SST_PCI_FIFO_RESET));
893 sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
894 ISET(sstPtr->fbiInit0, IGET(sstPtr->fbiInit0) & ~SST_PCI_FIFO_RESET);
895
896 sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
897 ISET(sstPtr->fbiInit0, IGET(sstPtr->fbiInit0) & ~SST_GRX_RESET);
898 sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
899
900 // Turnaround VGA_PASS to allow VGA monitor
901 sst1InitVgaPassCtrl((FxU32 *) sstPtr, 1);
902 sst1InitIdleFBINoNOP((FxU32 *) sstPtr);
903
904 // Set clock at 30 MHz to reduce power consumption...
905 sst1InitComputeClkParams((float) 30.0, &sstGrxClk);
906 if(sst1InitSetGrxClk((FxU32 *) sstPtr, &sstGrxClk) == FXFALSE)
907 INIT_PRINTF(("sst1InitShutdown() WARNING: sst1InitSetGrxClk failed...Continuing...\n"));
908 sst1CurrentBoard->initGrxClkDone = 0;
909
910#ifndef __linux__
911 pciUnmapPhysical((FxU32)sst1CurrentBoard->virtAddr[0],
912 0x1000000UL);
913#endif
914
915 if((++n > 1) || !sliEnabled)
916 break;
917 }
918
919 /* sst1InitIdle(sstbase); */
920
921#if !DIRECTX
922 //
923 // HACK alert.
924 //
925 // There's a pciClose(), but nobody calls it. This is needed by the
926 // DOS DPMI services to close fxmemmap.vxd.
927 //
928 // Note that the call to pciClose must be after the shutdown sequence,
929 // as the shutdown sequence uses PCI configuration reads/writes...
930 //
931 pciClose();
932#endif /* !DIRECTX */
933
934 INIT_PRINTF(("sst1InitShutdown(): Returning with status %d...\n", FXTRUE));
935#ifdef INIT_OUTPUT
936 if ( sst1InitMsgFile != stdout )
937 fclose(sst1InitMsgFile);
938#endif
939
940 // Make sure that the board info structures are
941 // cleared next time sst1InitMapBoard() is called.
942 clearBoardInfo = FXTRUE;
943
944 return(FXTRUE);
945}
946
947/*
948** sst1InitCheckBoard():
949** Set internal global variables for multiple SST-1 support
950**
951*/
952FX_EXPORT FxBool FX_CSTYLE sst1InitCheckBoard(FxU32 *sstbase)
953{
954 FxU32 n;
955 FxBool returnVal = FXFALSE;
956
957 for(n=0; n<boardsInSystem; n++) {
958 if((FxU32 *) sst1BoardInfo[n].virtAddr[0] == sstbase) {
959 sst1InitDeviceNumber = sst1BoardInfo[n].deviceNumber;
960 sst1CurrentBoard = &sst1BoardInfo[n];
961 returnVal = FXTRUE;
962 n = boardsInSystem;
963 }
964 }
965 return(returnVal);
966}
967
968/*
969** sst1InitGetBaseAddr():
970** Return virtual base address to hardware
971** Returns NULL if board requested has not been mapped
972**
973*/
974FX_EXPORT FxU32 * FX_CSTYLE sst1InitGetBaseAddr(FxU32 boardNum)
975{
976 SstRegs* sstBaseAddr = sst1BoardInfo[boardNum].virtAddr[0];
977 sst1DeviceInfoStruct devInfo;
978
979 if ((sstBaseAddr != NULL) &&
980 sst1InitGetDeviceInfo((FxU32*)sstBaseAddr, &devInfo) &&
981 devInfo.sliDetected &&
982 !devInfo.monitorDetected) {
983
984 SstRegs* tempAddr = NULL;
985
986 if (boardNum > 0) {
987 if (sst1BoardInfo[boardNum - 1].sliSlaveVirtAddr == (FxU32*)sstBaseAddr) {
988 tempAddr = sst1BoardInfo[boardNum - 1].virtAddr[0];
989 }
990 }
991
992 if ((tempAddr == NULL) && (boardNum < boardsInSystem)) {
993 if (sst1BoardInfo[boardNum + 1].sliSlaveVirtAddr == (FxU32*)sstBaseAddr) {
994 tempAddr = sst1BoardInfo[boardNum + 1].virtAddr[0];
995 }
996 }
997
998 if (tempAddr != NULL) sstBaseAddr = tempAddr;
999 }
1000
1001 return (FxU32*)sstBaseAddr;
1002}
1003
1004/*
1005** sst1InitClearBoardInfo():
1006** Clear board configuration information
1007**
1008*/
1009void sst1InitClearBoardInfo(void)
1010{
1011 FxU32 n, j;
1012
1013 for(n=0; n<SST1INIT_MAX_BOARDS; n++) {
1014 sst1BoardInfo[n].size = sizeof(sst1DeviceInfoStruct);
1015 //sst1BoardInfo[n].virtAddr[0] = (SstRegs *) NULL;
1016 //sst1BoardInfo[n].physAddr[0] = (FxU32) NULL;
1017 //sst1BoardInfo[n].deviceNumber = 0xdead;
1018 //sst1BoardInfo[n].vendorID = 0xdead;
1019 //sst1BoardInfo[n].deviceID = 0xdead;
1020
1021 //sst1BoardInfo[n].fbiRevision = 0xdead;
1022 //sst1BoardInfo[n].fbiFab = 0xdead;
1023 sst1BoardInfo[n].fbiBoardID = 0xdead;
1024 sst1BoardInfo[n].fbiVideo16BPP = 0xdead;
1025 sst1BoardInfo[n].fbiVideoWidth = 0xdead;
1026 sst1BoardInfo[n].fbiVideoHeight = 0xdead;
1027 sst1BoardInfo[n].fbiVideoRefresh = 0xdead;
1028 sst1BoardInfo[n].fbiVideoColBuffs = 0xdead;
1029 sst1BoardInfo[n].fbiVideoAuxBuffs = 0xdead;
1030 sst1BoardInfo[n].fbiVideoMemOffset = 0xdead;
1031 sst1BoardInfo[n].fbiVideoTilesInX = 0xdead;
1032 sst1BoardInfo[n].fbiVideoStruct = (sst1VideoTimingStruct *) NULL;
1033 sst1BoardInfo[n].fbiVideoDacType = 0xdead;
1034 sst1BoardInfo[n].fbiMemoryFifoEn = 0x0;
1035 sst1BoardInfo[n].fbiCmdFifoEn = 0x0;
1036 sst1BoardInfo[n].fbiLfbLocked = 0x0;
1037 sst1BoardInfo[n].fbiConfig = 0xdead;
1038 sst1BoardInfo[n].fbiGrxClkFreq = 0xdead;
1039 sst1BoardInfo[n].fbiMemSize = 0x0;
1040 sst1BoardInfo[n].fbiInitGammaDone = 0x0;
1041 sst1BoardInfo[n].fbiGammaRed = (double) 0.0;
1042 sst1BoardInfo[n].fbiGammaGreen = (double) 0.0;
1043 sst1BoardInfo[n].fbiGammaBlue = (double) 0.0;
1044
1045 sst1BoardInfo[n].tmuRevision = 0xdead;
1046 sst1BoardInfo[n].numberTmus = 0xdead;
1047 sst1BoardInfo[n].tmuConfig = 0xdead;
1048 sst1BoardInfo[n].tmuGrxClkFreq = 0xdead;
1049
1050 for(j=0; j<MAX_NUM_TMUS; j++) {
1051 sst1BoardInfo[n].tmuFab[j] = 0xdead;
1052 sst1BoardInfo[n].tmuMemSize[j] = 0x0;
1053 sst1BoardInfo[n].tmuInit0[j] = 0xdead;
1054 sst1BoardInfo[n].tmuInit1[j] = 0xdead;
1055 }
1056 sst1BoardInfo[n].fbiInit6 = 0;
1057 sst1BoardInfo[n].fbiInitEnable = 0;
1058
1059 sst1BoardInfo[n].sliDetected = 0;
1060 sst1BoardInfo[n].monitorDetected = 0;
1061 sst1BoardInfo[n].sliSlaveVirtAddr = (FxU32 *) NULL;
1062 sst1BoardInfo[n].initGrxClkDone = 0;
1063 sst1BoardInfo[n].vgaPassthruDisable = 0;
1064 sst1BoardInfo[n].vgaPassthruEnable = 0;
1065 sst1BoardInfo[n].memFifoStatusLwm = 0xdead;
1066 }
1067}
1068
1069/*
1070** sst1InitNumBoardsInSystem():
1071** Returns the number of SST-1 boards in the system
1072**
1073*/
1074FX_ENTRY FxU32 FX_CSTYLE sst1InitNumBoardsInSystem(void)
1075{
1076 FxU32 vendorID = _3DFX_PCI_ID; // 3Dfx Vendor ID
1077 FxU32 deviceID; // 0x0002 - Find Voodoo2 boards ( 0xFFFF - Find any 3Dfx board)
1078 FxU32 j, n;
1079
1080 if( GETENV( ("SSTV2_DEVICEID") ) )
1081 deviceID = ATOI( GETENV( "SSTV2_DEVICEID" ) );
1082 else
1083 deviceID = 0x0002;
1084
1085 boardsInSystemReally = 0;
1086 for(j=0; j<SST1INIT_MAX_BOARDS; j++) {
1087 if(pciFindCardMulti(vendorID, deviceID, &n, j))
1088 boardsInSystemReally++;
1089 }
1090 if(GETENV(("SSTV2_BOARDS")))
1091 return(ATOI(GETENV(("SSTV2_BOARDS"))));
1092 else
1093 return(boardsInSystemReally);
1094}
1095
1096/*
1097** sst1InitCaching
1098**
1099** Sets up memory caching on P6 systems for the entire 16mb virtual
1100** address space of the card.
1101**
1102*/
1103FX_ENTRY FxBool FX_CSTYLE
1104sst1InitCaching(FxU32* sstBase, FxBool enableP)
1105{
1106 FxBool retVal = sst1InitCheckBoard(sstBase);
1107
1108 if (!retVal) return FXFALSE;
1109
1110 if (enableP && (GETENV("SSTV2_IGNORE_CACHING") == NULL)) {
1111 FxU32 physAddr;
1112
1113 /* Get the board's base. Isn't this the same as what we
1114 * cary around in sst1CurrentBoard->physAddr[0]?
1115 */
1116 pciGetConfigData(PCI_BASE_ADDRESS_0, sst1CurrentBoard->deviceNumber, &physAddr);
1117
1118 // For some reason, there sometimes is a 008 at the end of the
1119 // physical address, so mask that puppy RTF out
1120 physAddr &= 0xfffff000;
1121
1122 /* dpc - 23 jan 1998 - Warning!!!!!
1123 * We are no longer mapping the entire board range as uswc because
1124 * this causes weird problems on some systems. We are now mapping
1125 * the 3d register area as uncacheable (since no one should be
1126 * writing here anyway, except to bump the swapbufferCMD register)
1127 * and the command fifo range and lfb range as uswc.
1128 *
1129 * NB: It is still unclear why this is happening because the
1130 * memory page containing the registers is never really explicitly
1131 * written to until we are shutting down so changing its caching
1132 * characteristics should have no bearing on anything. */
1133 {
1134#define kCacheSizeWriteCombine (0x08UL << 20UL)
1135#define kCacheSizeUncacheable (0x1000UL)
1136 FxBool hasWC = pciFindMTRRMatch(physAddr, kCacheSizeWriteCombine,
1137 PciMemTypeWriteCombining,
1138 &sst1CurrentBoard->mtrrWriteCombine);
1139 FxBool hasUC = pciFindMTRRMatch(physAddr, kCacheSizeUncacheable,
1140 PciMemTypeUncacheable,
1141 &sst1CurrentBoard->mtrrUncacheable);
1142
1143 if (!hasWC) {
1144 if (pciFindFreeMTRR(&sst1CurrentBoard->mtrrWriteCombine)) {
1145 hasWC = pciSetMTRR(sst1CurrentBoard->mtrrWriteCombine,
1146 physAddr, kCacheSizeWriteCombine,
1147 PciMemTypeWriteCombining);
1148 if (!hasWC) INIT_PRINTF(("sst1InitCaching(): Could not set wc mtrr\n"));
1149 } else {
1150 INIT_PRINTF(("sst1InitCaching(): Could not find wc mtrr\n"));
1151 }
1152 } else {
1153 INIT_PRINTF(("sst1InitCaching(): Already have wc\n"));
1154 }
1155
1156 if (!hasUC) {
1157 if (pciFindFreeMTRR(&sst1CurrentBoard->mtrrUncacheable)) {
1158 hasUC = pciSetMTRR(sst1CurrentBoard->mtrrUncacheable,
1159 physAddr, kCacheSizeUncacheable,
1160 PciMemTypeUncacheable);
1161 if (!hasUC) INIT_PRINTF(("sst1InitCaching(): Could not set uc mtrr\n"));
1162 } else {
1163 INIT_PRINTF(("sst1InitCaching(): Could not find uc mtrr\n"));
1164 }
1165 } else {
1166 INIT_PRINTF(("sst1InitCaching(): Already have uc\n"));
1167 }
1168
1169 /* We only succeed if we have them both since having only uswc
1170 * seems to cause problems.
1171 */
1172 retVal = (hasWC && hasUC);
1173 if (!retVal) goto __errExit;
1174
1175 INIT_PRINTF(("sst1InitCaching(): wc(0x%X) : uc(0x%X)\n",
1176 sst1CurrentBoard->mtrrWriteCombine,
1177 sst1CurrentBoard->mtrrUncacheable));
1178 }
1179 } else {
1180 /* This always succeeds */
1181 retVal = FXTRUE;
1182
1183__errExit:
1184 if (sst1CurrentBoard->mtrrUncacheable != 0) {
1185 pciSetMTRR(sst1CurrentBoard->mtrrUncacheable, 0, 0, 0);
1186 sst1CurrentBoard->mtrrUncacheable = 0;
1187 }
1188
1189 if (sst1CurrentBoard->mtrrWriteCombine != 0) {
1190 pciSetMTRR(sst1CurrentBoard->mtrrWriteCombine, 0, 0, 0);
1191 sst1CurrentBoard->mtrrWriteCombine = 0;
1192 }
1193 }
1194
1195 return retVal;
1196} // sst1InitSetCaching
1197
1198#pragma optimize ("",on)
Note: See TracBrowser for help on using the repository browser.