1 | /*-*-c++-*-*/
|
---|
2 | /* $Id: util.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 | ** Utility routines for SST-1 Initialization code
|
---|
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 | #include <sst1vid.h>
|
---|
42 | #include <sst1init.h>
|
---|
43 |
|
---|
44 | /*
|
---|
45 | ** sst1InitIdle():
|
---|
46 | ** Return idle condition of SST-1
|
---|
47 | **
|
---|
48 | ** Returns:
|
---|
49 | ** FXTRUE if SST-1 is idle (fifos are empty, graphics engines are idle)
|
---|
50 | ** FXFALSE if SST-1 has not been mapped
|
---|
51 | **
|
---|
52 | */
|
---|
53 | FX_EXPORT FxBool FX_CSTYLE sst1InitIdle(FxU32 *sstbase)
|
---|
54 | {
|
---|
55 | if(!sstbase)
|
---|
56 | return(FXFALSE);
|
---|
57 |
|
---|
58 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
59 | return(FXFALSE);
|
---|
60 |
|
---|
61 | if(!initIdleEnabled)
|
---|
62 | return(FXTRUE);
|
---|
63 |
|
---|
64 | if(sst1CurrentBoard->fbiLfbLocked) {
|
---|
65 | if(sst1CurrentBoard->sliSlaveVirtAddr == (FxU32 *) NULL)
|
---|
66 | // SLI not enabled...
|
---|
67 | sst1InitPciFifoIdleLoop(sstbase);
|
---|
68 | else {
|
---|
69 | // Check idle for Master...
|
---|
70 | sst1InitPciFifoIdleLoop(sstbase);
|
---|
71 | // Check idle for Slave...
|
---|
72 | sst1InitPciFifoIdleLoop(sst1CurrentBoard->sliSlaveVirtAddr);
|
---|
73 | }
|
---|
74 | } else {
|
---|
75 | if(sst1CurrentBoard->sliSlaveVirtAddr == (FxU32 *) NULL)
|
---|
76 | // SLI not enabled...
|
---|
77 | sst1InitIdleLoop(sstbase, FXTRUE);
|
---|
78 | else {
|
---|
79 | // Check idle for Master...
|
---|
80 | sst1InitIdleLoop(sstbase, FXTRUE);
|
---|
81 |
|
---|
82 | // Check idle for Slave...
|
---|
83 | // Note that the Slave does not need another NOP command, because
|
---|
84 | // it will snoop the NOP command sent to the Master above.
|
---|
85 | // Sending a NOP command to the Slave also confuses the callback
|
---|
86 | // write routines for the command fifo which are not setup to
|
---|
87 | // handle any other base addresses other than the Master's...
|
---|
88 | sst1InitIdleLoop(sst1CurrentBoard->sliSlaveVirtAddr, FXFALSE);
|
---|
89 | }
|
---|
90 | }
|
---|
91 | return(FXTRUE);
|
---|
92 | }
|
---|
93 |
|
---|
94 | FX_EXPORT FxBool FX_CSTYLE sst1InitIdleWithTimeout(FxU32 *sstbase,
|
---|
95 | FxU32 timeout)
|
---|
96 | {
|
---|
97 | int retVal;
|
---|
98 |
|
---|
99 | if(!sstbase)
|
---|
100 | return(FXFALSE);
|
---|
101 |
|
---|
102 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
103 | return(FXFALSE);
|
---|
104 |
|
---|
105 | if(sst1CurrentBoard->sliSlaveVirtAddr == (FxU32 *) NULL)
|
---|
106 | // SLI not enabled...
|
---|
107 | retVal = sst1InitIdleWithTimeoutLoop(sstbase, FXTRUE, timeout);
|
---|
108 | else {
|
---|
109 | // Check idle for Master...
|
---|
110 | if(!sst1InitIdleWithTimeoutLoop(sstbase, FXTRUE, timeout))
|
---|
111 | return(FXFALSE);
|
---|
112 |
|
---|
113 | // Check idle for Slave...
|
---|
114 | // Note that the Slave does not need another NOP command, because
|
---|
115 | // it will snoop the NOP command sent to the Master above.
|
---|
116 | // Sending a NOP command to the Slave also confuses the callback
|
---|
117 | // write routines for the command fifo which are not setup to
|
---|
118 | // handle any other base addresses other than the Master's...
|
---|
119 | retVal = sst1InitIdleWithTimeoutLoop(sst1CurrentBoard->sliSlaveVirtAddr,
|
---|
120 | FXFALSE, timeout);
|
---|
121 | }
|
---|
122 | if(!retVal)
|
---|
123 | return(FXFALSE);
|
---|
124 | else
|
---|
125 | return(FXTRUE);
|
---|
126 | }
|
---|
127 |
|
---|
128 | FX_EXPORT FxBool FX_CSTYLE sst1InitIdleNoNOP(FxU32 *sstbase)
|
---|
129 | {
|
---|
130 | if(!sstbase)
|
---|
131 | return(FXFALSE);
|
---|
132 |
|
---|
133 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
134 | return(FXFALSE);
|
---|
135 |
|
---|
136 | if(!initIdleEnabled)
|
---|
137 | return(FXTRUE);
|
---|
138 |
|
---|
139 | if(sst1CurrentBoard->fbiLfbLocked) {
|
---|
140 | if(sst1CurrentBoard->sliSlaveVirtAddr == (FxU32 *) NULL)
|
---|
141 | // SLI not enabled...
|
---|
142 | sst1InitPciFifoIdleLoop(sstbase);
|
---|
143 | else {
|
---|
144 | // Check idle for Master...
|
---|
145 | sst1InitPciFifoIdleLoop(sstbase);
|
---|
146 | // Check idle for Slave...
|
---|
147 | sst1InitPciFifoIdleLoop(sst1CurrentBoard->sliSlaveVirtAddr);
|
---|
148 | }
|
---|
149 | } else {
|
---|
150 | if(sst1CurrentBoard->sliSlaveVirtAddr == (FxU32 *) NULL)
|
---|
151 | // SLI not enabled...
|
---|
152 | sst1InitIdleLoop(sstbase, FXFALSE);
|
---|
153 | else {
|
---|
154 | // Check idle for Master...
|
---|
155 | sst1InitIdleLoop(sstbase, FXFALSE);
|
---|
156 | // Check idle for Slave...
|
---|
157 | sst1InitIdleLoop(sst1CurrentBoard->sliSlaveVirtAddr, FXFALSE);
|
---|
158 | }
|
---|
159 | }
|
---|
160 | return(FXTRUE);
|
---|
161 | }
|
---|
162 |
|
---|
163 | void sst1InitIdleLoop(FxU32 *sstbase, FxBool issueNOP)
|
---|
164 | {
|
---|
165 | FxU32 cntr;
|
---|
166 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
167 |
|
---|
168 | if(issueNOP)
|
---|
169 | ISET(sst->nopCMD, 0x0);
|
---|
170 |
|
---|
171 | cntr = 0;
|
---|
172 | while(1) {
|
---|
173 | if(!(sst1InitReturnStatus(sstbase) & SST_BUSY)) {
|
---|
174 | if(++cntr >= 3)
|
---|
175 | break;
|
---|
176 | } else
|
---|
177 | cntr = 0;
|
---|
178 | }
|
---|
179 | }
|
---|
180 |
|
---|
181 | int sst1InitIdleWithTimeoutLoop(FxU32 *sstbase, FxBool issueNOP, FxU32 timeout)
|
---|
182 | {
|
---|
183 | FxU32 cntr, loop;
|
---|
184 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
185 |
|
---|
186 | if(issueNOP)
|
---|
187 | ISET(sst->nopCMD, 0x0);
|
---|
188 |
|
---|
189 | cntr = loop = 0;
|
---|
190 | while(++loop < timeout) {
|
---|
191 | if(!(sst1InitReturnStatus(sstbase) & SST_BUSY)) {
|
---|
192 | if(++cntr >= 3)
|
---|
193 | break;
|
---|
194 | } else
|
---|
195 | cntr = 0;
|
---|
196 | }
|
---|
197 | if(loop >= timeout)
|
---|
198 | return(0);
|
---|
199 | else
|
---|
200 | return(1);
|
---|
201 | }
|
---|
202 |
|
---|
203 | void sst1InitPciFifoIdleLoop(FxU32 *sstbase)
|
---|
204 | {
|
---|
205 | FxU32 cntr;
|
---|
206 |
|
---|
207 | cntr = 0;
|
---|
208 | while(1) {
|
---|
209 | if(((sst1InitReturnStatus(sstbase) & SST_FIFOLEVEL)) == 0x3f) {
|
---|
210 | // Since sst1InitPciFifoIdleLoop is only called when we're trying
|
---|
211 | // to "fake" idle during lfb locks, wait for 6 passes to give the
|
---|
212 | // hardware time to drain
|
---|
213 | if(++cntr >= 6)
|
---|
214 | break;
|
---|
215 | } else
|
---|
216 | cntr = 0;
|
---|
217 | }
|
---|
218 | }
|
---|
219 |
|
---|
220 | /*
|
---|
221 | ** sst1InitIdleFBI():
|
---|
222 | ** Return idle condition of FBI (ignoring idle status of TMU)
|
---|
223 | **
|
---|
224 | ** Returns:
|
---|
225 | ** FXTRUE if FBI is idle (fifos are empty, graphics engines are idle)
|
---|
226 | ** FXFALSE if FBI has not been mapped
|
---|
227 | **
|
---|
228 | */
|
---|
229 | FX_EXPORT FxBool FX_CSTYLE sst1InitIdleFBI(FxU32 *sstbase)
|
---|
230 | {
|
---|
231 | FxU32 cntr;
|
---|
232 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
233 |
|
---|
234 | if(!sst)
|
---|
235 | return(FXFALSE);
|
---|
236 |
|
---|
237 | ISET(sst->nopCMD, 0x0);
|
---|
238 | cntr = 0;
|
---|
239 | while(1) {
|
---|
240 | if(!(sst1InitReturnStatus(sstbase) & SST_FBI_BUSY)) {
|
---|
241 | if(++cntr >= 3)
|
---|
242 | break;
|
---|
243 | } else
|
---|
244 | cntr = 0;
|
---|
245 | }
|
---|
246 | return(FXTRUE);
|
---|
247 | }
|
---|
248 |
|
---|
249 | /*
|
---|
250 | ** sst1InitIdleFBINoNOP():
|
---|
251 | ** Return idle condition of FBI (ignoring idle status of TMU)
|
---|
252 | ** sst1InitIdleFBINoNOP() differs from sst1InitIdleFBI() in that no NOP command
|
---|
253 | ** is issued to flush the graphics pipeline.
|
---|
254 | **
|
---|
255 | ** Returns:
|
---|
256 | ** FXTRUE if FBI is idle (fifos are empty, graphics engines are idle)
|
---|
257 | ** FXFALSE if FBI has not been mapped
|
---|
258 | **
|
---|
259 | */
|
---|
260 | FX_EXPORT FxBool FX_CSTYLE sst1InitIdleFBINoNOP(FxU32 *sstbase)
|
---|
261 | {
|
---|
262 | FxU32 cntr;
|
---|
263 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
264 |
|
---|
265 | if(!sst)
|
---|
266 | return(FXFALSE);
|
---|
267 |
|
---|
268 | // ISET(sst->nopCMD, 0x0);
|
---|
269 | cntr = 0;
|
---|
270 | while(1) {
|
---|
271 | if(!(sst1InitReturnStatus(sstbase) & SST_FBI_BUSY)) {
|
---|
272 | if(++cntr > 5)
|
---|
273 | break;
|
---|
274 | } else
|
---|
275 | cntr = 0;
|
---|
276 | }
|
---|
277 | return(FXTRUE);
|
---|
278 | }
|
---|
279 |
|
---|
280 | // Included so compiler doesn't optimize out loop code waiting on status bits
|
---|
281 | FX_EXPORT FxU32 FX_CSTYLE sst1InitReturnStatus(FxU32 *sstbase)
|
---|
282 | {
|
---|
283 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
284 |
|
---|
285 | return(IGET(sst->status));
|
---|
286 | }
|
---|
287 |
|
---|
288 |
|
---|
289 | /*
|
---|
290 | ** sst1InitClearSwapPending():
|
---|
291 | ** Clear any swaps pending in the status register
|
---|
292 | ** NOTE: The video unit of FBI must be initialized before calling this routine
|
---|
293 | **
|
---|
294 | ** Returns:
|
---|
295 | ** FXTRUE
|
---|
296 | **
|
---|
297 | */
|
---|
298 | FX_ENTRY FxBool FX_CALL sst1InitClearSwapPending(FxU32 *sstbase)
|
---|
299 | {
|
---|
300 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
301 | FxU32 displayedBuffer, i;
|
---|
302 |
|
---|
303 | INIT_PRINTF(("sst1InitClearSwapPending() WARNING: Clearing pending swapbufferCMDs...\n"));
|
---|
304 |
|
---|
305 | sst1InitIdle(sstbase);
|
---|
306 | displayedBuffer =
|
---|
307 | (IGET(sst->status) & SST_DISPLAYED_BUFFER) >>
|
---|
308 | SST_DISPLAYED_BUFFER_SHIFT;
|
---|
309 |
|
---|
310 | // Wait until vsync is inactive to guarantee that swaps queue in the
|
---|
311 | // PCI fifo properly
|
---|
312 | while(!(IGET(sst->status) & SST_VRETRACE) ||
|
---|
313 | ((IGET(sst->vRetrace) & 0xfff) > 100) || ((IGET(sst->vRetrace) & 0xfff)
|
---|
314 | < 10))
|
---|
315 | ;
|
---|
316 |
|
---|
317 | // First swap syncs to Vsync...Subsequent ones do not...
|
---|
318 | ISET(sst->swapbufferCMD, 0x1);
|
---|
319 | ISET(sst->nopCMD, 0x0);
|
---|
320 | for(i=0; i<17; i++) {
|
---|
321 | ISET(sst->swapbufferCMD, 0x0);
|
---|
322 | ISET(sst->nopCMD, 0x0);
|
---|
323 | }
|
---|
324 | if(displayedBuffer) {
|
---|
325 | ISET(sst->swapbufferCMD, 0x0);
|
---|
326 | ISET(sst->nopCMD, 0x0);
|
---|
327 | }
|
---|
328 | sst1InitIdle(sstbase);
|
---|
329 |
|
---|
330 | return(FXTRUE);
|
---|
331 | }
|
---|
332 |
|
---|
333 | /*
|
---|
334 | ** sst1InitVgaPassCtrl():
|
---|
335 | ** Control VGA passthrough setting
|
---|
336 | **
|
---|
337 | **
|
---|
338 | */
|
---|
339 | FX_EXPORT FxBool FX_CSTYLE sst1InitVgaPassCtrl(FxU32 *sstbase, FxU32 enable)
|
---|
340 | {
|
---|
341 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
342 |
|
---|
343 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
344 | return(FXFALSE);
|
---|
345 |
|
---|
346 | if(enable) {
|
---|
347 | // VGA controls monitor
|
---|
348 | ISET(sst->fbiInit0, (IGET(sst->fbiInit0) & ~SST_EN_VGA_PASSTHRU) |
|
---|
349 | sst1CurrentBoard->vgaPassthruEnable);
|
---|
350 | ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_BLANK_EN);
|
---|
351 | } else {
|
---|
352 | // SST-1 controls monitor
|
---|
353 | ISET(sst->fbiInit0, (IGET(sst->fbiInit0) & ~SST_EN_VGA_PASSTHRU) |
|
---|
354 | sst1CurrentBoard->vgaPassthruDisable);
|
---|
355 | ISET(sst->fbiInit1, IGET(sst->fbiInit1) & ~SST_VIDEO_BLANK_EN);
|
---|
356 | }
|
---|
357 |
|
---|
358 | return(FXTRUE);
|
---|
359 | }
|
---|
360 |
|
---|
361 | /*
|
---|
362 | ** sst1InitResetTmus():
|
---|
363 | ** Reset TMUs
|
---|
364 | **
|
---|
365 | */
|
---|
366 | FX_EXPORT FxBool FX_CSTYLE sst1InitResetTmus(FxU32 *sstbase)
|
---|
367 | {
|
---|
368 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
369 | FxU32 fbiInit3, i, cntr = 0;
|
---|
370 | int j;
|
---|
371 | FxU32 allowTexturing = (GETENV(("SSTV2_TEXMAP_DISABLE"))) ? 0 : 1;
|
---|
372 |
|
---|
373 | if(!sst)
|
---|
374 | return(FXFALSE);
|
---|
375 |
|
---|
376 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
377 | return(FXFALSE);
|
---|
378 |
|
---|
379 | fbiInit3 = IGET(sst->fbiInit3);
|
---|
380 | while(++cntr < 6) {
|
---|
381 | // Ignore stalls on FT Bus
|
---|
382 | ISET(sst->fbiInit3, fbiInit3 | SST_TEXMAP_DISABLE);
|
---|
383 | for(i=0; i<3; i++) sst1InitReturnStatus(sstbase);
|
---|
384 |
|
---|
385 | // Set Default initialization values for all TMUs...
|
---|
386 | for(j=0; j<3; j++) {
|
---|
387 | ISET(SST_TREX(sst,j)->trexInit0, sst1CurrentBoard->tmuInit0[j]);
|
---|
388 | for(i=0; i<3; i++) sst1InitReturnStatus(sstbase);
|
---|
389 | }
|
---|
390 | for(j=0; j<3; j++) {
|
---|
391 | ISET(SST_TREX(sst,j)->trexInit1, sst1CurrentBoard->tmuInit1[j]);
|
---|
392 | for(i=0; i<3; i++) sst1InitReturnStatus(sstbase);
|
---|
393 | }
|
---|
394 |
|
---|
395 | // Reset TMU FIFOs and graphics core for all TMUs...
|
---|
396 | for(j=0; j<3; j++) {
|
---|
397 | ISET(SST_TREX(sst,j)->trexInit1, sst1CurrentBoard->tmuInit1[j] |
|
---|
398 | SST_TEX_RESET_FIFO | SST_TEX_RESET_GRX);
|
---|
399 | for(i=0; i<3; i++) sst1InitReturnStatus(sstbase);
|
---|
400 | }
|
---|
401 | // Allow reset to propogate
|
---|
402 | for(i=0; i<10; i++) sst1InitReturnStatus(sstbase);
|
---|
403 |
|
---|
404 | // Deassert resets. Start with upstream TMU and work down...
|
---|
405 | for(j=2; j >= 0; j--) {
|
---|
406 | ISET(SST_TREX(sst,j)->trexInit1, sst1CurrentBoard->tmuInit1[j]);
|
---|
407 | // Allow unreset to propogate
|
---|
408 | for(i=0; i<10; i++) sst1InitReturnStatus(sstbase);
|
---|
409 | }
|
---|
410 |
|
---|
411 | // Reset in the downstream TMU may cause glitches in FBI's TF FIFO
|
---|
412 | // Waiting for Idle in FBI will not stall on something in the TF FIFO,
|
---|
413 | // as the TF FIFO empty signal is not part of FBI's "busy" bit
|
---|
414 | sst1InitIdleFBI(sstbase);
|
---|
415 | sst1InitResetFbi(sstbase);
|
---|
416 |
|
---|
417 | if(allowTexturing) {
|
---|
418 | ISET(sst->fbiInit3, fbiInit3 & ~SST_TEXMAP_DISABLE);
|
---|
419 | for(i=0; i<3; i++) sst1InitReturnStatus(sstbase);
|
---|
420 | }
|
---|
421 |
|
---|
422 | if(sst1InitReturnStatus(sstbase) & SST_TREX_BUSY)
|
---|
423 | INIT_PRINTF(("sst1InitResetTmus(): Could not reset TMUs. Retry #%d...\n", cntr));
|
---|
424 | else
|
---|
425 | break;
|
---|
426 | }
|
---|
427 | if(cntr == 6) {
|
---|
428 | INIT_PRINTF(("sst1InitResetTmus(): Could not reset TMUs...\n"));
|
---|
429 | return(FXFALSE);
|
---|
430 | }
|
---|
431 |
|
---|
432 | // Fix problem where first Texture downloads to TMU weren't being
|
---|
433 | // received properly
|
---|
434 | ISET(*(long *) (0xf00000 + (long) sstbase), 0xdeadbeef);
|
---|
435 | sst1InitIdle(sstbase);
|
---|
436 |
|
---|
437 | return(FXTRUE);
|
---|
438 | }
|
---|
439 |
|
---|
440 | /*
|
---|
441 | ** sst1InitResetFbi():
|
---|
442 | ** Reset FBI graphics engine and frontend PCI Fifo...
|
---|
443 | **
|
---|
444 | */
|
---|
445 | FX_EXPORT FxBool FX_CSTYLE sst1InitResetFbi(FxU32 *sstbase)
|
---|
446 | {
|
---|
447 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
448 |
|
---|
449 | ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_GRX_RESET |
|
---|
450 | SST_PCI_FIFO_RESET);
|
---|
451 | sst1InitReturnStatus(sstbase);
|
---|
452 | sst1InitReturnStatus(sstbase);
|
---|
453 | sst1InitReturnStatus(sstbase);
|
---|
454 | ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_PCI_FIFO_RESET);
|
---|
455 | sst1InitReturnStatus(sstbase);
|
---|
456 | sst1InitReturnStatus(sstbase);
|
---|
457 | sst1InitReturnStatus(sstbase);
|
---|
458 | ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_GRX_RESET);
|
---|
459 | sst1InitReturnStatus(sstbase);
|
---|
460 | sst1InitReturnStatus(sstbase);
|
---|
461 | sst1InitReturnStatus(sstbase);
|
---|
462 |
|
---|
463 | return(FXTRUE);
|
---|
464 | }
|
---|
465 |
|
---|
466 | #if SET_BSWAP
|
---|
467 | #if __POWERPC__ && defined(__MWERKS__)
|
---|
468 | #define GET(s) __lwbrx(s, 0 )
|
---|
469 | #define SET(d, s) __stwbrx((s), (d), 0);
|
---|
470 | #else /* !__MWERKS__ */
|
---|
471 | #error "Define byte swapped macros for GET/SET"
|
---|
472 | #endif /* !__MWERKS__ */
|
---|
473 | #else /* !SET_BSWAP */
|
---|
474 | #ifdef GET
|
---|
475 | #undef GET
|
---|
476 | #endif
|
---|
477 | #ifdef SET
|
---|
478 | #undef SET
|
---|
479 | #endif
|
---|
480 | #define GET(s) (*s)
|
---|
481 | #define SET(d, s) ((*d) = s)
|
---|
482 | #endif /* !SET_BSWAP */
|
---|
483 |
|
---|
484 | /*
|
---|
485 | ** sst1InitWrite32():
|
---|
486 | ** Write 32-bit Word to specified address
|
---|
487 | **
|
---|
488 | */
|
---|
489 | FX_EXPORT void FX_CSTYLE sst1InitWrite32(FxU32 *addr, FxU32 data)
|
---|
490 | {
|
---|
491 | /* If the client software is using the command fifo then they are
|
---|
492 | * responsible for passing a callback that can be used to put
|
---|
493 | * register writes from the init code into the command fifo that
|
---|
494 | * they are managing. However, some registers cannot be accessed via
|
---|
495 | * the command fifo, and, inconveniently, these are not contiguously
|
---|
496 | * allocated.
|
---|
497 | */
|
---|
498 | const FxU32 addrOffset = ((const FxU32)addr - (const FxU32)sst1CurrentBoard->virtAddr[0]);
|
---|
499 | FxBool directWriteP = ((sst1CurrentBoard == NULL) ||
|
---|
500 | (sst1CurrentBoard->set32 == NULL) ||
|
---|
501 | sst1CurrentBoard->fbiLfbLocked ||
|
---|
502 | (addrOffset == 0x004) || /* intrCtrl */
|
---|
503 | ((addrOffset >= 0x1E0) && (addrOffset <= 0x200)) || /* cmdFifoBase ... fbiInit4 */
|
---|
504 | ((addrOffset >= 0x208) && (addrOffset <= 0x224)) || /* backPorch ... vSync */
|
---|
505 | ((addrOffset >= 0x22C) && (addrOffset <= 0x23C)) || /* dacData ... borderColor */
|
---|
506 | ((addrOffset >= 0x244) && (addrOffset <= 0x24C))); /* fbiInit5 ... fbiInit7 */
|
---|
507 |
|
---|
508 | if (directWriteP) {
|
---|
509 | P6FENCE;
|
---|
510 | SET(addr, data);
|
---|
511 | P6FENCE;
|
---|
512 | } else {
|
---|
513 | (*sst1CurrentBoard->set32)(addr, data);
|
---|
514 | }
|
---|
515 | }
|
---|
516 |
|
---|
517 | /*
|
---|
518 | ** sst1InitRead32():
|
---|
519 | ** Read 32-bit Word from specified address
|
---|
520 | **
|
---|
521 | */
|
---|
522 | FX_EXPORT FxU32 FX_CSTYLE sst1InitRead32(FxU32 *addr)
|
---|
523 | {
|
---|
524 | P6FENCE;
|
---|
525 | return GET(addr);
|
---|
526 | }
|
---|
527 |
|
---|
528 | /*
|
---|
529 | **
|
---|
530 | ** sst1InitCmdFifo():
|
---|
531 |
|
---|
532 | ** Setup Command Fifo.
|
---|
533 | **
|
---|
534 | ** The 'enable' parameter either enables or disables the Command Fifo.
|
---|
535 | **
|
---|
536 | ** Upon return, the 'virtAddrStart' parameter is filled with the starting
|
---|
537 | ** virtual address where command fifo packets should be stored. The
|
---|
538 | ** 'memAddrStart' parameter is filled with the address of where the command
|
---|
539 | ** fifo is stored in frame buffer memory. The 'memAddrStart' value is often
|
---|
540 | ** used by the JMP command to jump to the beginning of the command fifo.
|
---|
541 | ** The 'size' parameter is filled with the size of the command fifo.
|
---|
542 | ** The values of 'virtAddrstart', 'memAddrStart' and 'size'
|
---|
543 | ** are dependent on the amount of frame buffer memory detected as well as the
|
---|
544 | ** video resolution setup by sst1InitVideo(). 'virtAddrstart',
|
---|
545 | ** 'memAddrStart' and 'size' are all specified in bytes.
|
---|
546 | **
|
---|
547 | */
|
---|
548 | FX_ENTRY FxBool FX_CALL sst1InitCmdFifo(FxU32 *sstbase, FxBool enable,
|
---|
549 | FxU32 *virtAddrStart, FxU32 *memAddrStart, FxU32 *size, FxSet32Proc set32Proc)
|
---|
550 | {
|
---|
551 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
552 | FxU32 fbiInit, fifoStart, fifoSize;
|
---|
553 | FxBool directExec = (GETENV(("SSTV2_CMDFIFO_DIRECT"))) ? FXTRUE : FXFALSE;
|
---|
554 | FxBool disableHoles = (GETENV(("SSTV2_CMDFIFO_NOHOLES"))) ? FXTRUE : FXFALSE;
|
---|
555 |
|
---|
556 | if(!sst)
|
---|
557 | return(FXFALSE);
|
---|
558 |
|
---|
559 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
560 | return(FXFALSE);
|
---|
561 |
|
---|
562 | if(sst1CurrentBoard->fbiCmdFifoEn || (IGET(sst->fbiInit7) & SST_EN_CMDFIFO))
|
---|
563 | sst1InitIdleNoNOP(sstbase);
|
---|
564 | else
|
---|
565 | sst1InitIdle(sstbase);
|
---|
566 |
|
---|
567 | if(enable == FXFALSE) {
|
---|
568 | // Remove any client set callbacks before continuing since
|
---|
569 | // these must go straight to the hw.
|
---|
570 | sst1CurrentBoard->set32 = NULL;
|
---|
571 | sst1CurrentBoard->fbiCmdFifoEn = 0;
|
---|
572 |
|
---|
573 | // Disable Command Fifo
|
---|
574 | INIT_PRINTF(("sst1InitCmdFifo(): Disabling Command Fifo...\n"));
|
---|
575 | ISET(sst->fbiInit7, IGET(sst->fbiInit7) & ~SST_EN_CMDFIFO);
|
---|
576 |
|
---|
577 | // Reset graphics core to force disable to take effect...
|
---|
578 | ISET(sst->fbiInit0, IGET(sst->fbiInit0) | SST_GRX_RESET |
|
---|
579 | SST_EN_LFB_MEMFIFO | SST_EN_TEX_MEMFIFO);
|
---|
580 | sst1InitReturnStatus(sstbase);
|
---|
581 | sst1InitReturnStatus(sstbase);
|
---|
582 | sst1InitReturnStatus(sstbase);
|
---|
583 | ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_GRX_RESET);
|
---|
584 |
|
---|
585 | if(sst1CurrentBoard->sliSlaveVirtAddr) {
|
---|
586 | SstRegs *slaveSst = (SstRegs *) sst1CurrentBoard->sliSlaveVirtAddr;
|
---|
587 |
|
---|
588 | ISET(slaveSst->fbiInit7, IGET(slaveSst->fbiInit7) & ~SST_EN_CMDFIFO);
|
---|
589 | // Reset graphics core to force disable to take effect...
|
---|
590 | ISET(slaveSst->fbiInit0, IGET(slaveSst->fbiInit0) | SST_GRX_RESET |
|
---|
591 | SST_EN_LFB_MEMFIFO | SST_EN_TEX_MEMFIFO);
|
---|
592 | sst1InitReturnStatus(sst1CurrentBoard->sliSlaveVirtAddr);
|
---|
593 | sst1InitReturnStatus(sst1CurrentBoard->sliSlaveVirtAddr);
|
---|
594 | sst1InitReturnStatus(sst1CurrentBoard->sliSlaveVirtAddr);
|
---|
595 | ISET(slaveSst->fbiInit0, IGET(slaveSst->fbiInit0) & ~SST_GRX_RESET);
|
---|
596 |
|
---|
597 | if(sst1InitCheckBoard(sst1CurrentBoard->sliSlaveVirtAddr) == FXFALSE)
|
---|
598 | return(FXFALSE);
|
---|
599 | sst1CurrentBoard->set32 = NULL;
|
---|
600 | sst1CurrentBoard->fbiCmdFifoEn = 0;
|
---|
601 | }
|
---|
602 | return(FXTRUE);
|
---|
603 | }
|
---|
604 |
|
---|
605 | sst1InitIdle(sstbase);
|
---|
606 | fbiInit = IGET(sst->fbiInit4);
|
---|
607 | fifoStart =
|
---|
608 | (fbiInit & SST_MEM_FIFO_ROW_BASE) >> SST_MEM_FIFO_ROW_BASE_SHIFT;
|
---|
609 | fifoStart <<= 12; // Convert page-address into byte-address
|
---|
610 |
|
---|
611 | if(sst1CurrentBoard->fbiMemSize == 4)
|
---|
612 | fifoSize = (1024 - (fifoStart >> 12)) << 12;
|
---|
613 | else if(sst1CurrentBoard->fbiMemSize == 2)
|
---|
614 | fifoSize = (512 - (fifoStart >> 12)) << 12;
|
---|
615 | else
|
---|
616 | fifoSize = (256 - (fifoStart >> 12)) << 12;
|
---|
617 | if(fifoSize > (256<<10))
|
---|
618 | fifoSize = (256<<10);
|
---|
619 |
|
---|
620 | *virtAddrStart = (FxU32) (((FxU32) sstbase) + SST_CMDFIFO_ADDR);
|
---|
621 | *memAddrStart = fifoStart;
|
---|
622 | *size = fifoSize;
|
---|
623 |
|
---|
624 | if(!sst1InitCmdFifoDirect(sstbase, 0,
|
---|
625 | fifoStart, fifoSize,
|
---|
626 | directExec, disableHoles,
|
---|
627 | set32Proc)) {
|
---|
628 | INIT_PRINTF(("sst1InitCmdFifo(): sst1InitCmdFifoDirect() failed...\n"));
|
---|
629 | return(FXFALSE);
|
---|
630 | }
|
---|
631 |
|
---|
632 | if(sst1CurrentBoard->sliSlaveVirtAddr) {
|
---|
633 | if(!sst1InitCmdFifoDirect(sst1CurrentBoard->sliSlaveVirtAddr, 0,
|
---|
634 | fifoStart, fifoSize,
|
---|
635 | directExec, disableHoles,
|
---|
636 | set32Proc)) {
|
---|
637 | INIT_PRINTF(("sst1InitCmdFifo(): sst1InitCmdFifoDirect() failed for SLI Slave...\n"));
|
---|
638 | return(FXFALSE);
|
---|
639 | }
|
---|
640 | }
|
---|
641 |
|
---|
642 | INIT_PRINTF(("sst1InitCmdFifo() exiting with status %d...\n", FXTRUE));
|
---|
643 | return(FXTRUE);
|
---|
644 | }
|
---|
645 |
|
---|
646 | /*
|
---|
647 | **
|
---|
648 | ** sst1InitCmdFifoDirect():
|
---|
649 | ** Explicitly initialize Command FIFO. This routine is typically not
|
---|
650 | ** called directly from apps.
|
---|
651 | **
|
---|
652 | ** The 'start' and 'size' parameters are specified in bytes.
|
---|
653 | ** The 'which' parameter is not used, but is included for H3 compatibility.
|
---|
654 | **
|
---|
655 | */
|
---|
656 | FX_ENTRY FxBool FX_CALL sst1InitCmdFifoDirect(FxU32 *sstbase, FxU32 which,
|
---|
657 | FxU32 start, FxU32 size, FxBool directExec, FxBool disableHoles,
|
---|
658 | FxSet32Proc set32Proc)
|
---|
659 | {
|
---|
660 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
661 | FxU32 fbiInit7, initEnable, n;
|
---|
662 | FxU32 pageStart = start >> 12;
|
---|
663 | FxU32 pageEnd = (start+size-1) >> 12;
|
---|
664 |
|
---|
665 | if(!sst)
|
---|
666 | return(FXFALSE);
|
---|
667 |
|
---|
668 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
669 | return(FXFALSE);
|
---|
670 |
|
---|
671 | // sst1Initidle() routines must be properly executed...
|
---|
672 | initIdleEnabled = 1;
|
---|
673 |
|
---|
674 | INIT_PRINTF(("sst1InitCmdFifoDirect(): Start:0x%x bytes, Size:%d(0x%x) bytes\n",
|
---|
675 | start, size, size));
|
---|
676 | INIT_PRINTF(("sst1InitCmdFifoDirect(): DirectExec:%d, DisableHoles:%d\n",
|
---|
677 | directExec, disableHoles));
|
---|
678 | INIT_PRINTF(("sst1InitCmdFifoDirect(): pageStart:%d, pageEnd:%d\n",
|
---|
679 | pageStart, pageEnd));
|
---|
680 | INIT_PRINTF(("sst1InitCmdFifoDirect(): set32Proc: 0x%X\n",
|
---|
681 | (FxU32)set32Proc));
|
---|
682 |
|
---|
683 | if(sst1CurrentBoard->fbiCmdFifoEn || (IGET(sst->fbiInit7) & SST_EN_CMDFIFO))
|
---|
684 | sst1InitIdleNoNOP(sstbase);
|
---|
685 | else
|
---|
686 | sst1InitIdle(sstbase);
|
---|
687 | // Disable memory-backed fifo, and disallow lfb and texture writes
|
---|
688 | // through command fifo...
|
---|
689 | ISET(sst->fbiInit0, (IGET(sst->fbiInit0) &
|
---|
690 | ~(SST_MEM_FIFO_EN | SST_EN_LFB_MEMFIFO | SST_EN_TEX_MEMFIFO)));
|
---|
691 | sst1InitReturnStatus(sstbase);
|
---|
692 |
|
---|
693 | fbiInit7 = IGET(sst->fbiInit7);
|
---|
694 | fbiInit7 &= ~(SST_EN_CMDFIFO |
|
---|
695 | SST_EN_CMDFIFO_OFFSCREEN | SST_CMDFIFO_DISABLE_HOLES |
|
---|
696 | SST_CMDFIFO_REGS_SYNC_WRITES | SST_CMDFIFO_REGS_SYNC_READS |
|
---|
697 | SST_CMDFIFO_RDFETCH_THRESH | SST_CMDFIFO_PCI_TIMEOUT);
|
---|
698 | fbiInit7 |= SST_CMDFIFO_REGS_SYNC_WRITES | SST_CMDFIFO_REGS_SYNC_READS |
|
---|
699 | (0x10<<SST_CMDFIFO_RDFETCH_THRESH_SHIFT) |
|
---|
700 | (127<<SST_CMDFIFO_PCI_TIMEOUT_SHIFT);
|
---|
701 | ISET(sst->fbiInit7, fbiInit7); // turn off the command fifo
|
---|
702 | sst1InitReturnStatus(sstbase);
|
---|
703 |
|
---|
704 | // Disable all writes to the PCI fifo while we're setting up CMDFIFO
|
---|
705 | PCICFG_RD(SST1_PCI_INIT_ENABLE, initEnable);
|
---|
706 | PCICFG_WR(SST1_PCI_INIT_ENABLE,
|
---|
707 | ((initEnable & ~(SST_INITWR_EN | SST_PCI_FIFOWR_EN)) | SST_INITWR_EN));
|
---|
708 |
|
---|
709 | // Setup command fifo...
|
---|
710 | ISET(sst->cmdFifoBase, (pageEnd << SST_CMDFIFO_END_SHIFT) | pageStart);
|
---|
711 | sst1InitReturnStatus(sstbase); // prevent PCI bursts...
|
---|
712 | ISET(sst->cmdFifoReadPtr, start);
|
---|
713 | sst1InitReturnStatus(sstbase);
|
---|
714 | ISET(sst->cmdFifoAmin, start-4);
|
---|
715 | sst1InitReturnStatus(sstbase);
|
---|
716 | ISET(sst->cmdFifoAmax, start-4);
|
---|
717 | sst1InitReturnStatus(sstbase);
|
---|
718 | ISET(sst->cmdFifoDepth, 0);
|
---|
719 | sst1InitReturnStatus(sstbase);
|
---|
720 | ISET(sst->cmdFifoHoles, 0);
|
---|
721 | sst1InitReturnStatus(sstbase);
|
---|
722 | sst1InitIdle(sstbase);
|
---|
723 |
|
---|
724 | // Turn on command fifo...
|
---|
725 | ISET(sst->fbiInit7, fbiInit7 | SST_EN_CMDFIFO |
|
---|
726 | (directExec ? 0 : SST_EN_CMDFIFO_OFFSCREEN) |
|
---|
727 | (disableHoles ? SST_CMDFIFO_DISABLE_HOLES : 0));
|
---|
728 | // Can't perform sst1InitIdle() here because it will generate
|
---|
729 | // writes to the CMDFIFO since the CMDFIFO is now enabled...
|
---|
730 | sst1InitReturnStatus(sstbase);
|
---|
731 |
|
---|
732 | // Enable writes to be pushed onto the CMDFIFO...
|
---|
733 | PCICFG_WR(SST1_PCI_INIT_ENABLE,
|
---|
734 | (initEnable | SST_INITWR_EN | SST_PCI_FIFOWR_EN));
|
---|
735 |
|
---|
736 | sst1CurrentBoard->fbiCmdFifoEn = 1;
|
---|
737 | if(GETENV(("SSTV2_IGNORE_IDLE")))
|
---|
738 | initIdleEnabled = 0;
|
---|
739 |
|
---|
740 | /* Set the client callbacks, if necessary. */
|
---|
741 | sst1CurrentBoard->set32 = set32Proc;
|
---|
742 |
|
---|
743 | return(FXTRUE);
|
---|
744 | }
|
---|
745 |
|
---|
746 | /*
|
---|
747 | **
|
---|
748 | ** sst1InitLfbLock():
|
---|
749 | ** Used to workaround a hw bug when performing lfb and texture writes when
|
---|
750 | ** the command fifo is enabled. The routines sst1InitLfbLock() and
|
---|
751 | ** sst1InitLfbUnlock() dynamically disable the command fifo so that lfb
|
---|
752 | ** and texture accesses do not pass through the command fifo.
|
---|
753 | ** WARNING: No register writes of any kind may be performed between a
|
---|
754 | ** sst1InitLfbLock() and sst1InitLfbUnlock() pair -- only lfb reads and
|
---|
755 | ** writes are allowed.
|
---|
756 | */
|
---|
757 | FX_ENTRY FxBool FX_CALL sst1InitLfbLock(FxU32* sstbase)
|
---|
758 | {
|
---|
759 | if(!sstbase)
|
---|
760 | return(FXFALSE);
|
---|
761 |
|
---|
762 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
763 | return(FXFALSE);
|
---|
764 |
|
---|
765 | // Idle the hardware...
|
---|
766 | sst1InitIdle(sstbase);
|
---|
767 |
|
---|
768 | if(sst1InitLfbLockDirect(sstbase) == FXFALSE)
|
---|
769 | return(FXFALSE);
|
---|
770 |
|
---|
771 | if(sst1CurrentBoard->sliSlaveVirtAddr) {
|
---|
772 | // SLI Enabled
|
---|
773 | if(sst1InitLfbLockDirect(sst1CurrentBoard->sliSlaveVirtAddr) == FXFALSE)
|
---|
774 | return(FXFALSE);
|
---|
775 | }
|
---|
776 |
|
---|
777 | return(FXTRUE);
|
---|
778 | }
|
---|
779 |
|
---|
780 | FX_ENTRY FxBool FX_CALL sst1InitLfbLockDirect(FxU32* sstbase)
|
---|
781 | {
|
---|
782 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
783 |
|
---|
784 | if(!sst)
|
---|
785 | return(FXFALSE);
|
---|
786 |
|
---|
787 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
788 | return(FXFALSE);
|
---|
789 |
|
---|
790 | if((!(IGET(sst->fbiInit7) & SST_EN_CMDFIFO) &&
|
---|
791 | !sst1CurrentBoard->fbiCmdFifoEn) || sst1CurrentBoard->fbiLfbLocked)
|
---|
792 | return(FXTRUE);
|
---|
793 |
|
---|
794 | // Force direct writes...
|
---|
795 | sst1CurrentBoard->fbiLfbLocked = 1;
|
---|
796 |
|
---|
797 | ISET(sst->fbiInit7, IGET(sst->fbiInit7) & ~SST_EN_CMDFIFO_OFFSCREEN);
|
---|
798 | sst1InitReturnStatus(sstbase);
|
---|
799 | sst1InitReturnStatus(sstbase);
|
---|
800 | sst1InitReturnStatus(sstbase);
|
---|
801 |
|
---|
802 | return(FXTRUE);
|
---|
803 | }
|
---|
804 |
|
---|
805 | /*
|
---|
806 | **
|
---|
807 | ** sst1InitLfbUnlock():
|
---|
808 | ** Used to workaround a hw bug when performing lfb and texture writes when
|
---|
809 | ** the command fifo is enabled. The routines sst1InitLfbLock() and
|
---|
810 | ** sst1InitLfbUnlock() dynamically disable the command fifo so that lfb
|
---|
811 | ** and texture accesses do not pass through the command fifo.
|
---|
812 | ** WARNING: No register writes of any kind may be performed between a
|
---|
813 | ** sst1InitLfbLock() and sst1InitLfbUnlock() pair -- only lfb reads and
|
---|
814 | ** writes are allowed.
|
---|
815 | */
|
---|
816 |
|
---|
817 | FX_ENTRY FxBool FX_CALL sst1InitLfbUnlock(FxU32* sstbase)
|
---|
818 | {
|
---|
819 | if(!sstbase)
|
---|
820 | return(FXFALSE);
|
---|
821 |
|
---|
822 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
823 | return(FXFALSE);
|
---|
824 |
|
---|
825 | // Idle the hardware. Since lfb lock is set, a NOP will not be issued, and
|
---|
826 | // sst1InitPciFifoIdleLoop() will be used instead of sst1InitIdleLoop()...
|
---|
827 | sst1InitIdle(sstbase);
|
---|
828 |
|
---|
829 | if(sst1CurrentBoard->sliSlaveVirtAddr) {
|
---|
830 | // SLI Enabled
|
---|
831 | if(sst1InitLfbUnlockDirect(sst1CurrentBoard->sliSlaveVirtAddr) ==
|
---|
832 | FXFALSE)
|
---|
833 | return(FXFALSE);
|
---|
834 | }
|
---|
835 | if(sst1InitLfbUnlockDirect(sstbase) == FXFALSE)
|
---|
836 | return(FXFALSE);
|
---|
837 |
|
---|
838 | // After the command fifo is re-enabled, make sure the chip is really idle...
|
---|
839 | sst1InitIdle(sstbase);
|
---|
840 |
|
---|
841 | return(FXTRUE);
|
---|
842 | }
|
---|
843 |
|
---|
844 | FX_ENTRY FxBool FX_CALL sst1InitLfbUnlockDirect(FxU32* sstbase)
|
---|
845 | {
|
---|
846 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
847 |
|
---|
848 | if(!sst)
|
---|
849 | return(FXFALSE);
|
---|
850 |
|
---|
851 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
852 | return(FXFALSE);
|
---|
853 |
|
---|
854 | if(!sst1CurrentBoard->fbiCmdFifoEn || !sst1CurrentBoard->fbiLfbLocked)
|
---|
855 | return(FXTRUE);
|
---|
856 |
|
---|
857 | ISET(sst->fbiInit7, IGET(sst->fbiInit7) | SST_EN_CMDFIFO_OFFSCREEN);
|
---|
858 |
|
---|
859 | sst1CurrentBoard->fbiLfbLocked = 0;
|
---|
860 |
|
---|
861 | sst1InitReturnStatus(sstbase);
|
---|
862 | sst1InitReturnStatus(sstbase);
|
---|
863 | sst1InitReturnStatus(sstbase);
|
---|
864 |
|
---|
865 | return(FXTRUE);
|
---|
866 | }
|
---|
867 |
|
---|
868 | /*
|
---|
869 | **
|
---|
870 | ** sst1InitPrintInitRegs():
|
---|
871 | ** Print Initialization Registers
|
---|
872 | **
|
---|
873 | */
|
---|
874 | FX_EXPORT void FX_CSTYLE sst1InitPrintInitRegs(FxU32 *sstbase)
|
---|
875 | {
|
---|
876 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
877 |
|
---|
878 | INIT_PRINTF(("FBI Initialization Registers:\n"));
|
---|
879 | INIT_PRINTF(("-----------------------------\n"));
|
---|
880 | INIT_PRINTF(("fbiInit0:0x%08x fbiInit1:0x%08x\n",
|
---|
881 | IGET(sst->fbiInit0), IGET(sst->fbiInit1)));
|
---|
882 | INIT_PRINTF(("fbiInit2:0x%08x fbiInit3:0x%08x\n",
|
---|
883 | IGET(sst->fbiInit2), IGET(sst->fbiInit3)));
|
---|
884 | INIT_PRINTF(("fbiInit4:0x%08x fbiInit5:0x%08x\n",
|
---|
885 | IGET(sst->fbiInit4), IGET(sst->fbiInit5)));
|
---|
886 | INIT_PRINTF(("fbiInit6:0x%08x fbiInit7:0x%08x\n",
|
---|
887 | IGET(sst->fbiInit6), IGET(sst->fbiInit7)));
|
---|
888 | INIT_PRINTF(("videoDimensions:0x%08x\n\n",
|
---|
889 | IGET(sst->videoDimensions)));
|
---|
890 | INIT_PRINTF(("FBI Command Fifo Registers:\n"));
|
---|
891 | INIT_PRINTF(("---------------------------\n"));
|
---|
892 | INIT_PRINTF(("cmdFifoBase: 0x%08x\tcmdFifoBump:0x%x\n",
|
---|
893 | IGET(sst->cmdFifoBase), IGET(sst->cmdFifoBump)));
|
---|
894 | INIT_PRINTF(("cmdFifoReadPtr: 0x%08x\tcmdFifoAmin:0x%x\n",
|
---|
895 | IGET(sst->cmdFifoReadPtr), IGET(sst->cmdFifoAmin)));
|
---|
896 | INIT_PRINTF(("cmdFifoAmax: 0x%08x\tcmdFifoDepth:0x%x\n",
|
---|
897 | IGET(sst->cmdFifoAmax), IGET(sst->cmdFifoDepth)));
|
---|
898 | INIT_PRINTF(("cmdFifoHoles: 0x%08x\n", IGET(sst->cmdFifoHoles)));
|
---|
899 | }
|
---|
900 |
|
---|
901 | /*
|
---|
902 | **
|
---|
903 | ** sst1InitMeasureSiProcess():
|
---|
904 | ** Use silicon process register to measure silicon performance
|
---|
905 | **
|
---|
906 | */
|
---|
907 | FX_EXPORT FxU32 FX_CSTYLE sst1InitMeasureSiProcess(FxU32 *sstbase, FxU32 which)
|
---|
908 | {
|
---|
909 | FxU32 n, siProcess, nandOsc, norOsc;
|
---|
910 | FxU32 pciCntrLoad = 0xfff;
|
---|
911 | FxU32 cntr;
|
---|
912 |
|
---|
913 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
914 | return(FXFALSE);
|
---|
915 |
|
---|
916 | if(GETENV(("SSTV2_SIPROCESS_CNTR"))) {
|
---|
917 | SSCANF(GETENV(("SSTV2_SIPROCESS_CNTR")), "%i", &pciCntrLoad);
|
---|
918 | INIT_PRINTF(("sst1InitMeasureSiProcess(): Using PCI Counter preload value of 0x%x...\n", pciCntrLoad));
|
---|
919 | }
|
---|
920 |
|
---|
921 | if(!which) {
|
---|
922 | ////////////////////////////////
|
---|
923 | // Test NAND oscillator tree...
|
---|
924 | ////////////////////////////////
|
---|
925 | PCICFG_WR(SST1_PCI_SIPROCESS,
|
---|
926 | (pciCntrLoad<<SST_SIPROCESS_PCI_CNTR_SHIFT) |
|
---|
927 | SST_SIPROCESS_OSC_CNTR_RESET_N | SST_SIPROCESS_OSC_NAND_SEL);
|
---|
928 |
|
---|
929 | // Allow oscillator to run...
|
---|
930 | PCICFG_RD(SST1_PCI_SIPROCESS, siProcess);
|
---|
931 | PCICFG_WR(SST1_PCI_SIPROCESS,
|
---|
932 | (pciCntrLoad<<SST_SIPROCESS_PCI_CNTR_SHIFT) |
|
---|
933 | SST_SIPROCESS_OSC_CNTR_RUN | SST_SIPROCESS_OSC_NAND_SEL);
|
---|
934 |
|
---|
935 | // Loop until PCI counter decrements to 0
|
---|
936 | cntr = 0 ;
|
---|
937 | do {
|
---|
938 | ++cntr;
|
---|
939 | PCICFG_RD(SST1_PCI_SIPROCESS, siProcess);
|
---|
940 | } while(siProcess & SST_SIPROCESS_PCI_CNTR);
|
---|
941 |
|
---|
942 | PCICFG_RD(SST1_PCI_SIPROCESS, siProcess);
|
---|
943 | siProcess &= SST_SIPROCESS_OSC_CNTR;
|
---|
944 | nandOsc = siProcess;
|
---|
945 | if(nandOsc < 3000)
|
---|
946 | nandOsc <<= 1; // Running on 66 MHz PCI...
|
---|
947 | sst1CurrentBoard->fbiNandTree = nandOsc;
|
---|
948 |
|
---|
949 | INIT_PRINTF(("sst1InitInfo(): NAND-tree: %d\n", nandOsc));
|
---|
950 | } else {
|
---|
951 | ////////////////////////////////
|
---|
952 | // Test NOR oscillator tree...
|
---|
953 | ////////////////////////////////
|
---|
954 | PCICFG_WR(SST1_PCI_SIPROCESS,
|
---|
955 | (pciCntrLoad<<SST_SIPROCESS_PCI_CNTR_SHIFT) |
|
---|
956 | SST_SIPROCESS_OSC_CNTR_RESET_N | SST_SIPROCESS_OSC_NOR_SEL);
|
---|
957 |
|
---|
958 | // Allow oscillator to run...
|
---|
959 | PCICFG_RD(SST1_PCI_SIPROCESS, siProcess);
|
---|
960 | PCICFG_WR(SST1_PCI_SIPROCESS,
|
---|
961 | (pciCntrLoad<<SST_SIPROCESS_PCI_CNTR_SHIFT) |
|
---|
962 | SST_SIPROCESS_OSC_CNTR_RUN | SST_SIPROCESS_OSC_NOR_SEL);
|
---|
963 |
|
---|
964 | // Loop until PCI counter decrements to 0
|
---|
965 | cntr = 0 ;
|
---|
966 | do {
|
---|
967 | ++cntr;
|
---|
968 | PCICFG_RD(SST1_PCI_SIPROCESS, siProcess);
|
---|
969 | } while(siProcess & SST_SIPROCESS_PCI_CNTR);
|
---|
970 |
|
---|
971 | PCICFG_RD(SST1_PCI_SIPROCESS, siProcess);
|
---|
972 | siProcess &= SST_SIPROCESS_OSC_CNTR;
|
---|
973 | norOsc = siProcess;
|
---|
974 | if(norOsc < 3000)
|
---|
975 | norOsc <<= 1; // Running on 66 MHz PCI...
|
---|
976 | sst1CurrentBoard->fbiNorTree = norOsc;
|
---|
977 |
|
---|
978 | INIT_PRINTF(("sst1InitInfo(): NOR-tree : %d\n", norOsc));
|
---|
979 | }
|
---|
980 | return(siProcess);
|
---|
981 | }
|
---|
982 |
|
---|
983 | /*
|
---|
984 | **
|
---|
985 | ** sst1InitCalcTClkDelay()
|
---|
986 | ** Calculate optimal TF/TT Clock delay values
|
---|
987 | **
|
---|
988 | */
|
---|
989 | FX_EXPORT FxBool FX_CSTYLE sst1InitCalcTClkDelay(FxU32 *sstbase,
|
---|
990 | FxU32 tmuNumber, FxU32 tClkDelay)
|
---|
991 | {
|
---|
992 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
993 | volatile FxU32 *texAddr;
|
---|
994 |
|
---|
995 | if(sst1InitCheckBoard(sstbase) == FXFALSE)
|
---|
996 | return(FXFALSE);
|
---|
997 |
|
---|
998 | ISET(sst->tLOD, 0x0);
|
---|
999 | ISET(sst->tDetail, 0x0);
|
---|
1000 | ISET(sst->texBaseAddr, 0x0);
|
---|
1001 | ISET(sst->fogMode, 0x0);
|
---|
1002 | ISET(sst->alphaMode, 0x0);
|
---|
1003 | ISET(sst->fbzMode, SST_ENCHROMAKEY);
|
---|
1004 | ISET(sst->fbzColorPath, SST_RGBSEL_TREXOUT | SST_CC_PASS | SST_ENTEXTUREMAP);
|
---|
1005 | //texAddr = (numTmu<<(21-2)) + (FxU32 *) SST_TEX_ADDRESS(sst);
|
---|
1006 | texAddr = (0<<(21-2)) + (FxU32 *) SST_TEX_ADDRESS(sst);
|
---|
1007 | ISET(texAddr[0], 0x0);
|
---|
1008 | texAddr = (1<<(21-2)) + (FxU32 *) SST_TEX_ADDRESS(sst);
|
---|
1009 | ISET(texAddr[0], 0x0);
|
---|
1010 | texAddr = (2<<(21-2)) + (FxU32 *) SST_TEX_ADDRESS(sst);
|
---|
1011 | ISET(texAddr[0], 0x0);
|
---|
1012 |
|
---|
1013 | ISET(SST_TREX(sst,tmuNumber)->trexInit1,
|
---|
1014 | (sst1CurrentBoard->tmuInit1[tmuNumber] & ~SST_TEX_TF_CLK_DEL_ADJ) |
|
---|
1015 | (tClkDelay<<SST_TEX_TF_CLK_DEL_ADJ_SHIFT));
|
---|
1016 |
|
---|
1017 | if(sst1InitIdleWithTimeout(sstbase, 10000) == FXFALSE)
|
---|
1018 | return(FXFALSE);
|
---|
1019 |
|
---|
1020 | // Reset pixel stat registers
|
---|
1021 | ISET(sst->nopCMD, 0x3);
|
---|
1022 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0xff0000);
|
---|
1023 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0x00ffff);
|
---|
1024 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0xf0f0f0);
|
---|
1025 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0x0f0f0f);
|
---|
1026 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0x55aa55);
|
---|
1027 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0xaa55aa);
|
---|
1028 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0x5a5a5a);
|
---|
1029 | sst1InitCheckTmuMemConst(sstbase, tmuNumber, 0xa5a5a5);
|
---|
1030 |
|
---|
1031 | if(sst1InitIdleWithTimeout(sstbase, 10000) == FXFALSE)
|
---|
1032 | return(FXFALSE);
|
---|
1033 |
|
---|
1034 | if(IGET(sst->stats.fbiChromaFail))
|
---|
1035 | return(FXFALSE);
|
---|
1036 | else
|
---|
1037 | return(FXTRUE);
|
---|
1038 | }
|
---|
1039 |
|
---|
1040 | #define COLOR32TOCOLOR24_6666(X) \
|
---|
1041 | ((((X >> 2) & 0x3F) << 0) | \
|
---|
1042 | (((X >> 10) & 0x3F) << 6) | \
|
---|
1043 | (((X >> 18) & 0x3F) << 12) | \
|
---|
1044 | (((X >> 26) & 0x3F) << 18))
|
---|
1045 | #define COLOR24_6666TOCOLOR32(X) \
|
---|
1046 | (((((X >> 0) & 0x3F) << 2) | (((X >> 4) & 0x3) << 0)) | \
|
---|
1047 | ((((X >> 6) & 0x3F) << 10) | (((X >> 10) & 0x3) << 8)) | \
|
---|
1048 | ((((X >> 12) & 0x3F) << 18) | (((X >> 16) & 0x3) << 16)) | \
|
---|
1049 | ((((X >> 18) & 0x3F) << 26) | (((X >> 22) & 0x3) << 24)))
|
---|
1050 |
|
---|
1051 | void sst1InitCheckTmuMemConst(FxU32 *sstbase, FxU32 tmuNumber,
|
---|
1052 | FxU32 dataExpect32)
|
---|
1053 | {
|
---|
1054 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
1055 | FxU32 dataExpect6666 = COLOR32TOCOLOR24_6666(dataExpect32);
|
---|
1056 | FxU32 dataExpect6666To32 = COLOR24_6666TOCOLOR32(dataExpect6666) & 0xffffff;
|
---|
1057 |
|
---|
1058 | ISET(sst->chromaKey, dataExpect6666To32);
|
---|
1059 | ISET(sst->chromaRange, dataExpect6666To32 | SST_ENCHROMARANGE |
|
---|
1060 | SST_CHROMARANGE_BLUE_EX | SST_CHROMARANGE_GREEN_EX |
|
---|
1061 | SST_CHROMARANGE_RED_EX | SST_CHROMARANGE_BLOCK_OR);
|
---|
1062 |
|
---|
1063 | if(!tmuNumber) {
|
---|
1064 | ISET(sst->textureMode, SST_P8_ARGB6666 | SST_TC_REPLACE | SST_TCA_ZERO);
|
---|
1065 | } else if(tmuNumber == 1) {
|
---|
1066 | // Force downstream TMU to passthrough upstream data
|
---|
1067 | ISET(SST_TREX(sst,0)->textureMode, SST_P8_ARGB6666 | SST_TC_PASS |
|
---|
1068 | SST_TCA_PASS);
|
---|
1069 | ISET(SST_TREX(sst,1)->textureMode, SST_P8_ARGB6666 | SST_TC_REPLACE |
|
---|
1070 | SST_TCA_ZERO);
|
---|
1071 | ISET(SST_TREX(sst,2)->textureMode, SST_P8_ARGB6666 | SST_TC_REPLACE |
|
---|
1072 | SST_TCA_ZERO);
|
---|
1073 | } else {
|
---|
1074 | // Force downstream TMUs to passthrough upstream data
|
---|
1075 | ISET(SST_TREX(sst,0)->textureMode, SST_P8_ARGB6666 | SST_TC_PASS |
|
---|
1076 | SST_TCA_PASS);
|
---|
1077 | ISET(SST_TREX(sst,1)->textureMode, SST_P8_ARGB6666 | SST_TC_PASS |
|
---|
1078 | SST_TCA_PASS);
|
---|
1079 | ISET(SST_TREX(sst,2)->textureMode, SST_P8_ARGB6666 | SST_TC_REPLACE |
|
---|
1080 | SST_TCA_ZERO);
|
---|
1081 | }
|
---|
1082 | // Specify color in palette entry 0...
|
---|
1083 | //sst->nccTable0[4]=BIT(31) | ((index>>1)<<24) | (palette[index] & 0xffffff);
|
---|
1084 | ISET(sst->nccTable0[4], BIT(31) | COLOR32TOCOLOR24_6666(dataExpect32));
|
---|
1085 | sst1InitDrawRectUsingTris(sstbase, 0, 0, 128);
|
---|
1086 |
|
---|
1087 | return;
|
---|
1088 | }
|
---|
1089 |
|
---|
1090 | void sst1InitDrawRectUsingTris(FxU32 *sstbase, FxU32 x, FxU32 y, FxU32 tSize)
|
---|
1091 | {
|
---|
1092 | SstRegs *sst = (SstRegs *) sstbase;
|
---|
1093 |
|
---|
1094 | ISET(sst->vA.x, (x<<SST_XY_FRACBITS));
|
---|
1095 | ISET(sst->vA.y, (y<<SST_XY_FRACBITS));
|
---|
1096 | ISET(sst->vB.x, ((x+tSize)<<SST_XY_FRACBITS));
|
---|
1097 | ISET(sst->vB.y, (y<<SST_XY_FRACBITS));
|
---|
1098 | ISET(sst->vC.x, ((x+tSize)<<SST_XY_FRACBITS));
|
---|
1099 | ISET(sst->vC.y, ((y+tSize)<<SST_XY_FRACBITS));
|
---|
1100 | ISET(sst->s, 0);
|
---|
1101 | ISET(sst->t, 0);
|
---|
1102 | ISET(sst->w, 0);
|
---|
1103 | ISET(sst->r, (0xff<<SST_XY_INTBITS));
|
---|
1104 | ISET(sst->g, 0);
|
---|
1105 | ISET(sst->b, 0);
|
---|
1106 | ISET(sst->dsdx, 0);
|
---|
1107 | ISET(sst->dtdx, 0);
|
---|
1108 | ISET(sst->dwdx, 0);
|
---|
1109 | ISET(sst->dsdy, 0);
|
---|
1110 | ISET(sst->dtdy, 0);
|
---|
1111 | ISET(sst->dwdy, 0);
|
---|
1112 | ISET(sst->triangleCMD, 0);
|
---|
1113 | ISET(sst->vB.x, (x<<SST_XY_FRACBITS));
|
---|
1114 | ISET(sst->vB.y, ((y+tSize)<<SST_XY_FRACBITS));
|
---|
1115 | ISET(sst->triangleCMD, 0xFFFFFFFF);
|
---|
1116 | }
|
---|
1117 |
|
---|
1118 | #pragma optimize ("",on)
|
---|