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

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

Added $Id:$ keyword.

File size: 45.3 KB
Line 
1/*-*-c++-*-*/
2/* $Id: video.c,v 1.2 2001-09-05 14:30:43 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:43 $
24**
25** Initialization code for initializing SST-1 video unit
26**
27*/
28#pragma optimize ("",off)
29#include <stdio.h>
30#include <stdlib.h>
31#include <math.h>
32#ifdef BUILD_FOR_SST1
33#include <sst.h>
34#else
35#include <3dfx.h>
36#include <cvgregs.h>
37#include <cvgdefs.h>
38#endif
39#define FX_DLL_DEFINITION
40#include <fxdll.h>
41#define SST1INIT_VIDEO_ALLOCATE // allocate data structures for video timing
42#include <sst1vid.h>
43#include <sst1init.h>
44
45/*
46** sst1InitVideo():
47** Initialize video (including DAC setup) for the specified resolution
48**
49** Note: sst1InitVideo() is included for compatibility with SST-1 apps only
50** and should not be used for Voodoo2. Use sst1InitVideoBuffers() instead.
51**
52*/
53FX_EXPORT FxBool FX_CSTYLE sst1InitVideo(FxU32 *sstbase,
54 GrScreenResolution_t screenResolution, GrScreenRefresh_t screenRefresh,
55 void *placeHolder)
56{
57 FxU32 memSizeInPages;
58 sst1VideoTimingStruct *videoTiming;
59 FxU32 colorBuffs, auxBuffs;
60
61 if(!sstbase)
62 return(FXFALSE);
63
64 if(sst1InitCheckBoard(sstbase) == FXFALSE)
65 return(FXFALSE);
66
67 if(GETENV(("SSTV2_IGNORE_INIT_VIDEO"))) {
68 INIT_PRINTF(("WARNING: Ignoring sst1InitVideo()...\n"));
69 sst1InitIdleFBINoNOP(sstbase);
70 return(FXTRUE);
71 }
72
73 if(!(videoTiming = sst1InitFindVideoTimingStruct(screenResolution,
74 screenRefresh)))
75 return(FXFALSE);
76
77 if(sst1CurrentBoard->fbiMemSize == 1)
78 memSizeInPages = 256;
79 else if(sst1CurrentBoard->fbiMemSize == 2)
80 memSizeInPages = 512;
81 else
82 memSizeInPages = 1024;
83 if(sst1CurrentBoard->sliDetected)
84 memSizeInPages <<= 1;
85
86 // Do we have enough memory for the desired resolution?
87 if(memSizeInPages > (3 * videoTiming->memOffset)) {
88 colorBuffs = 2;
89 auxBuffs = 1;
90 } else if(memSizeInPages > (2 * videoTiming->memOffset)) {
91 colorBuffs = 2;
92 auxBuffs = 0;
93 } else {
94 INIT_PRINTF(("sst1InitVideo(): Insufficient memory available for desired resolution...\n"));
95 return(FXFALSE);
96 }
97
98 return(sst1InitVideoBuffers(sstbase, screenResolution, screenRefresh,
99 colorBuffs, auxBuffs, (sst1VideoTimingStruct *) NULL, FXTRUE));
100}
101
102/*
103** sst1InitVideoBuffers():
104** Initialize video (including DAC setup) for the specified resolution
105**
106** Returns:
107** FXTRUE if successfully initializes specified SST-1 video resolution
108** FXFALSE if cannot initialize SST-1 to specified video resolution
109**
110*/
111FX_EXPORT FxBool FX_CSTYLE sst1InitVideoBuffers(FxU32 *sstbase,
112 GrScreenResolution_t screenResolution, GrScreenRefresh_t screenRefresh,
113 FxU32 nColorBuffs, FxU32 nAuxBuffs, sst1VideoTimingStruct *altVideoTiming,
114 FxBool switchPassThru)
115{
116 FxU32 n, vtmp;
117 SstRegs *sst = (SstRegs *) sstbase;
118 sst1VideoTimingStruct *sstVideoRez;
119 FxU32 video16BPP;
120 FxU32 memFifoLwm, memFifoHwm, pciFifoLwm;
121 FxU32 vInClkDel, vOutClkDel;
122 FxU32 tf0_clkdel, tf1_clkdel, tf2_clkdel;
123 FxU32 ft_clkdel, memSizeInPages;
124 FxU32 nCol, nAux, miscCtrl;
125 int memFifoEntries;
126
127 if(!sst)
128 return(FXFALSE);
129
130 if(sst1InitCheckBoard(sstbase) == FXFALSE)
131 return(FXFALSE);
132
133 if(GETENV(("SSTV2_IGNORE_INIT_VIDEO"))) {
134 INIT_PRINTF(("WARNING: Ignoring sst1InitVideo()...\n"));
135 sst1InitIdleFBINoNOP(sstbase);
136 return(FXTRUE);
137 }
138
139 if(altVideoTiming && !GETENV(("SSTV2_SCREENREZ")) &&
140 !GETENV(("SSTV2_SCREENREFRESH")))
141 sstVideoRez = altVideoTiming;
142 else {
143 if(!(sstVideoRez = sst1InitFindVideoTimingStruct(screenResolution,
144 screenRefresh)))
145 return(FXFALSE);
146 }
147
148 nCol = nColorBuffs;
149 nAux = nAuxBuffs;
150
151 // Disallow unsupported buffer combinations...
152 if(nCol < 2 || nCol > 3 || nAux > 1)
153 return(FXFALSE);
154
155 if(sst1CurrentBoard->fbiMemSize == 1)
156 memSizeInPages = 256;
157 else if(sst1CurrentBoard->fbiMemSize == 2)
158 memSizeInPages = 512;
159 else
160 memSizeInPages = 1024;
161 if(sst1CurrentBoard->sliDetected)
162 memSizeInPages <<= 1;
163
164 // To be compatible with Voodoo1, if there is enough memory to
165 // allocate an aux buffer, then do it...
166 if(nCol == 2 && nAux == 0) {
167 if(memSizeInPages > (3 * sstVideoRez->memOffset)) {
168 INIT_PRINTF(("sst1InitVideo(): Allocating 1 Aux Buffer for SST-1 Compatibility...\n"));
169 nAux++;
170 }
171 }
172
173 if(GETENV(("SSTV2_ALLOC_COLOR")))
174 nCol = ATOI(GETENV(("SSTV2_ALLOC_COLOR")));
175 if(GETENV(("SSTV2_ALLOC_AUX")))
176 nAux = ATOI(GETENV(("SSTV2_ALLOC_AUX")));
177
178 // Disallow unsupported buffer combinations (from environment vars)...
179 if(nCol < 2 || nCol > 3 || nAux > 1)
180 return(FXFALSE);
181
182 //
183 // Do we have enough memory for the desired resolution?
184 //
185 if(memSizeInPages < ((nCol + nAux) * sstVideoRez->memOffset)) {
186 INIT_PRINTF(("sst1InitVideo(): Insufficient memory available for desired resolution.\n"));
187 return(FXFALSE);
188 }
189 if(GETENV(("SSTV2_VIDEO_24BPP")))
190 sst1CurrentBoard->fbiVideo16BPP =
191 (ATOI(GETENV(("SSTV2_VIDEO_24BPP")))) ^ 0x1;
192 else {
193 sst1CurrentBoard->fbiVideo16BPP = 0;
194
195 if(sst1CurrentBoard->fbiVideo16BPP && (sstVideoRez->video16BPPIsOK ==
196 FXFALSE))
197 sst1CurrentBoard->fbiVideo16BPP = 0;
198 if(!sst1CurrentBoard->fbiVideo16BPP && (sstVideoRez->video24BPPIsOK ==
199 FXFALSE))
200 sst1CurrentBoard->fbiVideo16BPP = 1;
201
202 if(altVideoTiming == (sst1VideoTimingStruct *) NULL) {
203 // Determine when cannot output 24bpp video...
204 // Cannot run at high frequencies across SLI connector...
205 if(sst1CurrentBoard->sliDetected &&
206 sstVideoRez->clkFreq24bpp > 90.0F)
207 sst1CurrentBoard->fbiVideo16BPP = 1;
208 }
209 }
210 video16BPP = sst1CurrentBoard->fbiVideo16BPP;
211
212 // Reset Video Refresh Unit
213 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
214
215 // Setup SST video timing registers
216 if(GETENV(("SSTV2_HSYNC"))) {
217 SSCANF(GETENV(("SSTV2_HSYNC")), "%i", &vtmp);
218 INIT_PRINTF(("sst1InitVideo(): Using SST_HSYNC=0x%x\n", vtmp));
219 ISET(sst->hSync, vtmp);
220 } else
221 ISET(sst->hSync, ((sstVideoRez->hSyncOff << SST_VIDEO_HSYNC_OFF_SHIFT) |
222 (sstVideoRez->hSyncOn << SST_VIDEO_HSYNC_ON_SHIFT)));
223 if(GETENV(("SSTV2_VSYNC"))) {
224 SSCANF(GETENV(("SSTV2_VSYNC")), "%i", &vtmp);
225 INIT_PRINTF(("sst1InitVideo(): Using SST_VSYNC=0x%x\n", vtmp));
226 ISET(sst->vSync, vtmp);
227 } else
228 ISET(sst->vSync, ((sstVideoRez->vSyncOff << SST_VIDEO_VSYNC_OFF_SHIFT) |
229 (sstVideoRez->vSyncOn << SST_VIDEO_VSYNC_ON_SHIFT)));
230 if(GETENV(("SSTV2_BACKPORCH"))) {
231 SSCANF(GETENV(("SSTV2_BACKPORCH")), "%i", &vtmp);
232 INIT_PRINTF(("sst1InitVideo(): Using SST_BACKPORCH=0x%x\n", vtmp));
233 ISET(sst->backPorch, vtmp);
234 } else
235 ISET(sst->backPorch,
236 ((sstVideoRez->vBackPorch << SST_VIDEO_VBACKPORCH_SHIFT) |
237 (sstVideoRez->hBackPorch << SST_VIDEO_HBACKPORCH_SHIFT)));
238 if(GETENV(("SSTV2_DIMENSIONS"))) {
239 SSCANF(GETENV(("SSTV2_DIMENSIONS")), "%i", &vtmp);
240 INIT_PRINTF(("sst1InitVideo(): Using SST_DIMENSIONS=0x%x\n", vtmp));
241 sstVideoRez->yDimension = (vtmp >> SST_VIDEO_YDIM_SHIFT) & 0x3ff;
242 sstVideoRez->xDimension = vtmp & 0x3ff;
243 }
244 ISET(sst->videoDimensions,
245 ((sstVideoRez->yDimension << SST_VIDEO_YDIM_SHIFT) |
246 ((sstVideoRez->xDimension-1) << SST_VIDEO_XDIM_SHIFT)));
247 if(GETENV(("SSTV2_MEMOFFSET"))) {
248 SSCANF(GETENV(("SSTV2_MEMOFFSET")), "%i", &vtmp);
249 INIT_PRINTF(("sst1InitVideo(): Using video memOffset=0x%x\n", vtmp));
250 sstVideoRez->memOffset = vtmp;
251 }
252 if(GETENV(("SSTV2_TILESINX"))) {
253 SSCANF(GETENV(("SSTV2_TILESINX")), "%i", &vtmp);
254 INIT_PRINTF(("sst1InitVideo(): Using video tilesInX=0x%x\n", vtmp));
255 sstVideoRez->tilesInX = vtmp;
256 }
257
258 // Update info structure
259 sst1CurrentBoard->fbiVideoWidth = sstVideoRez->xDimension;
260 sst1CurrentBoard->fbiVideoHeight = sstVideoRez->yDimension;
261 sst1CurrentBoard->fbiVideoRefresh = sstVideoRez->refreshRate;
262 sst1CurrentBoard->fbiVideoColBuffs = nCol;
263 sst1CurrentBoard->fbiVideoAuxBuffs = nAux;
264 sst1CurrentBoard->fbiVideoMemOffset = sstVideoRez->memOffset;
265 sst1CurrentBoard->fbiVideoTilesInX = sstVideoRez->tilesInX;
266 sst1CurrentBoard->fbiVideoStruct = sstVideoRez;
267
268 // Setup SST memory mapper for desired resolution
269 if(sst1CurrentBoard->fbiMemSize == 4)
270 sst1InitSetResolution(sstbase, sstVideoRez, 1);
271 else
272 sst1InitSetResolution(sstbase, sstVideoRez, 0);
273
274 // Calculate graphics clock frequency
275 if(sst1InitCalcGrxClk(sstbase) == FXFALSE)
276 return(FXFALSE);
277
278 // Setup video fifo
279 // NOTE: Lower values for the video fifo threshold improve video fifo
280 // underflow problems
281 if(GETENV(("SSTV2_VFIFO_THRESH"))) {
282 INIT_PRINTF(("sst1InitVideo(): Overriding Default Video Fifo Threshold %d and Storing %d\n",
283 sstVideoRez->vFifoThreshold, ATOI(GETENV(("SSTV2_VFIFO_THRESH")))));
284 ISET(sst->fbiInit3, (IGET(sst->fbiInit3) & ~SST_VIDEO_FIFO_THRESH) |
285
286 ((ATOI(GETENV(("SSTV2_VFIFO_THRESH"))))
287 << SST_VIDEO_FIFO_THRESH_SHIFT));
288 } else {
289 FxU32 vFifoThresholdVal = sstVideoRez->vFifoThreshold;
290
291 if(sst1CurrentBoard->fbiGrxClkFreq < 45)
292 // Lower threshold value for slower graphics clocks
293 vFifoThresholdVal = sstVideoRez->vFifoThreshold - 4;
294
295 ISET(sst->fbiInit3, (IGET(sst->fbiInit3) & ~SST_VIDEO_FIFO_THRESH) |
296 (vFifoThresholdVal << SST_VIDEO_FIFO_THRESH_SHIFT));
297 }
298
299 INIT_PRINTF(("sst1InitVideo() Setting up video for resolution (%d, %d), Refresh:%d Hz...\n",
300 sstVideoRez->xDimension, sstVideoRez->yDimension,
301 sstVideoRez->refreshRate));
302 INIT_PRINTF(("sst1InitVideo(): Video Fifo Threshold = %d\n",
303 (IGET(sst->fbiInit3) & SST_VIDEO_FIFO_THRESH) >>
304 SST_VIDEO_FIFO_THRESH_SHIFT));
305
306 // Initialize Y-Origin
307 sst1InitIdleFBINoNOP(sstbase);
308 ISET(sst->fbiInit3, (IGET(sst->fbiInit3) & ~SST_YORIGIN_TOP) |
309 ((sstVideoRez->yDimension - 1) << SST_YORIGIN_TOP_SHIFT));
310
311 sst1InitIdleFBINoNOP(sstbase);
312
313 memFifoLwm = 23;
314 if(GETENV(("SSTV2_MEMFIFO_LWM")))
315 SSCANF(GETENV(("SSTV2_MEMFIFO_LWM")), "%i", &memFifoLwm);
316 memFifoHwm = 54;
317 if(GETENV(("SSTV2_MEMFIFO_HWM")))
318 SSCANF(GETENV(("SSTV2_MEMFIFO_HWM")), "%i", &memFifoHwm);
319 pciFifoLwm = 13;
320 if(GETENV(("SSTV2_PCIFIFO_LWM")))
321 SSCANF(GETENV(("SSTV2_PCIFIFO_LWM")), "%i", &pciFifoLwm);
322 INIT_PRINTF(("sst1InitVideo(): pciFifoLwm:%d memFifoLwm:%d memFifoHwm:%d\n",
323 pciFifoLwm, memFifoLwm, memFifoHwm));
324
325 // Setup Memory FIFO
326 sst1InitIdleFBINoNOP(sstbase);
327 ISET(sst->fbiInit4, IGET(sst->fbiInit4) &
328 ~(SST_MEM_FIFO_ROW_BASE | SST_MEM_FIFO_ROW_ROLL | SST_MEM_FIFO_LWM));
329 sst1InitIdleFBINoNOP(sstbase);
330 if(sst1CurrentBoard->fbiMemSize == 1)
331 ISET(sst->fbiInit4, IGET(sst->fbiInit4) |
332 (0xff << SST_MEM_FIFO_ROW_ROLL_SHIFT));
333 else if (sst1CurrentBoard->fbiMemSize == 2)
334 ISET(sst->fbiInit4, IGET(sst->fbiInit4) |
335 (0x1ff << SST_MEM_FIFO_ROW_ROLL_SHIFT));
336 else
337 // 4 MBytes frame buffer memory...
338 ISET(sst->fbiInit4, IGET(sst->fbiInit4) |
339 (0x3ff << SST_MEM_FIFO_ROW_ROLL_SHIFT));
340 sst1InitIdleFBINoNOP(sstbase);
341
342 // Setup buffer management...
343 if(sst1InitAllocBuffers(sstbase, nCol, nAux) == FXFALSE)
344 return(FXFALSE);
345
346 INIT_PRINTF(("sst1InitVideo(): Allocating %d Color Buffers and %d Aux Buffer(s)...\n",
347 sst1CurrentBoard->fbiVideoColBuffs, sst1CurrentBoard->fbiVideoAuxBuffs));
348 ISET(sst->fbiInit4, IGET(sst->fbiInit4) |
349 (((nCol+nAux)*sstVideoRez->memOffset) << SST_MEM_FIFO_ROW_BASE_SHIFT));
350 sst1InitIdleFBINoNOP(sstbase);
351 ISET(sst->fbiInit4, IGET(sst->fbiInit4) |
352 (memFifoLwm << SST_MEM_FIFO_LWM_SHIFT));
353 sst1InitIdleFBINoNOP(sstbase);
354
355 // Set PCI FIFO LWM
356 ISET(sst->fbiInit0, (IGET(sst->fbiInit0) & ~SST_PCI_FIFO_LWM) |
357 (pciFifoLwm << SST_PCI_FIFO_LWM_SHIFT));
358 sst1InitIdleFBINoNOP(sstbase);
359
360 // Enable Memory Fifo...
361 if(GETENV(("SSTV2_MEMFIFO")))
362 n = ATOI(GETENV(("SSTV2_MEMFIFO")));
363 else
364 n = 1;
365
366 if(n) {
367 sst1CurrentBoard->fbiMemoryFifoEn = 1;
368 memFifoEntries = (65536 - (int)
369 (((int) (memSizeInPages - 1) -
370 (int) ((nCol+nAux) * sstVideoRez->memOffset)) * 512)) >> 5;
371 if(memFifoEntries <= 256)
372 memFifoEntries = 0x100; // max. memory fifo size...
373 else if(memFifoEntries >= 2048) {
374 INIT_PRINTF(("sst1InitVideo(): Invalid memFifoEntries 0x%x\n",
375 memFifoEntries));
376 return(FXFALSE);
377 }
378 if(GETENV(("SSTV2_MEMFIFO_ENTRIES")))
379 SSCANF(GETENV(("SSTV2_MEMFIFO_ENTRIES")), "%i", &memFifoEntries);
380 INIT_PRINTF(("sst1InitVideo(): Enabling Memory FIFO (Entries=%d)...\n",
381 65536 - (memFifoEntries << 5)));
382
383 sst1CurrentBoard->memFifoStatusLwm = (memFifoEntries << 5) | 0x1f;
384 ISET(sst->fbiInit0, (IGET(sst->fbiInit0) & ~(SST_MEM_FIFO_EN |
385 SST_MEM_FIFO_HWM | SST_PCI_FIFO_LWM | SST_MEM_FIFO_BURST_HWM)) |
386 (memFifoEntries << SST_MEM_FIFO_HWM_SHIFT) |
387 (pciFifoLwm << SST_PCI_FIFO_LWM_SHIFT) |
388 (memFifoHwm << SST_MEM_FIFO_BURST_HWM_SHIFT) |
389 SST_MEM_FIFO_EN);
390 INIT_PRINTF(("sst1InitVideo(): Setting memory FIFO LWM to 0x%x (%d)\n",
391 sst1CurrentBoard->memFifoStatusLwm,
392 sst1CurrentBoard->memFifoStatusLwm));
393 }
394
395 vInClkDel = 1;
396 if(GETENV(("SSTV2_VIN_CLKDEL")))
397 SSCANF(GETENV(("SSTV2_VIN_CLKDEL")), "%i", &vInClkDel);
398
399 vOutClkDel = 0;
400 if(GETENV(("SSTV2_VOUT_CLKDEL")))
401 SSCANF(GETENV(("SSTV2_VOUT_CLKDEL")), "%i", &vOutClkDel);
402
403 INIT_PRINTF(("sst1InitVideo(): vInClkDel=0x%x vOutClkDel=0x%x\n",
404
405 vInClkDel, vOutClkDel));
406
407 // Setup miscellaneous control
408 miscCtrl = 0;
409 if(sstVideoRez->miscCtrl & BIT(0))
410 miscCtrl |= SST_SCAN_DOUBLE_HORIZ;
411 if(sstVideoRez->miscCtrl & BIT(1))
412 miscCtrl |= SST_SCAN_DOUBLE_VERT;
413 if(sstVideoRez->miscCtrl & BIT(2))
414 miscCtrl |= SST_INVERT_HSYNC;
415 if(sstVideoRez->miscCtrl & BIT(3))
416 miscCtrl |= SST_INVERT_VSYNC;
417
418 // Drive dac output signals and select input video clock
419 if(video16BPP) {
420 INIT_PRINTF(("sst1InitVideo(): Setting 16BPP video mode...\n"));
421 ISET(sst->fbiInit1, (IGET(sst->fbiInit1) & ~SST_VIDEO_MASK) |
422 (SST_VIDEO_DATA_OE_EN |
423 SST_VIDEO_BLANK_OE_EN |
424 SST_VIDEO_HVSYNC_OE_EN |
425 SST_VIDEO_DCLK_OE_EN |
426 SST_VIDEO_VID_CLK_2X |
427 (vInClkDel << SST_VIDEO_VCLK_DEL_SHIFT) |
428 (vOutClkDel << SST_VIDEO_VCLK_2X_OUTPUT_DEL_SHIFT) |
429 SST_VIDEO_VCLK_SEL));
430 sst1InitIdleFBINoNOP(sstbase);
431 ISET(sst->fbiInit5, IGET(sst->fbiInit5) | miscCtrl);
432 } else {
433 INIT_PRINTF(("sst1InitVideo(): Setting 24BPP video mode...\n"));
434#if 0
435 // Old clock settings -- probably use for true 24-bit dac output
436 ISET(sst->fbiInit1, (IGET(sst->fbiInit1) & ~SST_VIDEO_MASK) |
437 (SST_VIDEO_DATA_OE_EN |
438 SST_VIDEO_BLANK_OE_EN |
439 SST_VIDEO_HVSYNC_OE_EN |
440 SST_VIDEO_DCLK_OE_EN |
441 SST_VIDEO_VID_CLK_2X |
442 SST_VIDEO_VCLK_DIV2 |
443 (vInClkDel << SST_VIDEO_VCLK_DEL_SHIFT) |
444 (vOutClkDel << SST_VIDEO_VCLK_2X_OUTPUT_DEL_SHIFT) |
445 SST_VIDEO_24BPP_EN));
446#else
447 ISET(sst->fbiInit1, (IGET(sst->fbiInit1) & ~SST_VIDEO_MASK) |
448 (SST_VIDEO_DATA_OE_EN |
449 SST_VIDEO_BLANK_OE_EN |
450 SST_VIDEO_HVSYNC_OE_EN |
451 SST_VIDEO_DCLK_OE_EN |
452 // SST_VIDEO_VID_CLK_2X | // BIT(17)
453 // SST_VIDEO_VCLK_DIV2 | // MUX select 0x1
454 (0x0 << SST_VIDEO_VCLK_SEL_SHIFT) | // MUX select 0x0
455 (vInClkDel << SST_VIDEO_VCLK_DEL_SHIFT) |
456 (vOutClkDel << SST_VIDEO_VCLK_2X_OUTPUT_DEL_SHIFT) |
457 SST_VIDEO_24BPP_EN));
458 ISET(sst->fbiInit5, IGET(sst->fbiInit5) |
459 SST_VIDEO_CLK_SLAVE_OE_EN | SST_VID_CLK_2X_OUT_OE_EN |
460 SST_VID_CLK_DAC_DATA16_SEL | miscCtrl);
461#endif
462 sst1InitIdleFBINoNOP(sstbase);
463 if(!GETENV(("SSTV2_VIDEO_FILTER_DISABLE"))) {
464 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_FILTER_EN);
465 if(GETENV(("SSTV2_VIDEO_FILTER_THRESHOLD"))) {
466 SSCANF(GETENV(("SSTV2_VIDEO_FILTER_THRESHOLD")), "%i", &n);
467 INIT_PRINTF(("sst1InitVideo(): Setting Video Filtering Treshold to 0x%x...\n", n));
468
469 ISET(sst->videoFilterRgbThreshold, n);
470 } else
471 // ISET(sst->videoFilterRgbThreshold, 0x180c18);
472 ISET(sst->videoFilterRgbThreshold, 0x080408);
473 } else
474 INIT_PRINTF(("sst1InitVideo(): Disabling Video Filtering...\n"));
475 }
476
477 // Setup prelim. clock delay values...
478 if(sst1CurrentBoard->fbiBoardID == 0x3) {
479 // Early 4-layer 4220 board -- Runs at 83 MHz by default...
480 if(sst1CurrentBoard->fbiGrxClkFreq <= 80) {
481 ft_clkdel = 0x5;
482 tf0_clkdel = 0x7;
483 tf1_clkdel = 0x8;
484 tf2_clkdel = 0x8;
485 } else {
486 ft_clkdel = 0x4;
487 tf0_clkdel = 0x6;
488 tf1_clkdel = 0x7;
489 tf2_clkdel = 0x7;
490 }
491 } else if(sst1CurrentBoard->fbiBoardID == 0x2) {
492 // 4400 8-layer bringup board -- Runs at 90 MHz by default...
493 ft_clkdel = 0x4;
494 tf0_clkdel = 0x6;
495 tf1_clkdel = 0x6;
496 tf2_clkdel = 0x6;
497 } else {
498 // Setup basic values...
499 ft_clkdel = 0x4;
500 tf0_clkdel = 0x6;
501 tf1_clkdel = 0x6;
502 tf2_clkdel = 0x6;
503 }
504
505 ISET(sst->fbiInit3, (IGET(sst->fbiInit3) & ~SST_FT_CLK_DEL_ADJ) |
506 (ft_clkdel << SST_FT_CLK_DEL_ADJ_SHIFT));
507 sst1InitIdleFBINoNOP(sstbase);
508
509 sst1CurrentBoard->tmuInit1[0] = (sst1CurrentBoard->tmuInit1[0] &
510 ~SST_TEX_TF_CLK_DEL_ADJ) | (tf0_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
511 sst1CurrentBoard->tmuInit1[1] = (sst1CurrentBoard->tmuInit1[1] &
512 ~SST_TEX_TF_CLK_DEL_ADJ) | (tf1_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
513 sst1CurrentBoard->tmuInit1[2] = (sst1CurrentBoard->tmuInit1[2] &
514 ~SST_TEX_TF_CLK_DEL_ADJ) | (tf2_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
515
516 // Calling sst1InitResetTmus() will put the new trexinit values in the
517 // TMUs, as well as reset FBI and TMU...
518 sst1InitResetTmus(sstbase);
519
520 // Setup graphics clock
521 if(sst1InitGrxClk(sstbase) == FXFALSE)
522 return(FXFALSE);
523
524 // Setup video mode
525 if(sst1InitSetVidMode(sstbase, video16BPP) == FXFALSE)
526 return(FXFALSE);
527
528 // Adjust Video Clock
529#ifndef DIRECTX
530 if(GETENV(("SSTV2_VIDCLK2X"))) {
531 float vidClkFreq;
532
533 SSCANF(GETENV(("SSTV2_VIDCLK2X")), "%f", &vidClkFreq);
534 if(sst1InitSetVidClk(sstbase, vidClkFreq) == FXFALSE)
535 return(FXFALSE);
536 } else {
537#endif
538 if(sst1InitUseVoodooFile == FXTRUE) {
539 if(sst1InitSetVidClkINI(sstbase, sst1CurrentBoard->fbiVideoWidth,
540 sst1CurrentBoard->fbiVideoHeight,
541 sst1CurrentBoard->fbiVideoRefresh, video16BPP) == FXFALSE)
542 return(FXFALSE);
543 } else {
544 if(video16BPP) {
545 if(sst1InitSetVidClk(sstbase, sstVideoRez->clkFreq16bpp) ==
546 FXFALSE)
547 return(FXFALSE);
548 } else {
549 if(sst1InitSetVidClk(sstbase, sstVideoRez->clkFreq24bpp) ==
550 FXFALSE)
551 return(FXFALSE);
552 }
553 }
554#ifndef DIRECTX
555 }
556#endif
557
558 // Wait for video clock to stabilize
559 for(n=0; n<200000; n++)
560 sst1InitReturnStatus(sstbase);
561
562 // Run Video Reset Module
563 ISET(sst->fbiInit1, IGET(sst->fbiInit1) & ~SST_VIDEO_RESET);
564 sst1InitIdleFBINoNOP(sstbase);
565
566 ISET(sst->fbiInit2, IGET(sst->fbiInit2) | SST_EN_DRAM_REFRESH);
567
568 sst1InitIdleFBINoNOP(sstbase);
569
570 // Calculate final clock delay values...
571 if(sst1InitSetClkDelays(sstbase) == FXFALSE) {
572 INIT_PRINTF(("sst1InitVideo() ERROR: Could not calculate clock delay values...\n"));
573 return(FXFALSE);
574 }
575
576 // Clear memory...
577 if(!GETENV(("SSTV2_VIDEO_NOCLEAR"))) {
578 FxU32 clearColor = 0x0;
579 FxU32 pagesToFill;
580
581 if(GETENV(("SSTV2_VIDEO_CLEARCOLOR")))
582 SSCANF(GETENV(("SSTV2_VIDEO_CLEARCOLOR")), "%i", &clearColor);
583
584 if(sst1CurrentBoard->fbiMemSize == 1)
585 pagesToFill = 256;
586 else if(sst1CurrentBoard->fbiMemSize == 2)
587 pagesToFill = 512;
588 else
589 pagesToFill = 1024;
590
591 ISET(sst->bltColor, clearColor);
592 ISET(sst->bltDstXY, 0x0);
593 ISET(sst->bltSize, ((pagesToFill-1)<<16) | 511);
594 ISET(sst->bltCommand, SSTG_FRECTFILL | SSTG_GO);
595 sst1InitIdle(sstbase);
596 } else
597 INIT_PRINTF(("sst1InitVideo(): Not Clearing Frame Buffer...\n"));
598
599 // Clear fbistat registers after clearing screen
600 ISET(sst->nopCMD, 0x3);
601
602 // Only switch passthrough and do monitor detection if
603 // requested.
604 if(switchPassThru == FXTRUE)
605 {
606 // 3D now owns monitor...
607 sst1InitVgaPassCtrl(sstbase, 0);
608
609 // Detect presence of monitor...
610 sst1InitMonitorDetect(sstbase);
611 INIT_PRINTF(("sst1InitVideo(): Monitor Detected:%d\n",
612 sst1CurrentBoard->monitorDetected));
613
614 // sst1InitMonitorDetect() trashes the gamma table. Reload to the
615 // original value if sst1InitGamma() has already been called -- otherwise
616 // load a 1.0 gamma table
617 if(sst1CurrentBoard->fbiInitGammaDone)
618 sst1InitGammaRGB(sstbase, sst1CurrentBoard->fbiGammaRed,
619 sst1CurrentBoard->fbiGammaGreen, sst1CurrentBoard->fbiGammaBlue);
620 else {
621 // Do not display gamma values when called by sst1InitVideo()...
622 sst1CurrentBoard->fbiInitGammaDone = 1;
623 sst1InitGammaRGB(sstbase, (double) 1.0, (double) 1.0, (double) 1.0);
624 sst1CurrentBoard->fbiInitGammaDone = 0;
625 }
626 }
627
628 if(GETENV(("SSTV2_VIDEO_DISABLE"))) {
629 INIT_PRINTF(("sst1InitVideo(): Disabling video timing...\n"));
630 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
631 sst1InitIdleFBINoNOP(sstbase);
632 }
633 sst1InitIdle(sstbase);
634
635 if(((IGET(sst->status) & SST_SWAPBUFPENDING) >>
636 SST_SWAPBUFPENDING_SHIFT) > 0)
637 sst1InitClearSwapPending(sstbase);
638
639 // Since initVideo() is the last init call, if the user wants to
640 // disable idling, do it here. This way, all the calls to initIdle
641 // required within the init code still idle the hardware.
642 if(GETENV(("SSTV2_IGNORE_IDLE"))) {
643 INIT_PRINTF(("sst1InitVideo(): Ignoring calls to sst1InitIdle()...\n"));
644 initIdleEnabled = 0;
645 }
646
647 // Update info structure for initEnable
648 PCICFG_RD(SST1_PCI_INIT_ENABLE, sst1CurrentBoard->fbiInitEnable);
649
650 // If this board is SLI-capable, tristate the video output signals so
651 // that monitor detection will work properly for the second board. The
652 // video output signals will be re-enabled during SLI initialization for
653 // the Master board
654 if(sst1CurrentBoard->sliDetected) {
655 INIT_PRINTF(("sst1InitVideo(): Disabling video output signals for proper monitor detection...\n"));
656 sst1InitVideoShutdown(sstbase, FXFALSE);
657 }
658
659 INIT_PRINTF(("sst1InitVideo() exiting with status %d...\n", FXTRUE));
660 return(FXTRUE);
661}
662
663/*
664** sst1InitAllocBuffers():
665** Initialize video for buffer management
666**
667*/
668static FxBool
669sst1InitAllocBuffersDirect(FxU32 *sstbase, FxU32 nColorBuffs, FxU32 nAuxBuffs)
670{
671 SstRegs *sst = (SstRegs *) sstbase;
672 FxU32 nCol = nColorBuffs;
673 FxU32 nAux = nAuxBuffs;
674
675 if(!sst)
676 return(FXFALSE);
677
678 // Setup buffer management...
679 if(nCol == 2 && nAux == 0)
680 ISET(sst->fbiInit5, (IGET(sst->fbiInit5) & ~SST_BUFFER_ALLOC) |
681 SST_BUFFER_ALLOC_2C0Z);
682 else if(nCol == 2 && nAux == 1)
683 ISET(sst->fbiInit5, (IGET(sst->fbiInit5) & ~SST_BUFFER_ALLOC) |
684 SST_BUFFER_ALLOC_2C1Z);
685 else if(nCol == 3 && nAux == 0)
686 ISET(sst->fbiInit5, (IGET(sst->fbiInit5) & ~SST_BUFFER_ALLOC) |
687 SST_BUFFER_ALLOC_3C0Z);
688 else if(nCol == 3 && nAux == 1)
689 ISET(sst->fbiInit5, (IGET(sst->fbiInit5) & ~SST_BUFFER_ALLOC) |
690 SST_BUFFER_ALLOC_3C1Z);
691 else {
692 INIT_PRINTF(("sst1InitAllocBuffers(): Unsupported Color/Aux buffer combination (%d/%d)\n",
693 nCol, nAux));
694 return(FXFALSE);
695 }
696 sst1InitReturnStatus(sstbase);
697
698 return(FXTRUE);
699}
700
701FX_EXPORT FxBool FX_CSTYLE
702sst1InitAllocBuffers(FxU32 *sstbase, FxU32 nColorBuffs, FxU32 nAuxBuffs)
703{
704 SstRegs *sst = (SstRegs *) sstbase;
705 FxU32 nCol = nColorBuffs;
706 FxU32 nAux = nAuxBuffs;
707 FxBool retVal;
708
709 if(!sst)
710 return(FXFALSE);
711
712 if(sst1InitCheckBoard(sstbase) == FXFALSE)
713 return(FXFALSE);
714
715 retVal = sst1InitAllocBuffersDirect(sstbase,
716 nColorBuffs, nAuxBuffs);
717
718 if (retVal && sst1CurrentBoard->sliDetected) {
719 /* NB: When writing to the slave we need to make sure that it does
720 * not have a client callback installed.
721 */
722 FxSet32Proc saveProc = sst1CurrentBoard->set32;
723 sst1CurrentBoard->set32 = NULL;
724
725 sst1InitAllocBuffersDirect(sst1CurrentBoard->sliSlaveVirtAddr,
726 nColorBuffs, nAuxBuffs);
727
728 sst1CurrentBoard->set32 = saveProc;
729 }
730
731 return retVal;
732}
733
734/*
735** sst1InitVideoShutdown():
736** Shutdown video by not driving video outputs
737** Do not reset the video engine
738**
739*/
740FX_EXPORT FxBool FX_CSTYLE sst1InitVideoShutdown(FxU32 *sstbase,
741 FxBool switchPassThruToVGA)
742{
743 SstRegs *sst = (SstRegs *) sstbase;
744
745 if(!sst)
746 return(FXFALSE);
747
748 if(sst1InitCheckBoard(sstbase) == FXFALSE)
749 return(FXFALSE);
750
751 ISET(sst->fbiInit1, (IGET(sst->fbiInit1) & ~(SST_VIDEO_DATA_OE_EN |
752 SST_VIDEO_DCLK_OE_EN | SST_VIDEO_HVSYNC_OE_EN)) | SST_VIDEO_BLANK_EN);
753 sst1InitReturnStatus(sstbase);
754 ISET(sst->fbiInit5, IGET(sst->fbiInit5) & ~(
755 SST_VIDEO_CLK_SLAVE_OE_EN | SST_VID_CLK_2X_OUT_OE_EN));
756 sst1InitReturnStatus(sstbase);
757
758 if(switchPassThruToVGA == FXTRUE)
759 // 2D/VGA now owns monitor...
760 sst1InitVgaPassCtrl(sstbase, 1);
761
762 return(FXTRUE);
763}
764
765/*
766** sst1InitSetVidMode():
767** Set video Mode
768**
769*/
770FxBool sst1InitSetVidMode(FxU32 *sstbase, FxU32 video16BPP)
771{
772 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
773
774 if(helper)
775 INIT_PRINTF(("sst1InitSetVidMode(): Entered...\n"));
776
777 if(sst1InitCheckBoard(sstbase) == FXFALSE)
778 return(FXFALSE);
779
780 if(sst1InitUseVoodooFile == FXTRUE) {
781 return(sst1InitSetVidModeINI(sstbase, video16BPP));
782 } else {
783 if((sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_ATT) ||
784 (sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_TI))
785 return(sst1InitSetVidModeATT(sstbase, video16BPP));
786 else if(sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_ICS)
787 return(sst1InitSetVidModeICS(sstbase, video16BPP));
788 else
789 return(FXFALSE);
790 }
791}
792
793/*
794** sst1InitSetResolution():
795** Setup FBI video resolution registers
796** This routine is used by sst1InitVideo()
797**
798**
799*/
800FX_EXPORT void FX_CSTYLE sst1InitSetResolution(FxU32 *sstbase,
801 sst1VideoTimingStruct *sstVideoRez,
802 FxU32 Banked)
803{
804 SstRegs *sst = (SstRegs *) sstbase;
805
806 if(Banked)
807 ISET(sst->fbiInit2, (IGET(sst->fbiInit2) & ~SST_VIDEO_BUFFER_OFFSET) |
808 (sstVideoRez->memOffset << SST_VIDEO_BUFFER_OFFSET_SHIFT) |
809 SST_DRAM_BANKING_CONFIG | SST_EN_DRAM_BANKED);
810 else
811 ISET(sst->fbiInit2, (IGET(sst->fbiInit2) & ~SST_VIDEO_BUFFER_OFFSET) |
812 (sstVideoRez->memOffset << SST_VIDEO_BUFFER_OFFSET_SHIFT));
813
814 ISET(sst->fbiInit1, (IGET(sst->fbiInit1) & ~SST_VIDEO_TILES_MASK) |
815 (((sstVideoRez->tilesInX>>1) & 0xF)<<SST_VIDEO_TILES_IN_X_SHIFT) |
816 (((sstVideoRez->tilesInX>>5) & 0x1)<<SST_VIDEO_TILES_IN_X_MSB_SHIFT));
817
818 // sst1CurrentBoard must be set previously with a sst1InitCheckBoard()
819 // call...
820 sst1CurrentBoard->fbiInit6 =
821 (sst1CurrentBoard->fbiInit6 & ~SST_VIDEO_TILES_IN_X_LSB) |
822 ((sstVideoRez->tilesInX & 0x1)<<SST_VIDEO_TILES_IN_X_LSB_SHIFT);
823 ISET(sst->fbiInit6, sst1CurrentBoard->fbiInit6);
824}
825
826/*
827** sst1InitSetVidClk():
828** Set video clock
829**
830*/
831FX_EXPORT FxBool FX_CSTYLE sst1InitSetVidClk(FxU32 *sstbase, float vidClkFreq)
832{
833 sst1ClkTimingStruct vidClkTiming;
834 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
835
836 if(helper)
837
838 INIT_PRINTF(("sst1InitSetVidClk(): Entered...\n"));
839
840 if(sst1InitCheckBoard(sstbase) == FXFALSE)
841 return(FXFALSE);
842
843 if(sst1InitComputeClkParams(vidClkFreq, &vidClkTiming) == FXFALSE)
844 return(FXFALSE);
845
846 INIT_PRINTF(("sst1InitSetVidClk(): Setting up %.2f MHz Video Clock...\n",
847 vidClkFreq));
848
849 if((sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_ATT) ||
850 (sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_TI))
851 return(sst1InitSetVidClkATT(sstbase, &vidClkTiming));
852 else if(sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_ICS)
853 return(sst1InitSetVidClkICS(sstbase, &vidClkTiming));
854 else
855 return(FXFALSE);
856}
857
858/*
859** sst1InitSetGrxClk():
860** Set graphics clock
861** NOTE: sst1InitSetGrxClk() resets the PCI fifo and the graphics subsystem
862** of FBI
863**
864*/
865FX_EXPORT FxBool FX_CSTYLE sst1InitSetGrxClk(FxU32 *sstbase,
866 sst1ClkTimingStruct *sstGrxClk)
867{
868 FxBool retVal = FXFALSE;
869 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
870
871 if(helper)
872 INIT_PRINTF(("sst1InitSetGrxClk(): Entered...\n"));
873
874 if(sst1InitCheckBoard(sstbase) == FXFALSE)
875 return(FXFALSE);
876
877 if(sst1InitUseVoodooFile == FXTRUE) {
878 retVal = sst1InitSetGrxClkINI(sstbase, sstGrxClk);
879 } else {
880 if((sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_ATT) ||
881 (sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_TI))
882 retVal = sst1InitSetGrxClkATT(sstbase, sstGrxClk);
883 else if(sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_ICS)
884 retVal = sst1InitSetGrxClkICS(sstbase, sstGrxClk);
885 }
886 if(retVal == FXFALSE)
887 return(FXFALSE);
888
889 // Always reset TMUs after a clock change...
890 return(sst1InitResetTmus(sstbase));
891}
892
893/*
894** sst1InitVideoBorder():
895** Initialize video color border
896**
897** The 'mask' parameter specifies which border(s) to enable:
898** SST_COLOR_BORDER_LEFT_EN: Left edge
899** SST_COLOR_BORDER_RIGHT_EN: Right edge
900** SST_COLOR_BORDER_TOP_EN: Top edge
901** SST_COLOR_BORDER_BOTTOM_EN: Bottom edge
902** The 'color' parameter is in XXRRGGBB format
903**
904** Returns:
905** FXTRUE if successfully initializes video color border
906** FXFALSE if cannot initialize video color border
907**
908*/
909FX_EXPORT FxBool FX_CSTYLE sst1InitVideoBorder(FxU32 *sstbase,
910 FxU32 mask,
911 FxU32 color)
912{
913
914 FxU32 fbiInit5;
915 SstRegs *sst = (SstRegs *) sstbase;
916
917 if(!sst)
918 return(FXFALSE);
919
920 if(sst1InitCheckBoard(sstbase) == FXFALSE)
921 return(FXFALSE);
922
923 INIT_PRINTF(("sst1InitVideoBorder(): Setting border color to 0x%x...\n",
924 color));
925
926 fbiInit5 = IGET(sst->fbiInit5) &
927 ~(SST_COLOR_BORDER_LEFT_EN | SST_COLOR_BORDER_RIGHT_EN |
928 SST_COLOR_BORDER_TOP_EN | SST_COLOR_BORDER_BOTTOM_EN);
929 fbiInit5 |=
930 (mask & SST_COLOR_BORDER_LEFT_EN) ? SST_COLOR_BORDER_LEFT_EN : 0;
931 fbiInit5 |=
932 (mask & SST_COLOR_BORDER_RIGHT_EN) ? SST_COLOR_BORDER_RIGHT_EN : 0;
933 fbiInit5 |=
934 (mask & SST_COLOR_BORDER_TOP_EN) ? SST_COLOR_BORDER_TOP_EN : 0;
935 fbiInit5 |=
936 (mask & SST_COLOR_BORDER_BOTTOM_EN) ? SST_COLOR_BORDER_BOTTOM_EN : 0;
937
938 ISET(sst->borderColor, color);
939 ISET(sst->fbiInit5, fbiInit5);
940
941 return(FXTRUE);
942}
943
944/*
945** sst1InitFindVideoTimingStruct():
946** Find SST-1 video timing data structure from GrScreenResolution_t and
947** GrScreenRefresh_t input params
948**
949*/
950
951FX_EXPORT sst1VideoTimingStruct* FX_CSTYLE
952sst1InitFindVideoTimingStruct(GrScreenResolution_t screenResolution,
953 GrScreenRefresh_t screenRefresh)
954{
955 GrScreenResolution_t screenRez = screenResolution;
956 GrScreenRefresh_t refreshRate = screenRefresh;
957
958 // Override Screen resolution with environment variables
959 if(GETENV(("SSTV2_SCREENREZ"))) {
960 FxU32 screenRezEnv = ATOI(GETENV(("SSTV2_SCREENREZ")));
961
962 switch(screenRezEnv) {
963 case 512256:
964 screenRez = GR_RESOLUTION_512x256;
965 break;
966 case 512:
967 screenRez = GR_RESOLUTION_512x384;
968 break;
969 case 640400:
970 screenRez = GR_RESOLUTION_640x400;
971 break;
972 case 800:
973 screenRez = GR_RESOLUTION_800x600;
974 break;
975 case 856:
976 screenRez = GR_RESOLUTION_856x480;
977 break;
978 case 960:
979 screenRez = GR_RESOLUTION_960x720;
980 break;
981 case 1024:
982 screenRez = GR_RESOLUTION_1024x768;
983 break;
984 default:
985 screenRez = GR_RESOLUTION_640x480;
986 break;
987 }
988 }
989
990 // Override Screen resolution with environment variables
991 if(GETENV(("SSTV2_SCREENREFRESH"))) {
992 FxU32 refreshRateEnv = ATOI(GETENV(("SSTV2_SCREENREFRESH")));
993
994 switch(refreshRateEnv) {
995 case 75:
996 refreshRate = GR_REFRESH_75Hz;
997 break;
998 case 85:
999 refreshRate = GR_REFRESH_85Hz;
1000 break;
1001 case 120:
1002 refreshRate = GR_REFRESH_120Hz;
1003 break;
1004 default:
1005 refreshRate = GR_REFRESH_60Hz;
1006 break;
1007 }
1008 }
1009
1010 switch(screenRez) {
1011
1012 case(GR_RESOLUTION_512x256):
1013 return(&SST_VREZ_512X256_60);
1014 break;
1015
1016 case(GR_RESOLUTION_512x384):
1017
1018 if( GETENV( ("SSTV2_REFRESH_512x384") ) )
1019 refreshRate = sst1InitConvertRefreshRate( ATOI( GETENV( ("SSTV2_REFRESH_512x384") ) ) );
1020
1021 if(refreshRate == GR_REFRESH_120Hz)
1022 return(&SST_VREZ_512X384_120);
1023 else if(refreshRate == GR_REFRESH_85Hz) {
1024 if(sst1CurrentBoard->sliDetected)
1025 return(&SST_VREZ_512X384_85_NOSCANDOUBLE);
1026 else
1027 return(&SST_VREZ_512X384_85);
1028 } else if(refreshRate == GR_REFRESH_75Hz) {
1029 if(sst1CurrentBoard->sliDetected)
1030 return(&SST_VREZ_512X384_75_NOSCANDOUBLE);
1031 else
1032 return(&SST_VREZ_512X384_75);
1033 } else {
1034 if(sst1CurrentBoard->sliDetected)
1035 return(&SST_VREZ_512X384_72);
1036 else
1037 return(&SST_VREZ_512X384_60);
1038 }
1039 break;
1040
1041 case(GR_RESOLUTION_640x400):
1042
1043 if( GETENV( ("SSTV2_REFRESH_640x400") ) )
1044 refreshRate = sst1InitConvertRefreshRate( ATOI( GETENV( ("SSTV2_REFRESH_640x400") ) ) );
1045
1046 if(refreshRate == GR_REFRESH_120Hz)
1047 return(&SST_VREZ_640X400_120);
1048 else if(refreshRate == GR_REFRESH_85Hz)
1049 return(&SST_VREZ_640X400_85);
1050 else if(refreshRate == GR_REFRESH_75Hz)
1051 return(&SST_VREZ_640X400_75);
1052 else
1053 return(&SST_VREZ_640X400_70);
1054 break;
1055
1056 case(GR_RESOLUTION_640x480):
1057
1058 if( GETENV( ("SSTV2_REFRESH_640x480") ) )
1059 refreshRate = sst1InitConvertRefreshRate( ATOI( GETENV( ("SSTV2_REFRESH_640x480") ) ) );
1060
1061 if(refreshRate == GR_REFRESH_120Hz)
1062 return(&SST_VREZ_640X480_120);
1063 else if(refreshRate == GR_REFRESH_85Hz)
1064 return(&SST_VREZ_640X480_85);
1065 else if(refreshRate == GR_REFRESH_75Hz)
1066 return(&SST_VREZ_640X480_75);
1067 else
1068 return(&SST_VREZ_640X480_60);
1069 break;
1070
1071 case(GR_RESOLUTION_800x600):
1072
1073 if( GETENV( ("SSTV2_REFRESH_800x600") ) )
1074 refreshRate = sst1InitConvertRefreshRate( ATOI( GETENV( ("SSTV2_REFRESH_800x600") ) ) );
1075
1076 if(refreshRate == GR_REFRESH_120Hz)
1077 return(&SST_VREZ_800X600_120);
1078 else if(refreshRate == GR_REFRESH_85Hz)
1079 return(&SST_VREZ_800X600_85);
1080 else if(refreshRate == GR_REFRESH_75Hz)
1081 return(&SST_VREZ_800X600_75);
1082 else
1083 return(&SST_VREZ_800X600_60);
1084 break;
1085
1086 case(GR_RESOLUTION_856x480):
1087 return(&SST_VREZ_856X480_60);
1088 break;
1089
1090 case(GR_RESOLUTION_960x720):
1091 if( GETENV( ("SSTV2_REFRESH_960x720") ) )
1092 refreshRate = sst1InitConvertRefreshRate( ATOI( GETENV( ("SSTV2_REFRESH_960x720") ) ) );
1093
1094 if(refreshRate == GR_REFRESH_85Hz)
1095 return(&SST_VREZ_960X720_85);
1096 else if(refreshRate == GR_REFRESH_75Hz)
1097 return(&SST_VREZ_960X720_75);
1098 else
1099 return(&SST_VREZ_960X720_60);
1100 break;
1101
1102 case(GR_RESOLUTION_1024x768):
1103
1104 if( GETENV( ("SSTV2_REFRESH_1024x768") ) )
1105 refreshRate = sst1InitConvertRefreshRate( ATOI( GETENV( ("SSTV2_REFRESH_1024x768") ) ) );
1106
1107 if(refreshRate == GR_REFRESH_85Hz)
1108 return(&SST_VREZ_1024X768_85);
1109 else if(refreshRate == GR_REFRESH_75Hz)
1110 return(&SST_VREZ_1024X768_75);
1111 else
1112 return(&SST_VREZ_1024X768_60);
1113 break;
1114
1115 default:
1116 INIT_PRINTF(("sst1InitFindVideoTimingStruc(): Unsupported Resolution...\n"));
1117 return((sst1VideoTimingStruct *) NULL);
1118 break;
1119 }
1120}
1121
1122FxU32 sst1InitConvertRefreshRate( FxU32 refreshRate )
1123{
1124 switch( refreshRate )
1125 {
1126 case 75:
1127 return( GR_REFRESH_75Hz );
1128 case 85:
1129 return( GR_REFRESH_85Hz );
1130 case 120:
1131 return( GR_REFRESH_120Hz );
1132 default:
1133 return( GR_REFRESH_60Hz );
1134 }
1135}
1136
1137/*
1138**
1139** sst1InitMonitorDetect()
1140** Detect whether or not a monitor is connected to the board
1141**
1142*/
1143
1144FX_EXPORT FxBool FX_CSTYLE sst1InitMonitorDetect(FxU32 *sstbase)
1145{
1146 SstRegs *sst = (SstRegs *) sstbase;
1147 FxU32 gammaArray[32];
1148 FxU32 j, k;
1149 FxU32 gammaCorrectConstant = 0x5c;
1150
1151 if(!sst)
1152 return(FXFALSE);
1153
1154 if(sst1InitCheckBoard(sstbase) == FXFALSE)
1155 return(FXFALSE);
1156
1157 if(GETENV(("SSTV2_MDETECT_CONST"))) {
1158 SSCANF(GETENV(("SSTV2_MDETECT_CONST")), "%i", &gammaCorrectConstant);
1159 INIT_PRINTF(("sst1InitMonitorDetect(): Using value 0x%x for constant gamma value...\n", gammaCorrectConstant));
1160 }
1161
1162 // Force gamma to always output clearColor value...
1163 for(j=0; j<32; j++)
1164 gammaArray[j] = gammaCorrectConstant;
1165 //gammaArray[j] = 0xff; // 0xff never detects monitor...
1166 //gammaArray[j] = 0x0; // 0x0 always detects monitor...
1167 sst1InitGammaTable(sstbase, 32, gammaArray, gammaArray, gammaArray);
1168
1169 // Wait for for monitor to sync...
1170 sst1InitIdle(sstbase);
1171 for(k=0; k<(sst1CurrentBoard->fbiVideoRefresh>>2); k++) {
1172 // Wait for inactive vsync...
1173 do {
1174 j = IGET(sst->status);
1175 } while(!(j & SST_VRETRACE));
1176
1177 // Wait for active vsync
1178 do {
1179 j = IGET(sst->status);
1180 } while(j & SST_VRETRACE);
1181 }
1182
1183 while(1) {
1184 FxU32 firstInit6 = IGET(sst->fbiInit6) & SST_GPIO_3;
1185 FxU32 hvRetrace = IGET(sst->hvRetrace);
1186 FxU32 vBeam = hvRetrace & 0x1fff;
1187 FxU32 hBeam = (hvRetrace>>16) & 0x7ff;
1188 FxU32 secondInit6 = IGET(sst->fbiInit6) & SST_GPIO_3;
1189
1190 if((vBeam > (sst1CurrentBoard->fbiVideoStruct->vBackPorch + 10)) &&
1191 (vBeam < (sst1CurrentBoard->fbiVideoStruct->vBackPorch +
1192 sst1CurrentBoard->fbiVideoHeight - 10)) &&
1193 (hBeam > (sst1CurrentBoard->fbiVideoStruct->hBackPorch +
1194 sst1CurrentBoard->fbiVideoStruct->hSyncOn + 10)) &&
1195 (hBeam < (sst1CurrentBoard->fbiVideoStruct->hBackPorch +
1196 sst1CurrentBoard->fbiVideoStruct->hSyncOn +
1197 sst1CurrentBoard->fbiVideoWidth - 10))) {
1198 if(firstInit6 == secondInit6) {
1199 if(firstInit6)
1200 sst1CurrentBoard->monitorDetected = 1;
1201 else
1202 sst1CurrentBoard->monitorDetected = 0;
1203 break;
1204 }
1205 }
1206 }
1207
1208
1209 // Override with environment variable...
1210 if(GETENV(("SSTV2_MDETECT")))
1211 sst1CurrentBoard->monitorDetected =
1212 (ATOI(GETENV(("SSTV2_MDETECT")))) ? 1 : 0;
1213
1214 return(FXTRUE);
1215}
1216
1217/*
1218**
1219** sst1InitSetClkDelays():
1220** Calculate FT, TF0, and TF1 clock delay values...
1221**
1222*/
1223FX_EXPORT FxBool FX_CSTYLE sst1InitSetClkDelays(FxU32 *sstbase)
1224{
1225 FxU32 tf0_clkdel, tf1_clkdel, tf2_clkdel, ft_clkdel;
1226 SstRegs *sst = (SstRegs *) sstbase;
1227
1228 if(sst1CurrentBoard->fbiBoardID == 0x3) {
1229 // Early 4-layer 4220 board -- Runs at 83 MHz by default...
1230 if(sst1CurrentBoard->fbiGrxClkFreq <= 80) {
1231 ft_clkdel = 0x5;
1232 tf0_clkdel = 0x7;
1233 tf1_clkdel = 0x8;
1234 tf2_clkdel = 0x8;
1235 } else {
1236 ft_clkdel = 0x4;
1237 tf0_clkdel = 0x6;
1238 tf1_clkdel = 0x7;
1239 tf2_clkdel = 0x7;
1240 }
1241 goto setDelays;
1242 }
1243
1244 if(GETENV(("SSTV2_IGNORE_CLKDELAYS"))) {
1245 INIT_PRINTF(("sst1InitSetClkDelays() WARNING: Bypassing dynamic clock delay detection...\n"));
1246 ft_clkdel = 0x4;
1247 tf0_clkdel = 0x6;
1248 tf1_clkdel = 0x6;
1249 tf2_clkdel = 0x6;
1250 goto setDelays;
1251 }
1252
1253 // FT Clock Delay...
1254 if(sst1CurrentBoard->fbiNandTree < 5000)
1255 // Account for very slow processes...
1256 ft_clkdel = 0x3;
1257 else
1258 ft_clkdel = 0x4;
1259
1260 // TF2 Clock Delay...
1261 if(sst1CurrentBoard->numberTmus > 2) {
1262 if(sst1InitCalcTClkDelay(sstbase, 2, 11) == FXTRUE)
1263 // Test failed. Fast process TMUs...
1264 tf2_clkdel = 0x7;
1265 else
1266 tf2_clkdel = 0x6;
1267 } else
1268 tf2_clkdel = 0x6;
1269
1270 // TF1 Clock Delay...
1271 if(sst1CurrentBoard->numberTmus > 1) {
1272 if(sst1InitCalcTClkDelay(sstbase, 1, 11) == FXTRUE)
1273 // Test failed. Fast process TMUs...
1274 tf1_clkdel = 0x7;
1275 else
1276 tf1_clkdel = 0x6;
1277 } else
1278 tf1_clkdel = 0x6;
1279
1280 // Reset FBI & TMU, and put TF1 clock delay value back to default...
1281 if(sst1InitResetTmus(sstbase) == FXFALSE) {
1282 INIT_PRINTF(("sst1InitSetClkDelays() ERROR(1): Could not reset TMUs...\n"));
1283 return(FXFALSE);
1284 }
1285
1286 // TF0 Clock Delay...
1287 if(sst1InitCalcTClkDelay(sstbase, 0, 9) == FXTRUE)
1288 // Test failed. Fast process TMUs...
1289 tf0_clkdel = 0x7;
1290 else
1291 tf0_clkdel = 0x6;
1292
1293 // Reset FBI & TMU, and put TF0 clock delay value back to default...
1294 if(sst1InitResetTmus(sstbase) == FXFALSE) {
1295 INIT_PRINTF(("sst1InitSetClkDelays() ERROR(2): Could not reset TMUs...\n"));
1296 return(FXFALSE);
1297 }
1298
1299 // Adjust for lower frequencies...
1300 if(sst1CurrentBoard->fbiGrxClkFreq < 80) {
1301 ft_clkdel++;
1302 tf0_clkdel++;
1303 tf1_clkdel++;
1304 tf2_clkdel++;
1305 }
1306
1307setDelays:
1308
1309 // Override with environment variables
1310 if(GETENV(("SSTV2_FT_CLKDEL")))
1311 SSCANF(GETENV(("SSTV2_FT_CLKDEL")), "%i", &ft_clkdel);
1312 if(GETENV(("SSTV2_TF0_CLKDEL")))
1313 SSCANF(GETENV(("SSTV2_TF0_CLKDEL")), "%i", &tf0_clkdel);
1314 if(GETENV(("SSTV2_TF1_CLKDEL")))
1315 SSCANF(GETENV(("SSTV2_TF1_CLKDEL")), "%i", &tf1_clkdel);
1316 if(GETENV(("SSTV2_TF2_CLKDEL")))
1317 SSCANF(GETENV(("SSTV2_TF2_CLKDEL")), "%i", &tf2_clkdel);
1318
1319 INIT_PRINTF(("sst1InitSetClkDelays(): Setting FBI-to-TREX clock delay to 0x%x...\n", ft_clkdel));
1320 INIT_PRINTF(("sst1InitSetClkDelays(): Setting TREX#0 TREX-to-FBI clock delay to 0x%x\n",
1321 tf0_clkdel));
1322 INIT_PRINTF(("sst1InitSetClkDelays(): Setting TREX#1 TREX-to-FBI clock delay to 0x%x\n",
1323 tf1_clkdel));
1324 INIT_PRINTF(("sst1InitSetClkDelays(): Setting TREX#2 TREX-to-FBI clock delay to 0x%x\n",
1325 tf2_clkdel));
1326
1327 ISET(sst->fbiInit3, (IGET(sst->fbiInit3) & ~SST_FT_CLK_DEL_ADJ) |
1328 (ft_clkdel << SST_FT_CLK_DEL_ADJ_SHIFT));
1329 sst1InitIdleFBINoNOP(sstbase);
1330
1331 sst1CurrentBoard->tmuInit1[0] = (sst1CurrentBoard->tmuInit1[0] &
1332 ~SST_TEX_TF_CLK_DEL_ADJ) | (tf0_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
1333 sst1CurrentBoard->tmuInit1[1] = (sst1CurrentBoard->tmuInit1[1] &
1334 ~SST_TEX_TF_CLK_DEL_ADJ) | (tf1_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
1335 sst1CurrentBoard->tmuInit1[2] = (sst1CurrentBoard->tmuInit1[2] &
1336 ~SST_TEX_TF_CLK_DEL_ADJ) | (tf2_clkdel<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT);
1337
1338 // Calling sst1InitResetTmus() will put the new trexinit values in the
1339 // TMUs, as well as reset FBI and TMU...
1340 if(sst1InitResetTmus(sstbase) == FXFALSE) {
1341 INIT_PRINTF(("sst1InitSetClkDelays() ERROR(3): Could not reset TMUs...\n"));
1342 return(FXFALSE);
1343 }
1344 return(FXTRUE);
1345}
1346
1347#pragma optimize ("",on)
Note: See TracBrowser for help on using the repository browser.