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

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

Added $Id:$ keyword.

File size: 43.6 KB
Line 
1/* $Id: dac.c,v 1.2 2001-09-05 14:30:35 bird Exp $ */
2/*
3** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
4** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
5** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
6** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
7** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
8** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
9** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
10** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
11**
12** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
13** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
14** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
15** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
16** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
17** THE UNITED STATES.
18**
19** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
20**
21**
22** $Revision: 1.2 $
23** $Date: 2001-09-05 14:30:35 $
24**
25** Initialization code for initializing supported SST-1 DACs
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** sst1InitDacRd():
46** Read external DAC registers
47** NOTE: The video unit of FBI must be in reset before calling this routine.
48** The rendering engines of FBI and TREX must be idle before calling
49** this routine.
50** fbiInit23 register remapping (PCI config. initEnable[2]=1) must be
51** enabled before calling this routine
52**
53** Valid addresses are 0 <= addr <= 3
54**
55*/
56FX_EXPORT FxU32 FX_CSTYLE sst1InitDacRd(FxU32 *sstbase, FxU32 addr)
57{
58 SstRegs *sst = (SstRegs *) sstbase;
59 FxU32 retVal;
60 static FxBool firstPass = FXTRUE;
61 static int helper;
62
63 if(firstPass == FXTRUE) {
64 firstPass = FXFALSE;
65 helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
66 }
67
68 ISET(sst->dacData, ((addr) << SST_DACDATA_ADDR_SHIFT) | SST_DACDATA_RD);
69 sst1InitIdleFBINoNOP(sstbase);
70 retVal = IGET(sst->fbiInit2) & SST_DACDATA_DATA;
71 if(helper)
72 INIT_PRINTF(("dacRd(0x%x,0x%x)\n", addr, retVal));
73
74 return(retVal);
75}
76
77/*
78** sst1InitDacWr():
79** Write to external DAC registers
80** NOTE: The video unit of FBI must be in reset before calling this routine.
81** The rendering engines of FBI and TREX must be idle before calling
82** this routine.
83**
84** Valid addresses are 0 <= addr <= 3
85**
86*/
87FX_EXPORT void FX_CSTYLE sst1InitDacWr(FxU32 *sstbase, FxU32 addr, FxU32 data)
88{
89 SstRegs *sst = (SstRegs *) sstbase;
90 static FxBool firstPass = FXTRUE;
91 static int helper;
92
93 if(firstPass == FXTRUE) {
94 firstPass = FXFALSE;
95 helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
96 }
97
98 ISET(sst->dacData,
99 (data & SST_DACDATA_DATA) |
100 ((addr) << SST_DACDATA_ADDR_SHIFT) |
101 SST_DACDATA_WR);
102 sst1InitIdleFBINoNOP(sstbase);
103
104 if(helper)
105 INIT_PRINTF(("dacWr(0x%x,0x%x)\n", addr, data));
106}
107
108/*
109** sst1InitExecuteDacRdWr():
110** Execute DAC read/write command sequence defined in "voodoo2.ini" file
111**
112*/
113FxBool sst1InitExecuteDacRdWr(FxU32 *sstbase, sst1InitDacRdWrStruct
114 *dacRdWrBase)
115{
116 sst1InitDacRdWrStruct *dacRdWrPtr = dacRdWrBase;
117 FxU32 data;
118 FxBool retVal = FXTRUE;
119 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
120
121 while(dacRdWrPtr) {
122 if(dacRdWrPtr->type == DACRDWR_TYPE_WR) {
123 sst1InitDacWr(sstbase, dacRdWrPtr->addr, dacRdWrPtr->data);
124 } else if(dacRdWrPtr->type == DACRDWR_TYPE_RDMODWR) {
125 data = sst1InitDacRd(sstbase, dacRdWrPtr->addr);
126 if(helper)
127 INIT_PRINTF(("dacRdWr(Read=0x%x)\n", data));
128 data &= dacRdWrPtr->mask;
129 sst1InitDacWr(sstbase, dacRdWrPtr->addr, (data | dacRdWrPtr->data));
130 } else if(dacRdWrPtr->type == DACRDWR_TYPE_WRMOD_POP) {
131 data = iniStack[--iniStackPtr];
132 if(iniStackPtr < 0) {
133 retVal = FXFALSE;
134 break;
135 }
136 if(helper)
137 INIT_PRINTF(("dacWrModPop(Stack=0x%x,Mask=0x%x)\n", data,
138 dacRdWrPtr->mask));
139 data &= dacRdWrPtr->mask;
140 sst1InitDacWr(sstbase, dacRdWrPtr->addr, (data | dacRdWrPtr->data));
141 } else if(dacRdWrPtr->type == DACRDWR_TYPE_RDNOCHECK) {
142 sst1InitDacRd(sstbase, dacRdWrPtr->addr);
143 } else if(dacRdWrPtr->type == DACRDWR_TYPE_RDPUSH) {
144 data = sst1InitDacRd(sstbase, dacRdWrPtr->addr);
145 iniStack[iniStackPtr++] = data;
146 if(iniStackPtr == DACRDWR_MAX_PUSH) {
147 retVal = FXFALSE;
148 break;
149 }
150 } else if(dacRdWrPtr->type == DACRDWR_TYPE_RDCHECK) {
151 if(sst1InitDacRd(sstbase, dacRdWrPtr->addr) != dacRdWrPtr->data) {
152 retVal = FXFALSE;
153 break;
154 }
155 } else {
156 retVal = FXFALSE;
157 break;
158 }
159 dacRdWrPtr = dacRdWrPtr->nextRdWr;
160 }
161 return(retVal);
162}
163
164/*
165** sst1InitDacDetect():
166** Detect type of on-board DAC
167** NOTE: sst1InitDacDetect() resets the PCI fifo and the graphics subsystem
168** of FBI
169**
170*/
171FX_EXPORT FxBool FX_CSTYLE sst1InitDacDetect(FxU32 * sstbase)
172{
173 FxU32 n;
174 FxU32 fbiInit1_save;
175 FxU32 fbiInit2_save;
176 SstRegs *sst = (SstRegs *) sstbase;
177 FxBool retVal = FXFALSE;
178 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
179
180 if(!sst)
181 return(FXFALSE);
182
183 if(helper)
184 INIT_PRINTF(("sst1InitDacDetect(): Entered...\n"));
185
186 sst1InitIdleFBINoNOP(sstbase);
187
188 /* Save init register states before overwriting them */
189 fbiInit1_save = IGET(sst->fbiInit1);
190 fbiInit2_save = IGET(sst->fbiInit2);
191
192 /* Reset video unit to guarantee no contentions on the memory bus */
193 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
194 /* Turn off dram refresh to guarantee no contentions on the memory bus */
195 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
196 sst1InitIdleFBINoNOP(sstbase);
197
198 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
199 /* Disallow writes to pass through the PCI FIFO */
200 PCICFG_WR(SST1_PCI_INIT_ENABLE, SST_INITWR_EN | SST_FBIINIT23_REMAP);
201 sst1InitIdleFBINoNOP(sstbase);
202
203 if(sst1InitUseVoodooFile == FXTRUE) {
204 retVal = sst1InitDacDetectINI(sstbase);
205 } else {
206 if((retVal = sst1InitDacDetectICS(sstbase)) == FXTRUE)
207 goto done;
208 if((retVal = sst1InitDacDetectATT(sstbase)) == FXTRUE)
209 goto done;
210 retVal = sst1InitDacDetectTI(sstbase);
211 }
212
213done:
214 /* Disable fbiinit23 address remapping */
215 PCICFG_WR(SST1_PCI_INIT_ENABLE, SST_INITWR_EN | SST_PCI_FIFOWR_EN);
216
217 /* Restore init register states */
218 sst1InitIdleFBINoNOP(sstbase);
219 ISET(sst->fbiInit1, fbiInit1_save);
220 ISET(sst->fbiInit2, fbiInit2_save);
221 sst1InitIdleFBINoNOP(sstbase);
222 return(retVal);
223}
224
225/*
226** sst1InitDacDetectINI():
227** Detect DAC based on rules supplied in "voodoo2.ini"
228**
229*/
230FxBool sst1InitDacDetectINI(FxU32 * sstbase)
231{
232 sst1InitDacStruct *dacPtr;
233 FxU32 j;
234 FxBool retVal = FXFALSE;
235
236 dacPtr = dacStructBase;
237 while(dacPtr) {
238 if(dacPtr->detect) {
239 /* Loop multiple times, as some DACs go into never-never land... */
240 for(j=0; j<100; j++) {
241 if((retVal = sst1InitExecuteDacRdWr(sstbase, dacPtr->detect))
242 == FXTRUE) {
243 iniDac = dacPtr;
244 break;
245 }
246 }
247 if(retVal == FXTRUE)
248 break;
249 }
250 dacPtr = dacPtr->nextDac;
251 }
252 return(retVal);
253}
254
255FxBool sst1InitDacDetectATT(FxU32 * sstbase)
256{
257 FxU32 n, j, dacmir, dacdir;
258 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
259
260 if(helper)
261 INIT_PRINTF(("sst1InitDacDetectATT(): Entered...\n"));
262
263 /* Detect ATT */
264 /* Sometimes the DACs seem to go into never-never land, so */
265 /* try and initialize the DAC multiple times */
266 n = 0;
267 while(1) {
268 if(++n > 100)
269 break;
270
271 /* Must guarantee that no rendering is being performed */
272 sst1InitIdleFBINoNOP(sstbase);
273
274 /* Reset current state of DAC command register 0 (CR0) via the read */
275 /* mask register (RMR) */
276 sst1InitDacWr(sstbase, SST_DACREG_WMA, 0x0); /* reset backdoor fsm */
277 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* RMR must be read 5 times */
278 sst1InitDacRd(sstbase, SST_DACREG_RMR);
279 sst1InitDacRd(sstbase, SST_DACREG_RMR);
280 sst1InitDacRd(sstbase, SST_DACREG_RMR);
281 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* Returns contents of CR0 */
282
283 /* Enable indexed programming by setting CR0[0] = 1 */
284 sst1InitDacWr(sstbase, SST_DACREG_WMA, 0x0); /* reset backdoor fsm */
285 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* RMR must be read 4 times */
286 sst1InitDacRd(sstbase, SST_DACREG_RMR);
287 sst1InitDacRd(sstbase, SST_DACREG_RMR);
288 sst1InitDacRd(sstbase, SST_DACREG_RMR);
289 sst1InitDacWr(sstbase, SST_DACREG_RMR,
290 SST_DACREG_CR0_INDEXED_ADDRESSING | SST_DACREG_CR0_8BITDAC);
291
292 /* NOW DAC IS IN INDEXED ADDRESS MODE... */
293
294 /* Check the manufacturing ID */
295 j = 0;
296 DAC_INDEXWRADDR(SST_DACREG_INDEX_MIR);
297 dacmir = DAC_INDEXRD();
298 if(dacmir == SST_DACREG_INDEX_MIR_ATT_DEFAULT)
299 j++;
300 else
301 continue;
302
303 /* Check the device ID */
304 DAC_INDEXWRADDR(SST_DACREG_INDEX_DIR);
305 dacdir = DAC_INDEXRD();
306 if(dacmir == SST_DACREG_INDEX_MIR_ATT_DEFAULT &&
307 dacdir == SST_DACREG_INDEX_DIR_ATT_DEFAULT)
308 j++;
309 else
310 continue;
311 if(j == 2) {
312 /* Found ATT DAC... */
313 sst1CurrentBoard->fbiVideoDacType = SST_FBI_DACTYPE_ATT;
314 sst1InitIdleFBINoNOP(sstbase);
315 /* Disable indexed-mode addressing */
316 sst1InitDacWr(sstbase, SST_DACREG_INDEXADDR, SST_DACREG_INDEX_CR0);
317 sst1InitDacWr(sstbase, SST_DACREG_INDEXDATA,
318 sst1InitDacRd(sstbase, SST_DACREG_INDEXDATA) &
319 ~SST_DACREG_CR0_INDEXED_ADDRESSING);
320 if(helper)
321 INIT_PRINTF(("sst1InitDacDetectATT(): Exiting...\n"));
322 return(FXTRUE);
323 }
324 }
325 if(helper)
326 INIT_PRINTF(("sst1InitDacDetectATT(): Exiting...\n"));
327 return(FXFALSE);
328}
329
330FxBool sst1InitDacDetectTI(FxU32 * sstbase)
331{
332 FxU32 n, j, dacmir, dacdir;
333 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
334
335 if(helper)
336 INIT_PRINTF(("sst1InitDacDetectTI(): Entered...\n"));
337
338 /* Detect TI */
339 /* Sometimes the DACs seem to go into never-never land, so */
340 /* try and initialize the DAC multiple times */
341 n = 0;
342 while(1) {
343 if(++n > 100)
344 break;
345
346 /* Must guarantee that no rendering is being performed */
347 sst1InitIdleFBINoNOP(sstbase);
348
349 /* Reset current state of DAC command register 0 (CR0) via the read */
350 /* mask register (RMR) */
351 sst1InitDacWr(sstbase, SST_DACREG_WMA, 0x0); /* reset backdoor fsm */
352 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* RMR must be read 5 times */
353 sst1InitDacRd(sstbase, SST_DACREG_RMR);
354 sst1InitDacRd(sstbase, SST_DACREG_RMR);
355 sst1InitDacRd(sstbase, SST_DACREG_RMR);
356 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* Returns contents of CR0 */
357
358 /* Enable indexed programming by setting CR0[0] = 1 */
359 sst1InitDacWr(sstbase, SST_DACREG_WMA, 0x0); /* reset backdoor fsm */
360 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* RMR must be read 4 times */
361 sst1InitDacRd(sstbase, SST_DACREG_RMR);
362 sst1InitDacRd(sstbase, SST_DACREG_RMR);
363 sst1InitDacRd(sstbase, SST_DACREG_RMR);
364 sst1InitDacWr(sstbase, SST_DACREG_RMR,
365 SST_DACREG_CR0_INDEXED_ADDRESSING | SST_DACREG_CR0_8BITDAC);
366
367 /* NOW DAC IS IN INDEXED ADDRESS MODE... */
368
369 /* Check the manufacturing ID */
370 j = 0;
371 DAC_INDEXWRADDR(SST_DACREG_INDEX_MIR);
372 dacmir = DAC_INDEXRD();
373 if(dacmir == SST_DACREG_INDEX_MIR_TI_DEFAULT)
374 j++;
375 else
376 continue;
377
378 /* Check the device ID */
379 DAC_INDEXWRADDR(SST_DACREG_INDEX_DIR);
380 dacdir = DAC_INDEXRD();
381 if(dacmir == SST_DACREG_INDEX_MIR_TI_DEFAULT &&
382 dacdir == SST_DACREG_INDEX_DIR_TI_DEFAULT)
383 j++;
384 else
385 continue;
386 if(j == 2) {
387 /* Found TI DAC... */
388 sst1CurrentBoard->fbiVideoDacType = SST_FBI_DACTYPE_TI;
389 sst1InitIdleFBINoNOP(sstbase);
390 /* Disable indexed-mode addressing */
391 sst1InitDacWr(sstbase, SST_DACREG_INDEXADDR, SST_DACREG_INDEX_CR0);
392 sst1InitDacWr(sstbase, SST_DACREG_INDEXDATA,
393 sst1InitDacRd(sstbase, SST_DACREG_INDEXDATA) &
394 ~SST_DACREG_CR0_INDEXED_ADDRESSING);
395 if(helper)
396 INIT_PRINTF(("sst1InitDacDetectTI(): Exiting...\n"));
397 return(FXTRUE);
398 }
399 }
400 if(helper)
401 INIT_PRINTF(("sst1InitDacDetectTI(): Exiting...\n"));
402 return(FXFALSE);
403}
404
405FxBool sst1InitDacDetectICS(FxU32 * sstbase)
406{
407 FxU32 n;
408 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
409
410 if(helper)
411 INIT_PRINTF(("sst1InitDacDetectICS(): Entered...\n"));
412
413 /* Detect ICS... */
414 /* Sometimes the DACs seem to go into never-never land, so */
415 /* try and initialize the DAC multiple times */
416 n = 0;
417 while(1) {
418 FxU32 gclk1, vclk1, vclk7;
419
420 if(++n > 100)
421 break;
422 /* Must guarantee that no rendering is being performed */
423 sst1InitIdleFBINoNOP(sstbase);
424
425 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_RD,
426 SST_DACREG_ICS_PLLADDR_GCLK1);
427 gclk1 = sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
428 sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
429 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_RD,
430 SST_DACREG_ICS_PLLADDR_VCLK1);
431 vclk1 = sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
432 sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
433 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_RD,
434 SST_DACREG_ICS_PLLADDR_VCLK7);
435 vclk7 = sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
436 sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
437 if((gclk1 == SST_DACREG_ICS_PLLADDR_GCLK1_DEFAULT) &&
438 (vclk1 == SST_DACREG_ICS_PLLADDR_VCLK1_DEFAULT) &&
439 (vclk7 == SST_DACREG_ICS_PLLADDR_VCLK7_DEFAULT)) {
440 /* found ICS DAC... */
441 sst1CurrentBoard->fbiVideoDacType = SST_FBI_DACTYPE_ICS;
442 if(helper)
443 INIT_PRINTF(("sst1InitDacDetectICS(): Exiting...\n"));
444 return(FXTRUE);
445 }
446 }
447
448
449 if(helper)
450 INIT_PRINTF(("sst1InitDacDetectICS(): Exiting...\n"));
451 return(FXFALSE);
452}
453
454/*
455** sst1InitCalcGrxClk():
456** Determine graphics clock frequency
457** NOTE: sst1InitCalcGrxClk() must be called prior to sst1InitGrxClk()
458**
459*/
460FX_EXPORT FxBool FX_CSTYLE sst1InitCalcGrxClk(FxU32 *sstbase)
461{
462 FxU32 clkFreq;
463 SstRegs *sst = (SstRegs *) sstbase;
464
465 if(sst1InitCheckBoard(sstbase) == FXFALSE)
466 return(FXFALSE);
467
468 if(GETENV(("SSTV2_GRXCLK"))) {
469 INIT_PRINTF(("sst1InitCalcGrxClk(): Overriding default clk frequency with SST_GRXCLK\n"));
470 clkFreq = ATOI(GETENV(("SSTV2_GRXCLK")));
471 if(clkFreq < 16)
472 clkFreq = 16;
473 } else {
474 if(sst1CurrentBoard->numberTmus == 1 &&
475 sst1CurrentBoard->fbiMemSize == 2 &&
476 sst1CurrentBoard->tmuMemSize[0] == 2)
477 clkFreq = 83;
478 else
479 // clkFreq = 50 + (value of fb_data[63:58] latched during reset)
480 clkFreq = 50 + ((IGET(sst->fbiInit7) >> 2) & 0x3f);
481 }
482 sst1CurrentBoard->fbiGrxClkFreq = clkFreq;
483 sst1CurrentBoard->tmuGrxClkFreq = clkFreq;
484 return(FXTRUE);
485}
486
487/*
488** sst1InitGrxClk():
489** Initialize FBI and TREX Memory clocks
490** NOTE: sst1InitCalcGrxClk() must be called prior to sst1InitGrxClk()
491** NOTE: sst1InitGrxClk() resets the PCI fifo and the graphics subsystem of FBI
492**
493*/
494FX_EXPORT FxBool FX_CSTYLE sst1InitGrxClk(FxU32 *sstbase)
495{
496 sst1ClkTimingStruct sstGrxClk;
497
498 if(sst1InitCheckBoard(sstbase) == FXFALSE)
499 return(FXFALSE);
500 if(sst1CurrentBoard->initGrxClkDone)
501 return(FXTRUE);
502 sst1CurrentBoard->initGrxClkDone = 1;
503
504 INIT_PRINTF(("sst1InitGrxClk(): Setting up %d MHz Graphics Clock...\n",
505 sst1CurrentBoard->fbiGrxClkFreq));
506 if(sst1CurrentBoard->sliDetected) {
507 sst1CurrentBoard->fbiGrxClkFreq -= 5;
508 sst1CurrentBoard->tmuGrxClkFreq -= 5;
509 }
510 if(sst1InitComputeClkParams((float) sst1CurrentBoard->fbiGrxClkFreq,
511 &sstGrxClk) == FXFALSE)
512 return(FXFALSE);
513
514 return(sst1InitSetGrxClk(sstbase, &sstGrxClk));
515}
516
517/*
518** sst1InitComputeClkParams():
519** Compute PLL parameters for given clock frequency
520**
521*/
522FX_EXPORT FxBool FX_CSTYLE sst1InitComputeClkParams(float freq,
523 sst1ClkTimingStruct *clkTiming)
524{
525 if(sst1CurrentBoard->fbiVideoDacType == SST_FBI_DACTYPE_TI)
526 return(sst1InitComputeClkParamsTI(freq, clkTiming));
527 else
528 return(sst1InitComputeClkParamsATT(freq, clkTiming));
529}
530
531/*
532** sst1InitComputeClkParamsATT():
533** Compute PLL parameters for given clock frequency (ATT DACs)
534**
535*/
536FxBool sst1InitComputeClkParamsATT(float freq, sst1ClkTimingStruct
537 *clkTiming)
538{
539 float vcoFreqDivide, freqMultRatio, clkError;
540 float clkErrorMin;
541 FxU32 p, n, m, nPlusTwo;
542 int mPlusTwo;
543
544 /* Calculate P parameter */
545 p = 4;
546 if(((freq * (float) 1.) >= (float) 120.) &&
547 ((freq * (float) 1.) <= (float) 240.)) {
548 vcoFreqDivide = (float) 1.;
549 p = 0;
550 }
551 if(((freq * (float) 2.) >= (float) 120.) &&
552 ((freq * (float) 2.) <= (float) 240.)) {
553 vcoFreqDivide = (float) 2.;
554 p = 1;
555 }
556 if(((freq * (float) 4.) >= (float) 120.) &&
557 ((freq * (float) 4.) <= (float) 240.)) {
558 vcoFreqDivide = (float) 4.;
559 p = 2;
560 }
561 if(((freq * (float) 8.) >= (float) 120.) &&
562 ((freq * (float) 8.) <= (float) 240.)) {
563 vcoFreqDivide = (float) 8.;
564 p = 3;
565 }
566 if(p > 3)
567 return(FXFALSE);
568
569 /* Divide by 14.318 */
570 freqMultRatio = (freq * vcoFreqDivide) * (float) 0.06984216;
571
572 /* Calculate proper N and M parameters which yield the lowest error */
573 clkErrorMin = (float) 9999.; n = 0;
574 for(nPlusTwo = 3; nPlusTwo < 32; nPlusTwo++) {
575#ifdef DIRECTX
576 mPlusTwo = FTOL( (((float) nPlusTwo * freqMultRatio) + (float) 0.5) );
577 clkError = ((float) mPlusTwo * ITOF_INV( nPlusTwo ) ) - freqMultRatio;
578#else
579 mPlusTwo = (int) (((float) nPlusTwo * freqMultRatio) + (float) 0.5);
580 clkError = ((float) mPlusTwo / (float) nPlusTwo) - freqMultRatio;
581#endif
582 if(clkError < (float) 0.0)
583 clkError = -clkError;
584 if((clkError < clkErrorMin) && ((mPlusTwo - 2) < 127)) {
585 clkErrorMin = clkError;
586 n = nPlusTwo - 2;
587 m = mPlusTwo - 2;
588 }
589 }
590 if(n == 0)
591 return(FXFALSE);
592
593 clkTiming->freq = freq;
594 clkTiming->clkTiming_M = m;
595 clkTiming->clkTiming_P = p;
596 clkTiming->clkTiming_N = n;
597 if(freq < (float) 37.) {
598 clkTiming->clkTiming_L = 0xa;
599 clkTiming->clkTiming_IB = 0x6;
600 } else if(freq < (float) 45.) {
601 clkTiming->clkTiming_L = 0xc;
602 clkTiming->clkTiming_IB = 0x4;
603 } else if(freq < (float) 58.) {
604 clkTiming->clkTiming_L = 0x8;
605 clkTiming->clkTiming_IB = 0x4;
606 } else if(freq < (float) 66.) {
607 clkTiming->clkTiming_L = 0xa;
608 clkTiming->clkTiming_IB = 0x6;
609 } else {
610 clkTiming->clkTiming_L = 0xa;
611 clkTiming->clkTiming_IB = 0x8;
612 }
613#if 0
614 {
615 float calc;
616
617 calc = ((float) 14.318 * (float) (m + 2)) /
618 ((float) (n + 2) * vcoFreqDivide);
619 printf("freq:%.3f calc:%.3f\n", freq, calc);
620 printf("m:%d p:%d n:%d\n", m, p, n);
621 fflush(stdout);
622 }
623#endif
624 return(FXTRUE);
625}
626
627/*
628** sst1InitComputeClkParamsTI():
629** Compute PLL parameters for given clock frequency (TI DACs)
630**
631*/
632FxBool sst1InitComputeClkParamsTI(float freq, sst1ClkTimingStruct
633 *clkTiming)
634{
635 float clkError, clkErrorMin;
636 FxU32 p, n, m, pBest, nBest, mBest;
637 float lowVCO, highVCO;
638
639 //lowVCO = (float) 120.; highVCO = (float) 240.;
640 lowVCO = (float) 80.; highVCO = (float) 150.;
641
642 /* Loop through all the possible combinations and find the frequency
643 with the least error */
644 clkErrorMin = (float) 9999.; nBest = 9999;
645 for(p=0; p<4; p++) {
646 for(m=0; m<64; m++) {
647 for(n=0; n<5; n++) {
648 float clkFreq, vcoFreq;
649 float pFreqDivide;
650 float mPlusTwo = (float) m + (float) 2.0;
651 float nPlusTwo = (float) n + (float) 2.0;
652
653 if(p == 0) pFreqDivide = (float) 1.0;
654 else if(p == 1) pFreqDivide = (float) 2.0;
655 else if(p == 2) pFreqDivide = (float) 4.0;
656 else pFreqDivide = (float) 8.0;
657
658 clkFreq = ((float) 14.31818 * mPlusTwo) / (nPlusTwo * pFreqDivide);
659 vcoFreq = ((float) 14.31818 * mPlusTwo) / (nPlusTwo);
660 clkError = freq - clkFreq;
661 if(clkError < (float) 0.0)
662 clkError = -clkError;
663 if(clkError < clkErrorMin && vcoFreq >= lowVCO &&
664 vcoFreq <= highVCO) {
665 clkErrorMin = clkError;
666 pBest = p;
667 mBest = m;
668 nBest = n;
669 }
670 }
671 }
672 }
673
674 if(nBest == 9999) return(FXFALSE);
675
676 clkTiming->freq = freq;
677 clkTiming->clkTiming_M = mBest;
678 clkTiming->clkTiming_P = pBest;
679 clkTiming->clkTiming_N = nBest;
680 // L and IB params are not used by TI DACs...
681 clkTiming->clkTiming_L = 0;
682 clkTiming->clkTiming_IB = 0;
683
684#if 0
685 {
686 float clkFreq, vcoFreq, pFreqDivide;
687
688 if(clkTiming->clkTiming_P == 0) pFreqDivide = (float) 1.0;
689 else if(clkTiming->clkTiming_P == 1) pFreqDivide = (float) 2.0;
690 else if(clkTiming->clkTiming_P == 2) pFreqDivide = (float) 4.0;
691 else pFreqDivide = (float) 8.0;
692
693 clkFreq = ((float) 14.31818 * (float) (clkTiming->clkTiming_M + 2)) /
694 ((float) (clkTiming->clkTiming_N + 2) * pFreqDivide);
695 vcoFreq = ((float) 14.31818 * (float) (clkTiming->clkTiming_M + 2)) /
696 ((float) (clkTiming->clkTiming_N + 2));
697
698 printf("freq:%.3f calc:%.3f\n", freq, clkFreq);
699 printf("m:%d p:%d n:%d vco:%.2f\n", clkTiming->clkTiming_M,
700 clkTiming->clkTiming_P, clkTiming->clkTiming_N, vcoFreq);
701 printf("lowVCO:%.2f highVCO:%.2f\n", lowVCO, highVCO);
702 fflush(stdout);
703 }
704#endif
705 return(FXTRUE);
706}
707
708/*
709** sst1InitSetVidClkATT():
710** Set video clock for ATT Dacs
711**
712*/
713FxBool sst1InitSetVidClkATT(FxU32 *sstbase, sst1ClkTimingStruct
714 *sstVidClk)
715{
716 if(sst1InitDacIndexedEnable(sstbase, 1) == FXFALSE)
717 return(FXFALSE);
718
719 DAC_INDEXWRADDR(SST_DACREG_INDEX_AD0);
720 DAC_INDEXWR((sstVidClk->clkTiming_M) << SST_DACREG_CLKREG_MSHIFT);
721 DAC_INDEXWRADDR(SST_DACREG_INDEX_AD1);
722 DAC_INDEXWR(((sstVidClk->clkTiming_P) << SST_DACREG_CLKREG_PSHIFT) |
723 ((sstVidClk->clkTiming_N)
724 << SST_DACREG_CLKREG_NSHIFT));
725 DAC_INDEXWRADDR(SST_DACREG_INDEX_AD2);
726 DAC_INDEXWR(((sstVidClk->clkTiming_L) << SST_DACREG_CLKREG_LSHIFT) |
727 ((sstVidClk->clkTiming_IB) << SST_DACREG_CLKREG_IBSHIFT));
728 DAC_INDEXWRADDR(SST_DACREG_INDEX_CC);
729 DAC_INDEXWR((DAC_INDEXRD() | (0x3 << SST_DACREG_CC_ACLK_SEL_SHIFT) |
730 SST_DACREG_CC_ACLK_SELECT_AD));
731 DAC_INDEXWRADDR(SST_DACREG_INDEX_CC);
732
733 if(sst1InitDacIndexedEnable(sstbase, 0) == FXFALSE)
734 return(FXFALSE);
735
736 return(FXTRUE);
737}
738
739/*
740** sst1InitSetVidClkICS():
741** Set video clock for ICS Dacs
742**
743*/
744FxBool sst1InitSetVidClkICS(FxU32 *sstbase, sst1ClkTimingStruct
745 *sstVidClk)
746{
747 FxU32 n, fbiInit1_save, fbiInit2_save, pllCtrl, cfgInitEnable;
748 SstRegs *sst = (SstRegs *) sstbase;
749
750 sst1InitIdleFBINoNOP(sstbase);
751
752 /* Save init register states before overwriting them */
753 fbiInit1_save = IGET(sst->fbiInit1);
754 fbiInit2_save = IGET(sst->fbiInit2);
755
756 /* Reset video unit to guarantee no contentions on the memory bus */
757 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
758 /* Turn off dram refresh to guarantee no contentions on the memory bus */
759 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
760 sst1InitIdleFBINoNOP(sstbase);
761
762 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
763 /* Disallow writes to pass through the PCI FIFO */
764 PCICFG_RD(SST1_PCI_INIT_ENABLE, cfgInitEnable);
765 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable | SST_FBIINIT23_REMAP);
766 sst1InitIdleFBINoNOP(sstbase);
767
768 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_RD,
769 SST_DACREG_ICS_PLLADDR_CTRL);
770 pllCtrl = sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
771
772 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_WR,
773 SST_DACREG_ICS_PLLADDR_VCLK0);
774 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_DATA,
775 sstVidClk->clkTiming_M);
776 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_DATA,
777 (((sstVidClk->clkTiming_P) << 5) | sstVidClk->clkTiming_N));
778 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_WR,
779 SST_DACREG_ICS_PLLADDR_CTRL);
780 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_DATA,
781 ((pllCtrl & ~SST_DACREG_ICS_PLLCTRL_CLK0FREQ) |
782 SST_DACREG_ICS_PLLCTRL_CLK0SEL));
783 sst1InitIdleFBINoNOP(sstbase);
784
785 /* Disable fbiinit23 address remapping */
786 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable);
787
788 /* Restore init register states */
789 sst1InitIdleFBINoNOP(sstbase);
790 ISET(sst->fbiInit1, fbiInit1_save);
791 ISET(sst->fbiInit2, fbiInit2_save);
792 sst1InitIdleFBINoNOP(sstbase);
793
794 return(FXTRUE);
795}
796
797/*
798** sst1InitSetVidClkINI():
799** Set video clock for DACs defined in "voodoo2.ini"
800**
801*/
802FxBool sst1InitSetVidClkINI(FxU32 *sstbase, FxU32 width,
803 FxU32 height, FxU32 refresh, FxU32 video16BPP)
804{
805 FxU32 n, fbiInit1_save, fbiInit2_save, cfgInitEnable;
806 sst1InitDacSetVideoStruct *setVideo;
807 SstRegs *sst = (SstRegs *) sstbase;
808 int helper = (GETENV(("SSTV2_DEBUGDAC"))) ? 1 : 0;
809 FxBool retVal = FXFALSE;
810
811 if(helper)
812 INIT_PRINTF(("sst1InitSetVidClkINI(): Entered...\n"));
813
814 if(iniDac == (sst1InitDacStruct *) NULL)
815 return(FXFALSE);
816
817 if(sst1InitCheckBoard(sstbase) == FXFALSE)
818 return(FXFALSE);
819
820 sst1InitIdleFBINoNOP(sstbase);
821
822 /* Save init register states before overwriting them */
823 fbiInit1_save = IGET(sst->fbiInit1);
824 fbiInit2_save = IGET(sst->fbiInit2);
825
826 /* Reset video unit to guarantee no contentions on the memory bus */
827 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
828 /* Turn off dram refresh to guarantee no contentions on the memory bus */
829 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
830 sst1InitIdleFBINoNOP(sstbase);
831
832 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
833 /* Disallow writes to pass through the PCI FIFO */
834 PCICFG_RD(SST1_PCI_INIT_ENABLE, cfgInitEnable);
835 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable | SST_FBIINIT23_REMAP);
836 sst1InitIdleFBINoNOP(sstbase);
837
838 setVideo = iniDac->setVideo;
839 while(setVideo) {
840 if((setVideo->width == width) && (setVideo->height == height) &&
841 (setVideo->refresh == refresh) &&
842 (setVideo->video16BPP == video16BPP)) {
843 if((retVal = sst1InitExecuteDacRdWr(sstbase,
844 setVideo->setVideoRdWr)) == FXTRUE) {
845 retVal = FXTRUE;
846 break;
847 }
848 }
849 setVideo = setVideo->nextSetVideo;
850 }
851
852 /* Disable fbiinit23 address remapping */
853 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable);
854
855 /* Restore init register states */
856 sst1InitIdleFBINoNOP(sstbase);
857 ISET(sst->fbiInit1, fbiInit1_save);
858 ISET(sst->fbiInit2, fbiInit2_save);
859 sst1InitIdleFBINoNOP(sstbase);
860
861 return(retVal);
862}
863
864/*
865** sst1InitSetGrxClkATT():
866** Set graphics clock for ATT Dacs
867** NOTE: sst1InitSetGrxClkATT() resets the PCI fifo and the graphics subsystem
868** of FBI
869**
870*/
871FxBool sst1InitSetGrxClkATT(FxU32 *sstbase, sst1ClkTimingStruct
872 *sstGrxClk)
873{
874 FxU32 n;
875 SstRegs *sst = (SstRegs *) sstbase;
876
877 /* Reset graphics unit before we change grx clk */
878 ISET(sst->fbiInit0, IGET(sst->fbiInit0) |
879 (SST_GRX_RESET | SST_PCI_FIFO_RESET));
880 sst1InitIdleFBINoNOP(sstbase);
881
882 /* Enable DAC indexed addressing */
883 /* sst1InitDacIndexedEnable resets the video module, turns off dram refresh */
884 /* and disallows writes to the PCI fifo */
885 if(sst1InitDacIndexedEnable(sstbase, 1) == FXFALSE)
886 return(FXFALSE);
887
888 DAC_INDEXWRADDR(SST_DACREG_INDEX_BD0);
889 DAC_INDEXWR((sstGrxClk->clkTiming_M) << SST_DACREG_CLKREG_MSHIFT);
890 DAC_INDEXWRADDR(SST_DACREG_INDEX_BD1);
891 DAC_INDEXWR(((sstGrxClk->clkTiming_P) << SST_DACREG_CLKREG_PSHIFT) |
892 ((sstGrxClk->clkTiming_N) << SST_DACREG_CLKREG_NSHIFT));
893 DAC_INDEXWRADDR(SST_DACREG_INDEX_BD2);
894 DAC_INDEXWR(((sstGrxClk->clkTiming_L) << SST_DACREG_CLKREG_LSHIFT) |
895 ((sstGrxClk->clkTiming_IB) << SST_DACREG_CLKREG_IBSHIFT));
896 DAC_INDEXWRADDR(SST_DACREG_INDEX_CC);
897 DAC_INDEXWR((DAC_INDEXRD() | (0x3 << SST_DACREG_CC_BCLK_SEL_SHIFT) |
898 SST_DACREG_CC_BCLK_SELECT_BD));
899 sst1InitIdleFBINoNOP(sstbase);
900
901 /* Turn off DAC indexed addressing */
902
903 /* Disabling dac indexed mode re-enables writes to pass through the */
904 /* PCI fifo (and restores video refresh and dram refresh if previously */
905 /* enabled) */
906 if(sst1InitDacIndexedEnable(sstbase, 0) == FXFALSE)
907 return(FXFALSE);
908
909 /* Wait for graphics clock to stabilize */
910 for(n=0; n<200000; n++)
911 sst1InitReturnStatus(sstbase);
912
913 /* Unreset PCI FIFO and graphic subsystem */
914 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_PCI_FIFO_RESET);
915 sst1InitIdleFBINoNOP(sstbase);
916 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_GRX_RESET);
917 sst1InitIdleFBINoNOP(sstbase);
918
919 return(FXTRUE);
920}
921
922/*
923** sst1InitSetGrxClkICS():
924** Set graphics clock for ICS Dacs
925** NOTE: sst1InitSetGrxClkICS() resets the PCI fifo and the graphics subsystem
926** of FBI
927**
928*/
929FxBool sst1InitSetGrxClkICS(FxU32 *sstbase, sst1ClkTimingStruct
930 *sstGrxClk)
931{
932 FxU32 n, fbiInit1_save, fbiInit2_save, pllCtrl, cfgInitEnable;
933 SstRegs *sst = (SstRegs *) sstbase;
934
935 /* Reset graphics unit before we change grx clk */
936 ISET(sst->fbiInit0, IGET(sst->fbiInit0) |
937 (SST_GRX_RESET | SST_PCI_FIFO_RESET));
938 sst1InitIdleFBINoNOP(sstbase);
939
940 /* Save init register states before overwriting them */
941 fbiInit1_save = IGET(sst->fbiInit1);
942 fbiInit2_save = IGET(sst->fbiInit2);
943
944 /* Reset video unit to guarantee no contentions on the memory bus */
945 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
946 /* Turn off dram refresh to guarantee no contentions on the memory bus */
947 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
948 sst1InitIdleFBINoNOP(sstbase);
949
950 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
951 /* Disallow writes to pass through the PCI FIFO */
952 PCICFG_RD(SST1_PCI_INIT_ENABLE, cfgInitEnable);
953 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable | SST_FBIINIT23_REMAP);
954 sst1InitIdleFBINoNOP(sstbase);
955
956 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_RD,
957 SST_DACREG_ICS_PLLADDR_CTRL);
958 pllCtrl = sst1InitDacRd(sstbase, SST_DACREG_ICS_PLLADDR_DATA);
959
960 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_WR,
961 SST_DACREG_ICS_PLLADDR_GCLK0);
962 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_DATA,
963 sstGrxClk->clkTiming_M);
964 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_DATA,
965 (((sstGrxClk->clkTiming_P) << 5) | sstGrxClk->clkTiming_N));
966 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_WR,
967 SST_DACREG_ICS_PLLADDR_CTRL);
968 sst1InitDacWr(sstbase, SST_DACREG_ICS_PLLADDR_DATA,
969 (pllCtrl & ~SST_DACREG_ICS_PLLCTRL_CLK1SEL));
970 sst1InitIdleFBINoNOP(sstbase);
971
972 /* Disable fbiinit23 address remapping */
973 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable);
974
975 /* Restore init register states */
976 sst1InitIdleFBINoNOP(sstbase);
977 ISET(sst->fbiInit1, fbiInit1_save);
978 ISET(sst->fbiInit2, fbiInit2_save);
979 sst1InitIdleFBINoNOP(sstbase);
980
981 /* Wait for graphics clock to stabilize */
982 for(n=0; n<200000; n++)
983 sst1InitReturnStatus(sstbase);
984
985 /* Unreset PCI FIFO and graphic subsystem */
986 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_PCI_FIFO_RESET);
987 sst1InitIdleFBINoNOP(sstbase);
988 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_GRX_RESET);
989 sst1InitIdleFBINoNOP(sstbase);
990
991 return(FXTRUE);
992}
993
994/*
995** sst1InitSetGrxClkINI():
996** Set graphics clock for dac specified in "voodoo2.ini" file
997** NOTE: sst1InitSetGrxClkINI() resets the PCI fifo and the graphics subsystem
998** of FBI
999**
1000*/
1001FxBool sst1InitSetGrxClkINI(FxU32 *sstbase, sst1ClkTimingStruct
1002 *sstGrxClk)
1003{
1004 FxU32 n, fbiInit1_save, fbiInit2_save, cfgInitEnable;
1005 sst1InitDacSetMemClkStruct *setMemClk;
1006 FxBool retVal = FXFALSE;
1007 SstRegs *sst = (SstRegs *) sstbase;
1008
1009 if(iniDac == (sst1InitDacStruct *) NULL)
1010 return(FXFALSE);
1011
1012 /* Reset graphics unit before we change grx clk */
1013 ISET(sst->fbiInit0, IGET(sst->fbiInit0) |
1014 (SST_GRX_RESET | SST_PCI_FIFO_RESET));
1015 sst1InitIdleFBINoNOP(sstbase);
1016
1017 /* Save init register states before overwriting them */
1018 fbiInit1_save = IGET(sst->fbiInit1);
1019 fbiInit2_save = IGET(sst->fbiInit2);
1020
1021 /* Reset video unit to guarantee no contentions on the memory bus */
1022 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
1023 /* Turn off dram refresh to guarantee no contentions on the memory bus */
1024 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
1025 sst1InitIdleFBINoNOP(sstbase);
1026
1027 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
1028 /* Disallow writes to pass through the PCI FIFO */
1029 PCICFG_RD(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1030 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable | SST_FBIINIT23_REMAP);
1031 sst1InitIdleFBINoNOP(sstbase);
1032
1033 setMemClk = iniDac->setMemClk;
1034 while(setMemClk) {
1035 if(setMemClk->frequency == (FxU32) sstGrxClk->freq) {
1036 if((retVal = sst1InitExecuteDacRdWr(sstbase,
1037 setMemClk->setMemClkRdWr)) == FXTRUE) {
1038 retVal = FXTRUE;
1039 break;
1040 }
1041 }
1042 setMemClk = setMemClk->nextSetMemClk;
1043 }
1044 /* Disable fbiinit23 address remapping */
1045 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1046
1047 /* Restore init register states */
1048 sst1InitIdleFBINoNOP(sstbase);
1049 ISET(sst->fbiInit1, fbiInit1_save);
1050
1051 ISET(sst->fbiInit2, fbiInit2_save);
1052 sst1InitIdleFBINoNOP(sstbase);
1053
1054 /* Wait for graphics clock to stabilize */
1055 if(retVal == FXTRUE) {
1056 for(n=0; n<200000; n++)
1057 sst1InitReturnStatus(sstbase);
1058 }
1059
1060 /* Unreset PCI FIFO and graphic subsystem */
1061 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_PCI_FIFO_RESET);
1062 sst1InitIdleFBINoNOP(sstbase);
1063 ISET(sst->fbiInit0, IGET(sst->fbiInit0) & ~SST_GRX_RESET);
1064 sst1InitIdleFBINoNOP(sstbase);
1065
1066 return(retVal);
1067}
1068
1069/*
1070** sst1InitSetVidModeATT():
1071** Set video Mode for ATT dacs
1072**
1073*/
1074FxBool sst1InitSetVidModeATT(FxU32 *sstbase, FxU32 video16BPP)
1075{
1076 if(sst1InitDacIndexedEnable(sstbase, 1) == FXFALSE)
1077 return(FXFALSE);
1078
1079 /* Set 16 or 24-bit pixel output */
1080 if(video16BPP) {
1081 DAC_INDEXWRADDR(SST_DACREG_INDEX_CR0);
1082 DAC_INDEXWR((DAC_INDEXRD() & ~SST_DACREG_CR0_COLOR_MODE) |
1083 SST_DACREG_CR0_COLOR_MODE_16BPP | SST_DACREG_CR0_8BITDAC);
1084 } else {
1085 DAC_INDEXWRADDR(SST_DACREG_INDEX_CR0);
1086 DAC_INDEXWR((DAC_INDEXRD() & ~SST_DACREG_CR0_COLOR_MODE) |
1087 SST_DACREG_CR0_COLOR_MODE_24BPP | SST_DACREG_CR0_8BITDAC);
1088 }
1089
1090 if(sst1InitDacIndexedEnable(sstbase, 0) == FXFALSE)
1091 return(FXFALSE);
1092
1093
1094 return(FXTRUE);
1095}
1096
1097/*
1098** sst1InitSetVidModeICS():
1099** Set video Mode for ICS dacs
1100**
1101*/
1102FxBool sst1InitSetVidModeICS(FxU32 *sstbase, FxU32 video16BPP)
1103{
1104 FxU32 n, fbiInit1_save, fbiInit2_save, cfgInitEnable;
1105 SstRegs *sst = (SstRegs *) sstbase;
1106
1107 sst1InitIdleFBINoNOP(sstbase);
1108
1109 /* Save init register states before overwriting them */
1110 fbiInit1_save = IGET(sst->fbiInit1);
1111 fbiInit2_save = IGET(sst->fbiInit2);
1112
1113 /* Reset video unit to guarantee no contentions on the memory bus */
1114 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
1115 /* Turn off dram refresh to guarantee no contentions on the memory bus */
1116 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
1117 sst1InitIdleFBINoNOP(sstbase);
1118
1119 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
1120 /* Disallow writes to pass through the PCI FIFO */
1121 PCICFG_RD(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1122 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable | SST_FBIINIT23_REMAP);
1123 sst1InitIdleFBINoNOP(sstbase);
1124
1125 if(video16BPP)
1126 sst1InitDacWr(sstbase, SST_DACREG_ICS_CMD,
1127 SST_DACREG_ICS_COLORMODE_16BPP);
1128 else
1129 sst1InitDacWr(sstbase, SST_DACREG_ICS_CMD,
1130 SST_DACREG_ICS_COLORMODE_24BPP);
1131 sst1InitIdleFBINoNOP(sstbase);
1132
1133 /* Disable fbiinit23 address remapping */
1134 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1135
1136 /* Restore init register states */
1137 sst1InitIdleFBINoNOP(sstbase);
1138 ISET(sst->fbiInit1, fbiInit1_save);
1139 ISET(sst->fbiInit2, fbiInit2_save);
1140 sst1InitIdleFBINoNOP(sstbase);
1141
1142 return(FXTRUE);
1143}
1144
1145/*
1146** sst1InitSetVidModeINI():
1147** Set video Mode for DACs defined in "voodoo2.ini"
1148**
1149*/
1150FxBool sst1InitSetVidModeINI(FxU32 *sstbase, FxU32 video16BPP)
1151{
1152 FxU32 n, fbiInit1_save, fbiInit2_save, cfgInitEnable;
1153 sst1InitDacSetVideoModeStruct *setVideoMode;
1154 FxBool retVal = FXFALSE;
1155 SstRegs *sst = (SstRegs *) sstbase;
1156
1157 if(iniDac == (sst1InitDacStruct *) NULL)
1158 return(FXFALSE);
1159
1160 sst1InitIdleFBINoNOP(sstbase);
1161
1162 /* Save init register states before overwriting them */
1163 fbiInit1_save = IGET(sst->fbiInit1);
1164 fbiInit2_save = IGET(sst->fbiInit2);
1165
1166 /* Reset video unit to guarantee no contentions on the memory bus */
1167 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
1168 /* Turn off dram refresh to guarantee no contentions on the memory bus */
1169 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
1170 sst1InitIdleFBINoNOP(sstbase);
1171
1172 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
1173 /* Disallow writes to pass through the PCI FIFO */
1174 PCICFG_RD(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1175 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable | SST_FBIINIT23_REMAP);
1176 sst1InitIdleFBINoNOP(sstbase);
1177
1178 setVideoMode = iniDac->setVideoMode;
1179 while(setVideoMode) {
1180 if(setVideoMode->video16BPP == video16BPP) {
1181 if((retVal = sst1InitExecuteDacRdWr(sstbase,
1182 setVideoMode->setVideoModeRdWr)) == FXTRUE) {
1183 retVal = FXTRUE;
1184 break;
1185 }
1186 }
1187 setVideoMode = setVideoMode->nextSetVideoMode;
1188 }
1189 sst1InitIdleFBINoNOP(sstbase);
1190
1191 /* Disable fbiinit23 address remapping */
1192 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1193
1194 /* Restore init register states */
1195 sst1InitIdleFBINoNOP(sstbase);
1196 ISET(sst->fbiInit1, fbiInit1_save);
1197 ISET(sst->fbiInit2, fbiInit2_save);
1198 sst1InitIdleFBINoNOP(sstbase);
1199
1200 return(retVal);
1201}
1202
1203/*
1204** sst1InitDacIndexedEnable():
1205** Initialize DAC for indexed-mode addressing
1206** NOTE: When DAC indexed-mode addressing is enabled, video timing and
1207** DRAM refresh are both reset (disabled)
1208**
1209*/
1210FX_EXPORT FxBool FX_CSTYLE sst1InitDacIndexedEnable(FxU32 *sstbase,
1211 FxU32 Enable)
1212{
1213 FxU32 n, j, dacmir, dacdir, cr0_save;
1214 static FxU32 fbiInit1_save = 0;
1215 static FxU32 fbiInit2_save = 0;
1216 static FxU32 cfgInitEnable;
1217 SstRegs *sst = (SstRegs *) sstbase;
1218
1219 if(!sst)
1220 return(FXFALSE);
1221
1222 sst1InitIdleFBINoNOP(sstbase);
1223 if(!Enable) {
1224 /* Disable indexed-mode addressing */
1225 sst1InitDacWr(sstbase, SST_DACREG_INDEXADDR, SST_DACREG_INDEX_CR0);
1226 sst1InitDacWr(sstbase, SST_DACREG_INDEXDATA,
1227 sst1InitDacRd(sstbase, SST_DACREG_INDEXDATA) &
1228 ~SST_DACREG_CR0_INDEXED_ADDRESSING);
1229
1230 /* Disable fbiinit23 address remapping */
1231 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1232
1233 /* Restore init register states */
1234 sst1InitIdleFBINoNOP(sstbase);
1235 if(fbiInit1_save) /* Have we previously enabled indexed addressing? */
1236 ISET(sst->fbiInit1, fbiInit1_save);
1237 if(fbiInit2_save) /* Have we previously enabled indexed addressing? */
1238 ISET(sst->fbiInit2, fbiInit2_save);
1239 sst1InitIdleFBINoNOP(sstbase);
1240 return(FXTRUE);
1241 }
1242
1243 /* Save init register states before overwriting them */
1244 fbiInit1_save = IGET(sst->fbiInit1);
1245 fbiInit2_save = IGET(sst->fbiInit2);
1246
1247 /* Reset video unit to guarantee no contentions on the memory bus */
1248 ISET(sst->fbiInit1, IGET(sst->fbiInit1) | SST_VIDEO_RESET);
1249 /* Turn off dram refresh to guarantee no contentions on the memory bus */
1250 ISET(sst->fbiInit2, IGET(sst->fbiInit2) & ~SST_EN_DRAM_REFRESH);
1251 sst1InitIdleFBINoNOP(sstbase);
1252
1253 /* Enable reads from the DAC (multiplexed on the fbiInit2 address) */
1254 /* Disallow writes to pass through the PCI FIFO */
1255 PCICFG_RD(SST1_PCI_INIT_ENABLE, cfgInitEnable);
1256 PCICFG_WR(SST1_PCI_INIT_ENABLE, cfgInitEnable | SST_FBIINIT23_REMAP);
1257 sst1InitIdleFBINoNOP(sstbase);
1258
1259 /* Sometimes the DACs seem to go into never-never land, so */
1260 /* try and initialize the DAC multiple times */
1261 n = 0;
1262 while(1) {
1263 if(++n > 100) {
1264 INIT_PRINTF(("sst1InitDacIndexedEnable() ERROR: Could not Initialize DAC\n"));
1265 return(FXFALSE);
1266 }
1267
1268 /* Must guarantee that no rendering is being performed */
1269 sst1InitIdleFBINoNOP(sstbase);
1270
1271 /* Reset current state of DAC command register 0 (CR0) via the read */
1272 /* mask register (RMR) */
1273 sst1InitDacWr(sstbase, SST_DACREG_WMA, 0x0); /* reset backdoor fsm */
1274 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* RMR must be read 5 times */
1275 sst1InitDacRd(sstbase, SST_DACREG_RMR);
1276 sst1InitDacRd(sstbase, SST_DACREG_RMR);
1277 sst1InitDacRd(sstbase, SST_DACREG_RMR);
1278 cr0_save = sst1InitDacRd(sstbase, SST_DACREG_RMR);
1279
1280 /* Enable indexed programming by setting CR0[0] = 1 */
1281 sst1InitDacWr(sstbase, SST_DACREG_WMA, 0x0); /* reset backdoor fsm */
1282 sst1InitDacRd(sstbase, SST_DACREG_RMR); /* RMR must be read 4 times */
1283 sst1InitDacRd(sstbase, SST_DACREG_RMR);
1284 sst1InitDacRd(sstbase, SST_DACREG_RMR);
1285 sst1InitDacRd(sstbase, SST_DACREG_RMR);
1286 sst1InitDacWr(sstbase, SST_DACREG_RMR, ((cr0_save & 0xf0) |
1287 SST_DACREG_CR0_INDEXED_ADDRESSING | SST_DACREG_CR0_8BITDAC));
1288
1289 /* NOW DAC IS IN INDEXED ADDRESS MODE... */
1290
1291 /* Check the manufacturing ID for sanity */
1292 j = 0;
1293 DAC_INDEXWRADDR(SST_DACREG_INDEX_MIR);
1294 dacmir = DAC_INDEXRD();
1295
1296 if((dacmir == SST_DACREG_INDEX_MIR_ATT_DEFAULT) ||
1297 (dacmir == SST_DACREG_INDEX_MIR_TI_DEFAULT))
1298 j++;
1299 else
1300 continue;
1301
1302 /* Check the device ID for sanity */
1303 DAC_INDEXWRADDR(SST_DACREG_INDEX_DIR);
1304 dacdir = DAC_INDEXRD();
1305 if((dacmir == SST_DACREG_INDEX_MIR_ATT_DEFAULT &&
1306 dacdir == SST_DACREG_INDEX_DIR_ATT_DEFAULT) ||
1307 (dacmir == SST_DACREG_INDEX_MIR_TI_DEFAULT &&
1308 dacdir == SST_DACREG_INDEX_DIR_TI_DEFAULT))
1309 j++;
1310 else
1311 continue;
1312 if(j == 2)
1313 break;
1314 }
1315 sst1InitIdleFBINoNOP(sstbase);
1316 return(FXTRUE);
1317}
1318
1319#pragma optimize ("",on)
Note: See TracBrowser for help on using the repository browser.