1/*
2 * MGA-1064, MGA-G100, MGA-G200, MGA-G400, MGA-G550 RAMDAC driver
3 */
4
5#ifdef HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9#include "colormapst.h"
10
11/* All drivers should typically include these */
12#include "xf86.h"
13#include "xf86_OSproc.h"
14
15/* Drivers that need to access the PCI config space directly need this */
16#include "xf86Pci.h"
17
18#include "mga_reg.h"
19#include "mga.h"
20#include "mga_macros.h"
21#include "mga_maven.h"
22
23#include "xf86DDC.h"
24
25#include <stdlib.h>
26#include <unistd.h>
27
28/*
29 * implementation
30 */
31
32#define DACREGSIZE 0x50
33
34/*
35 * Only change bits shown in this mask.  Ideally reserved bits should be
36 * zeroed here.  Also, don't change the vgaioen bit here since it is
37 * controlled elsewhere.
38 *
39 * XXX These settings need to be checked.
40 */
41#define OPTION1_MASK	0xFFFFFEFF
42#define OPTION2_MASK	0xFFFFFFFF
43#define OPTION3_MASK	0xFFFFFFFF
44
45#define OPTION1_MASK_PRIMARY	0xFFFC0FF
46
47static void MGAGRamdacInit(ScrnInfoPtr);
48static void MGAGSave(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
49static void MGAGRestore(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
50static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr);
51static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
52static Bool MGAG_i2cInit(ScrnInfoPtr pScrn);
53
54#define P_ARRAY_SIZE 9
55
56void
57MGAG200E4ComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
58{
59    unsigned int ulComputedFo;
60    unsigned int ulFDelta;
61    unsigned int ulFTmpDelta;
62    unsigned int ulVCOMax, ulVCOMin;
63    unsigned int ulTestP;
64    unsigned int ulTestM;
65    unsigned int ulTestN;
66    unsigned int ulFoInternal;
67    unsigned int ulPLLFreqRef;
68    unsigned int pulPValues[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
69    unsigned int i;
70    unsigned int ulVCO;
71    unsigned int ulFVV;
72
73    ulVCOMax        = 1600000;
74    ulVCOMin        = 800000;
75    ulPLLFreqRef    = 25000;
76
77    if(lFo < 25000)
78        lFo = 25000;
79
80    ulFoInternal = lFo * 2;
81
82    ulFDelta = 0xFFFFFFFF;
83
84    for (i = 0 ; i < P_ARRAY_SIZE ; i++)
85    {
86        ulTestP = pulPValues[i];
87
88        if ((ulFoInternal * ulTestP) > ulVCOMax) continue;
89        if ((ulFoInternal * ulTestP) < ulVCOMin) continue;
90
91        for (ulTestN = 50; ulTestN <= 256; ulTestN++) {
92            for (ulTestM = 1; ulTestM <= 32; ulTestM++) {
93                ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP);
94                if (ulComputedFo > ulFoInternal)
95                    ulFTmpDelta = ulComputedFo - ulFoInternal;
96                else
97                    ulFTmpDelta = ulFoInternal - ulComputedFo;
98
99                if (ulFTmpDelta < ulFDelta) {
100                    ulFDelta = ulFTmpDelta;
101                    *M = ulTestM - 1;
102                    *N = ulTestN - 1;
103                    *P = ulTestP - 1;
104                }
105            }
106        }
107    }
108
109    ulVCO = ulPLLFreqRef * ((*N)+1) / ((*M)+1);
110    ulFVV = (ulVCO - 800000) / 50000;
111
112    if (ulFVV > 15)
113        ulFVV = 15;
114
115    *P |= (ulFVV << 4);
116
117    *M |= 0x80;
118}
119
120static void
121MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
122{
123    unsigned int ulComputedFo;
124    unsigned int ulFDelta;
125    unsigned int ulFTmpDelta;
126    unsigned int ulVCOMax, ulVCOMin;
127    unsigned int ulTestP;
128    unsigned int ulTestM;
129    unsigned int ulTestN;
130    unsigned int ulPLLFreqRef;
131
132    ulVCOMax        = 320000;
133    ulVCOMin        = 160000;
134    ulPLLFreqRef    = 25000;
135
136    ulFDelta = 0xFFFFFFFF;
137
138    /* Then we need to minimize the M while staying within 0.5% */
139    for (ulTestP = 8; ulTestP > 0; ulTestP >>= 1) {
140        if ((lFo * ulTestP) > ulVCOMax) continue;
141        if ((lFo * ulTestP) < ulVCOMin) continue;
142
143        for (ulTestN = 17; ulTestN <= 256; ulTestN++) {
144            for (ulTestM = 1; ulTestM <= 32; ulTestM++) {
145                ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP);
146                if (ulComputedFo > lFo)
147                    ulFTmpDelta = ulComputedFo - lFo;
148                else
149                    ulFTmpDelta = lFo - ulComputedFo;
150
151                if (ulFTmpDelta < ulFDelta) {
152                    ulFDelta = ulFTmpDelta;
153                    *M = ulTestM - 1;
154                    *N = ulTestN - 1;
155                    *P = ulTestP - 1;
156                }
157            }
158        }
159    }
160}
161
162static void
163MGAG200EVComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
164{
165    unsigned int ulComputedFo;
166    unsigned int ulFDelta;
167    unsigned int ulFTmpDelta;
168    unsigned int ulTestP;
169    unsigned int ulTestM;
170    unsigned int ulTestN;
171    unsigned int ulVCOMax;
172    unsigned int ulVCOMin;
173    unsigned int ulPLLFreqRef;
174
175    ulVCOMax        = 550000;
176    ulVCOMin        = 150000;
177    ulPLLFreqRef    = 50000;
178
179    ulFDelta = 0xFFFFFFFF;
180
181    /* Then we need to minimize the M while staying within 0.5% */
182    for (ulTestP = 16; ulTestP > 0; ulTestP--) {
183	if ((lFo * ulTestP) > ulVCOMax) continue;
184	if ((lFo * ulTestP) < ulVCOMin) continue;
185
186	for (ulTestN = 1; ulTestN <= 256; ulTestN++) {
187	    for (ulTestM = 1; ulTestM <= 16; ulTestM++) {
188		ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP);
189		if (ulComputedFo > lFo)
190		    ulFTmpDelta = ulComputedFo - lFo;
191		else
192		    ulFTmpDelta = lFo - ulComputedFo;
193
194		if (ulFTmpDelta < ulFDelta) {
195			ulFDelta = ulFTmpDelta;
196			*M = (CARD8)(ulTestM - 1);
197			*N = (CARD8)(ulTestN - 1);
198			*P = (CARD8)(ulTestP - 1);
199		}
200	    }
201	}
202    }
203#if DEBUG
204	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
205		   "lFo=%ld n=0x%x m=0x%x p=0x%x \n",
206		   lFo, *N, *M, *P );
207#endif
208}
209
210static void
211MGAG200WBComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
212{
213    unsigned int ulComputedFo;
214    unsigned int ulFDelta;
215    unsigned int ulFTmpDelta;
216    unsigned int ulVCOMax, ulVCOMin;
217    unsigned int ulTestP;
218    unsigned int ulTestM;
219    unsigned int ulTestN;
220    unsigned int ulPLLFreqRef;
221    unsigned int ulTestPStart;
222    unsigned int ulTestNStart;
223    unsigned int ulTestNEnd;
224    unsigned int ulTestMStart;
225    unsigned int ulTestMEnd;
226
227    ulVCOMax        = 550000;
228    ulVCOMin        = 150000;
229    ulPLLFreqRef    = 48000;
230    ulTestPStart    = 1;
231    ulTestNStart    = 1;
232    ulTestNEnd      = 150;
233    ulTestMStart    = 1;
234    ulTestMEnd      = 16;
235
236    ulFDelta = 0xFFFFFFFF;
237
238    /* Then we need to minimize the M while staying within 0.5% */
239    for (ulTestP = ulTestPStart; ulTestP < 9; ulTestP++) {
240	if ((lFo * ulTestP) > ulVCOMax) continue;
241	if ((lFo * ulTestP) < ulVCOMin) continue;
242
243        for (ulTestM = ulTestMStart; ulTestM <= ulTestMEnd; ulTestM++) {
244	   for (ulTestN = ulTestNStart; ulTestN <= ulTestNEnd; ulTestN++) {
245		ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP);
246		if (ulComputedFo > lFo)
247			ulFTmpDelta = ulComputedFo - lFo;
248		else
249			ulFTmpDelta = lFo - ulComputedFo;
250
251		if (ulFTmpDelta < ulFDelta) {
252			ulFDelta = ulFTmpDelta;
253        		*M = (CARD8)(ulTestM - 1) | (CARD8)(((ulTestN -1) >> 1) & 0x80);
254			*N = (CARD8)(ulTestN - 1);
255			*P = (CARD8)(ulTestP - 1);
256		}
257	    }
258	}
259    }
260#if DEBUG
261	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
262		   "lFo=%ld n=0x%x m=0x%x p=0x%x \n",
263		   lFo, *N, *M, *P );
264#endif
265}
266
267void
268MGAG200EW3ComputePLLParam(ScrnInfoPtr pScrn ,long lFo, int *M, int *N, int *P)
269{
270    unsigned int ulComputedFo;
271    unsigned int ulFDelta;
272    unsigned int ulFTmpDelta;
273    unsigned int ulVCOMax, ulVCOMin;
274    unsigned int ulTestP1;
275    unsigned int ulTestP2;
276    unsigned int ulTestM;
277    unsigned int ulTestN;
278    unsigned int ulPLLFreqRef;
279    unsigned int ulTestP1Start;
280    unsigned int ulTestP1End;
281    unsigned int ulTestP2Start;
282    unsigned int ulTestP2End;
283    unsigned int ulTestMStart;
284    unsigned int ulTestMEnd;
285    unsigned int ulTestNStart;
286    unsigned int ulTestNEnd;
287
288    ulVCOMax        = 800000;
289    ulVCOMin        = 400000;
290    ulPLLFreqRef    = 25000;
291    ulTestP1Start   = 1;
292    ulTestP1End     = 8;
293    ulTestP2Start   = 1;
294    ulTestP2End     = 8;
295    ulTestMStart    = 1;
296    ulTestMEnd      = 26;
297    ulTestNStart    = 32;
298    ulTestNEnd      = 2048;
299
300    ulFDelta = 0xFFFFFFFF;
301
302    /* Then we need to minimize the M while staying within 0.5% */
303    for (ulTestP1 = ulTestP1Start; ulTestP1 < ulTestP1End; ulTestP1++) {
304        for (ulTestP2 = ulTestP2Start; ulTestP2 < ulTestP2End; ulTestP2++) {
305            if (ulTestP1 < ulTestP2) continue;
306            if ((lFo * ulTestP1 * ulTestP2) > ulVCOMax) continue;
307            if ((lFo * ulTestP1 * ulTestP2) < ulVCOMin) continue;
308
309            for (ulTestM = ulTestMStart; ulTestM < ulTestMEnd; ulTestM++) {
310                for (ulTestN = ulTestNStart; ulTestN < ulTestNEnd; ulTestN++) {
311                    ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP1 * ulTestP2);
312                    if (ulComputedFo > lFo)
313                        ulFTmpDelta = ulComputedFo - lFo;
314                    else
315                        ulFTmpDelta = lFo - ulComputedFo;
316
317                    if (ulFTmpDelta < ulFDelta) {
318                        ulFDelta = ulFTmpDelta;
319                        *M = (CARD8)((ulTestN & 0x100) >> 1) |
320                             (CARD8)(ulTestM);
321                        *N = (CARD8)(ulTestN & 0xFF);
322                        *P = (CARD8)((ulTestN & 0x600) >> 3) |
323                             (CARD8)(ulTestP2 << 3) |
324                             (CARD8)ulTestP1;
325                    }
326                }
327            }
328        }
329    }
330}
331
332static void
333MGAG200EHComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
334{
335    unsigned int ulComputedFo;
336    unsigned int ulFDelta;
337    unsigned int ulFTmpDelta;
338    unsigned int ulTestP;
339    unsigned int ulTestM;
340    unsigned int ulTestN;
341    unsigned int ulVCOMax;
342    unsigned int ulVCOMin;
343    unsigned int ulPLLFreqRef;
344
345    ulVCOMax        = 800000;
346    ulVCOMin        = 400000;
347    ulPLLFreqRef    = 33333;
348
349    ulFDelta = 0xFFFFFFFF;
350
351    /* Then we need to minimize the M while staying within 0.5% */
352    for (ulTestP = 16; ulTestP > 0; ulTestP>>= 1) {
353        if ((lFo * ulTestP) > ulVCOMax) continue;
354        if ((lFo * ulTestP) < ulVCOMin) continue;
355
356        for (ulTestM = 1; ulTestM <= 32; ulTestM++) {
357           for (ulTestN = 17; ulTestN <= 256; ulTestN++) {
358               ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP);
359               if (ulComputedFo > lFo)
360		           ulFTmpDelta = ulComputedFo - lFo;
361               else
362                   ulFTmpDelta = lFo - ulComputedFo;
363
364               if (ulFTmpDelta < ulFDelta) {
365                   ulFDelta = ulFTmpDelta;
366                   *M = (CARD8)(ulTestM - 1);
367                   *N = (CARD8)(ulTestN - 1);
368                   *P = (CARD8)(ulTestP - 1);
369               }
370
371               if ((lFo * ulTestP) >= 600000)
372                   *P |= 0x80;
373           }
374        }
375    }
376}
377
378void
379MGAG200EH3ComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
380{
381    unsigned int ulComputedFo;
382    unsigned int ulFDelta;
383    unsigned int ulFTmpDelta;
384    unsigned int ulTestP;
385    unsigned int ulTestM;
386    unsigned int ulTestN;
387    unsigned int ulVCOMax;
388    unsigned int ulVCOMin;
389    unsigned int ulPLLFreqRef;
390
391    ulVCOMax        = 3000000;
392    ulVCOMin        = 1500000;
393    ulPLLFreqRef    = 25000;
394
395    ulTestP         = 0;
396
397    ulFDelta = 0xFFFFFFFF;
398
399    /* Then we need to minimize the M while staying within 0.5% */
400    for (ulTestM = 150; ulTestM >= 6; ulTestM--) {
401        if ((lFo * ulTestM) > ulVCOMax) continue;
402        if ((lFo * ulTestM) < ulVCOMin) continue;
403
404        for (ulTestN = 120; ulTestN >= 60; ulTestN--) {
405            ulComputedFo = (ulPLLFreqRef * ulTestN) / ulTestM;
406            if (ulComputedFo > lFo)
407	        ulFTmpDelta = ulComputedFo - lFo;
408            else
409                ulFTmpDelta = lFo - ulComputedFo;
410
411            if (ulFTmpDelta < ulFDelta) {
412                ulFDelta = ulFTmpDelta;
413                *M = (CARD8)(ulTestM);
414                *N = (CARD8)(ulTestN);
415                *P = (CARD8)(ulTestP);
416            }
417        }
418    }
419}
420
421static void
422MGAG200EVPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
423{
424    MGAPtr pMga = MGAPTR(pScrn);
425
426    unsigned char ucTempByte, ucPixCtrl;
427
428    // Set pixclkdis to 1
429    ucPixCtrl = inMGAdac(MGA1064_PIX_CLK_CTL);
430    ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_DIS;
431    outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
432
433    // Select PLL Set C
434    ucTempByte = INREG8(MGAREG_MEM_MISC_READ);
435    ucTempByte |= 0x3<<2; //select MGA pixel clock
436    OUTREG8(MGAREG_MEM_MISC_WRITE, ucTempByte);
437
438    // Set pixlock to 0
439    ucTempByte = inMGAdac(MGA1064_PIX_PLL_STAT);
440    outMGAdac(MGA1064_PIX_PLL_STAT, ucTempByte & ~0x40);
441
442    //    Set pix_stby to 1
443    ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
444    outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
445
446    // Program the Pixel PLL Register
447    outMGAdac(MGA1064_EV_PIX_PLLC_M, mgaReg->PllM);
448    outMGAdac(MGA1064_EV_PIX_PLLC_N, mgaReg->PllN);
449    outMGAdac(MGA1064_EV_PIX_PLLC_P, mgaReg->PllP);
450
451    // Wait 50 us
452    usleep(50);
453
454    // Set pix_stby to 0
455    ucPixCtrl &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
456    outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
457
458    // Wait 500 us
459    usleep(500);
460
461    // Select the pixel PLL by setting pixclksel to 1
462    ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
463    ucTempByte &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
464    ucTempByte |= MGA1064_PIX_CLK_CTL_SEL_PLL;
465    outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
466
467    // Set pixlock to 1
468    ucTempByte = inMGAdac(MGA1064_PIX_PLL_STAT);
469    outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte | 0x40);
470
471    // Reset dotclock rate bit.
472    ucTempByte = INREG8(MGAREG_MEM_MISC_READ);
473    ucTempByte |= 0x3<<2; //select MGA pixel clock
474    OUTREG8(MGAREG_MEM_MISC_WRITE, ucTempByte);
475
476    OUTREG8(MGAREG_SEQ_INDEX, 1);
477    ucTempByte = INREG8(MGAREG_SEQ_DATA);
478    OUTREG8(MGAREG_SEQ_DATA, ucTempByte & ~0x8);
479
480    // Set pixclkdis to 0
481    ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
482    ucTempByte &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
483    outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
484}
485
486static void
487MGAG200WBPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
488{
489    MGAPtr pMga = MGAPTR(pScrn);
490
491    unsigned long ulLoopCount, ulLockCheckIterations = 0, ulTempCount, ulVCount;
492    unsigned char ucTempByte, ucPixCtrl, ucPLLLocked = FALSE;
493
494    while(ulLockCheckIterations <= 32 && ucPLLLocked == FALSE)
495    {
496        if(ulLockCheckIterations > 0)
497        {
498            OUTREG8(MGAREG_CRTCEXT_INDEX, 0x1E);
499            ucTempByte = INREG8(MGAREG_CRTCEXT_DATA);
500            if(ucTempByte < 0xFF)
501            {
502                OUTREG8(MGAREG_CRTCEXT_DATA, ucTempByte+1);
503            }
504        }
505
506        // Set pixclkdis to 1
507        ucPixCtrl = inMGAdac(MGA1064_PIX_CLK_CTL);
508        ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_DIS;
509        outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
510
511        ucTempByte = inMGAdac(MGA1064_REMHEADCTL);
512        ucTempByte |= MGA1064_REMHEADCTL_CLKDIS;
513        outMGAdac(MGA1064_REMHEADCTL, ucTempByte);
514
515        // Select PLL Set C
516        ucTempByte = INREG8(MGAREG_MEM_MISC_READ);
517        ucTempByte |= 0x3<<2; //select MGA pixel clock
518        OUTREG8(MGAREG_MEM_MISC_WRITE, ucTempByte);
519
520        ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
521        outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
522
523        // Wait 500 us
524        usleep(500);
525
526        // Reset the PLL
527        //   When we are varying the output frequency by more than
528        //   10%, we must reset the PLL. However to be prudent, we
529        //   will reset it each time that we are changing it.
530        ucTempByte = inMGAdac(MGA1064_VREF_CTL);
531        ucTempByte &= ~0x04;
532        outMGAdac(MGA1064_VREF_CTL, ucTempByte );
533
534        // Wait 50 us
535        usleep(50);
536
537        // Program the Pixel PLL Register
538        outMGAdac(MGA1064_WB_PIX_PLLC_N, mgaReg->PllN);
539        outMGAdac(MGA1064_WB_PIX_PLLC_M, mgaReg->PllM);
540        outMGAdac(MGA1064_WB_PIX_PLLC_P, mgaReg->PllP);
541
542        // Wait 50 us
543        usleep(50);
544
545        // Turning the PLL on
546        ucTempByte = inMGAdac(MGA1064_VREF_CTL);
547        ucTempByte |= 0x04;
548        outMGAdac(MGA1064_VREF_CTL, ucTempByte );
549
550        // Wait 500 us
551        usleep(500);
552
553        // Select the pixel PLL by setting pixclksel to 1
554        ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
555        ucTempByte &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
556        ucTempByte |= MGA1064_PIX_CLK_CTL_SEL_PLL;
557        outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
558
559        ucTempByte = inMGAdac(MGA1064_REMHEADCTL);
560        ucTempByte &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
561        ucTempByte |= MGA1064_REMHEADCTL_CLKSL_PLL;
562        outMGAdac(MGA1064_REMHEADCTL, ucTempByte);
563
564        // Reset dotclock rate bit.
565        OUTREG8(MGAREG_SEQ_INDEX, 1);
566        ucTempByte = INREG8(MGAREG_SEQ_DATA);
567        OUTREG8(MGAREG_SEQ_DATA, ucTempByte & ~0x8);
568
569        // Set pixclkdis to 0
570        ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
571        ucTempByte &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
572        outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
573
574        // Poll VCount. If it increments twice inside 150us,
575        // we assume that the PLL has locked.
576        ulLoopCount = 0;
577        ulVCount = INREG(MGAREG_VCOUNT);
578
579        while(ulLoopCount < 30 && ucPLLLocked == FALSE)
580        {
581            ulTempCount = INREG(MGAREG_VCOUNT);
582
583            if(ulTempCount < ulVCount)
584            {
585                ulVCount = 0;
586            }
587            if ((ucTempByte - ulVCount) > 2)
588            {
589                ucPLLLocked = TRUE;
590            }
591            else
592            {
593                usleep(5);
594            }
595            ulLoopCount++;
596        }
597        ulLockCheckIterations++;
598    }
599
600    // Set remclkdis to 0
601    ucTempByte = inMGAdac(MGA1064_REMHEADCTL);
602    ucTempByte &= ~MGA1064_REMHEADCTL_CLKDIS;
603    outMGAdac(MGA1064_REMHEADCTL, ucTempByte);
604}
605
606#define G200ER_PLLREF 48000
607#define G200ER_VCOMIN 1056000
608#define G200ER_VCOMAX 1488000
609
610static void MGAG200ERComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *piM, int *piN, int *piP)
611{
612
613    int  ulM;
614    int  ulN;
615    int  ulO;
616    int  ulR;
617
618    CARD32 ulComputedFo;
619    CARD32 ulVco;
620    CARD32 ulFDelta;
621    CARD32 ulFTmpDelta;
622
623    CARD32 aulMDivValue[] = {1, 2, 4, 8};
624
625    CARD32 ulFo   = lFo;
626
627    ulFDelta = 0xFFFFFFFF;
628
629    for (ulR = 0; ulR < 4;  ulR++)
630    {
631    	if(ulFDelta==0) break;
632        for (ulN = 5; (ulN <= 128) ; ulN++)
633        {
634            if(ulFDelta==0) break;
635            for (ulM = 3; ulM >= 0; ulM--)
636            {
637            	if(ulFDelta==0) break;
638                for (ulO = 5; ulO <= 32; ulO++)
639                {
640                	ulVco = (G200ER_PLLREF * (ulN+1)) / (ulR+1);
641                	// Validate vco
642                    if (ulVco < G200ER_VCOMIN) continue;
643					if (ulVco > G200ER_VCOMAX) continue;
644                	ulComputedFo = ulVco / (aulMDivValue[ulM] * (ulO+1));
645
646                    if (ulComputedFo > ulFo)
647                    {
648                        ulFTmpDelta = ulComputedFo - ulFo;
649                    }
650                    else
651                    {
652                        ulFTmpDelta = ulFo - ulComputedFo;
653                    }
654
655                    if (ulFTmpDelta < ulFDelta)
656                    {
657                        ulFDelta = ulFTmpDelta;
658                        // XG200ERPIXPLLCM M<1:0> O<7:3>
659                        *piM = (CARD8)ulM | (CARD8)(ulO<<3);
660                        //
661                        // XG200ERPIXPLLCN N<6:0>
662                        *piN = (CARD8)ulN;
663                        //
664                        // XG200ERPIXPLLCP R<1:0> cg<7:4> (Use R value)
665                        *piP = (CARD8)ulR | (CARD8)(ulR<<3);
666
667                        // Test
668                        int ftest = (G200ER_PLLREF * (ulN+1)) / ((ulR+1) * aulMDivValue[ulM] * (ulO+1));
669                        ftest=ftest;
670                    }
671                } // End O Loop
672            } // End M Loop
673        } // End N Loop
674    } // End R Loop
675}
676
677static void
678MGAG200ERPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
679{
680    //TODO  G200ER Validate sequence
681    CARD8 ucPixCtrl, ucTempByte;
682    MGAPtr pMga = MGAPTR(pScrn);
683
684
685    // Set pixclkdis to 1
686    ucPixCtrl = inMGAdac(MGA1064_PIX_CLK_CTL);
687    ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_DIS;
688    outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
689
690    ucTempByte = inMGAdac(MGA1064_REMHEADCTL);
691    ucTempByte |= MGA1064_REMHEADCTL_CLKDIS;
692    outMGAdac(MGA1064_REMHEADCTL, ucTempByte);
693
694    // Select PLL Set C
695    ucTempByte = INREG8(MGAREG_MEM_MISC_READ);
696    ucTempByte |= (0x3<<2) | 0xc0; //select MGA pixel clock
697    OUTREG8(MGAREG_MEM_MISC_WRITE, ucTempByte);
698
699    ucPixCtrl &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
700    ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
701    outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
702
703    // Wait 500 us
704    usleep(500);
705
706    // Program the Pixel PLL Register
707    outMGAdac(MGA1064_ER_PIX_PLLC_N, mgaReg->PllN);
708    outMGAdac(MGA1064_ER_PIX_PLLC_M, mgaReg->PllM);
709    outMGAdac(MGA1064_ER_PIX_PLLC_P, mgaReg->PllP);
710
711        // Wait 50 us
712    usleep(50);
713
714}
715
716static void
717MGAG200WBPrepareForModeSwitch(ScrnInfoPtr pScrn)
718{
719    MGAPtr pMga = MGAPTR(pScrn);
720
721    unsigned char ucTmpData = 0;
722    int ulIterationMax = 0;
723    // 1- The first step is to warn the BMC of an upcoming mode change.
724    // We are putting the misc<0> to output.
725    ucTmpData = inMGAdac(MGA1064_GEN_IO_CTL);
726    ucTmpData |= 0x10;
727    outMGAdac(MGA1064_GEN_IO_CTL, ucTmpData);
728
729    // We are putting a 1 on the misc<0> line.
730    ucTmpData = inMGAdac(MGA1064_GEN_IO_DATA);
731    ucTmpData |= 0x10;
732    outMGAdac(MGA1064_GEN_IO_DATA, ucTmpData);
733
734    // 2- The second step is to mask any further scan request
735    // This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
736    ucTmpData = inMGAdac(MGA1064_SPAREREG);
737    ucTmpData |= 0x80;
738    outMGAdac(MGA1064_SPAREREG, ucTmpData);
739
740    // 3a- The third step is to verify if there is an active scan
741    // We are searching for a 0 on remhsyncsts (XSPAREREG<0>)
742    ulIterationMax = 300;
743    while (!(ucTmpData & 0x01) && ulIterationMax)
744    {
745        ucTmpData = inMGAdac(MGA1064_SPAREREG);
746        usleep(1000);
747        ulIterationMax--;
748    }
749
750    // 3b- This step occurs only if the remote is actually scanning
751    // We are waiting for the end of the frame which is a 1 on
752    // remvsyncsts (XSPAREREG<1>)
753    if (ulIterationMax)
754    {
755        ulIterationMax = 300;
756        while ((ucTmpData & 0x02) && ulIterationMax)
757        {
758            ucTmpData = inMGAdac(MGA1064_SPAREREG);
759            usleep(1000);
760            ulIterationMax--;
761        }
762    }
763}
764
765static void
766MGAG200WBRestoreFromModeSwitch(ScrnInfoPtr pScrn)
767{
768    MGAPtr pMga = MGAPTR(pScrn);
769
770    unsigned char ucTmpData = 0;
771
772    // 1- The first step is to ensure that the vrsten and hrsten are set
773    OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01);
774    ucTmpData = INREG8(MGAREG_CRTCEXT_DATA);
775    OUTREG8(MGAREG_CRTCEXT_DATA, ucTmpData | 0x88);
776
777    // 2- The second step is is to assert the rstlvl2
778    ucTmpData = inMGAdac(MGA1064_REMHEADCTL2);
779    ucTmpData |= 0x08;
780    outMGAdac(MGA1064_REMHEADCTL2, ucTmpData);
781
782    // - Wait for 10 us
783    usleep(10);
784
785    // 3- The next step is is to deassert the rstlvl2
786    ucTmpData &= ~0x08;
787    outMGAdac(MGA1064_REMHEADCTL2, ucTmpData);
788
789    // - Wait for 10 us
790    usleep(10);
791
792    // 4- The fourth step is to remove the mask of scan request
793    // This will be done by deasserting the remfreqmsk bit (XSPAREREG<7>)
794    ucTmpData = inMGAdac(MGA1064_SPAREREG);
795    ucTmpData &= ~0x80;
796    outMGAdac(MGA1064_SPAREREG, ucTmpData);
797
798    // 5- Finally, we are putting back a 0 on the misc<0> line.
799    ucTmpData = inMGAdac(MGA1064_GEN_IO_DATA);
800    ucTmpData &= ~0x10;
801    outMGAdac(MGA1064_GEN_IO_DATA, ucTmpData);
802}
803
804static void
805MGAG200EHPIXPLLSET(ScrnInfoPtr pScrn, MGARegPtr mgaReg)
806{
807    MGAPtr pMga = MGAPTR(pScrn);
808
809    unsigned long ulLoopCount, ulLockCheckIterations = 0, ulTempCount, ulVCount;
810    unsigned char ucTempByte, ucPixCtrl, ucPLLLocked = FALSE;
811
812    while(ulLockCheckIterations <= 32 && ucPLLLocked == FALSE)
813    {
814        // Set pixclkdis to 1
815        ucPixCtrl = inMGAdac(MGA1064_PIX_CLK_CTL);
816        ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_DIS;
817        outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
818
819        // Select PLL Set C
820        ucTempByte = INREG8(MGAREG_MEM_MISC_READ);
821        ucTempByte |= 0x3<<2; //select MGA pixel clock
822        OUTREG8(MGAREG_MEM_MISC_WRITE, ucTempByte);
823
824        ucPixCtrl |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
825        ucPixCtrl &= ~0x80;
826        outMGAdac(MGA1064_PIX_CLK_CTL, ucPixCtrl);
827
828        // Wait 500 us
829        usleep(500);
830
831        // Program the Pixel PLL Register
832        outMGAdac(MGA1064_EH_PIX_PLLC_N, mgaReg->PllN);
833        outMGAdac(MGA1064_EH_PIX_PLLC_M, mgaReg->PllM);
834        outMGAdac(MGA1064_EH_PIX_PLLC_P, mgaReg->PllP);
835
836        // Wait 500 us
837        usleep(500);
838
839        // Select the pixel PLL by setting pixclksel to 1
840        ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
841        ucTempByte &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
842        ucTempByte |= MGA1064_PIX_CLK_CTL_SEL_PLL;
843        outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
844
845        // Reset dotclock rate bit.
846        OUTREG8(MGAREG_SEQ_INDEX, 1);
847        ucTempByte = INREG8(MGAREG_SEQ_DATA);
848        OUTREG8(MGAREG_SEQ_DATA, ucTempByte & ~0x8);
849
850        // Set pixclkdis to 0 and pixplldn to 0
851        ucTempByte = inMGAdac(MGA1064_PIX_CLK_CTL);
852        ucTempByte &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
853        ucTempByte &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
854        outMGAdac(MGA1064_PIX_CLK_CTL, ucTempByte);
855
856        // Poll VCount. If it increments twice inside 150us,
857        // we assume that the PLL has locked.
858        ulLoopCount = 0;
859        ulVCount = INREG(MGAREG_VCOUNT);
860
861        while(ulLoopCount < 30 && ucPLLLocked == FALSE)
862        {
863            ulTempCount = INREG(MGAREG_VCOUNT);
864
865            if(ulTempCount < ulVCount)
866            {
867                ulVCount = 0;
868            }
869            if ((ucTempByte - ulVCount) > 2)
870            {
871                ucPLLLocked = TRUE;
872            }
873            else
874            {
875                usleep(5);
876            }
877            ulLoopCount++;
878        }
879        ulLockCheckIterations++;
880    }
881}
882
883/**
884 * Calculate the PLL settings (m, n, p, s).
885 *
886 * For more information, refer to the Matrox "MGA1064SG Developer
887 * Specification" (document 10524-MS-0100).  chapter 5.7.8. "PLLs Clocks
888 * Generators"
889 *
890 * \param f_out   Desired clock frequency, measured in kHz.
891 * \param best_m  Value of PLL 'm' register.
892 * \param best_n  Value of PLL 'n' register.
893 * \param p       Value of PLL 'p' register.
894 * \param s       Value of PLL 's' filter register (pix pll clock only).
895 */
896
897static void
898MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out,
899		int *best_m, int *best_n, int *p, int *s )
900{
901	MGAPtr pMga = MGAPTR(pScrn);
902	int m, n;
903	double f_vco;
904	double m_err, calc_f;
905	const double ref_freq = (double) pMga->bios.pll_ref_freq;
906	const int feed_div_max = 127;
907	const int in_div_min = 1;
908	const int post_div_max = 7;
909	int feed_div_min;
910	int in_div_max;
911
912
913	switch( pMga->Chipset )
914	{
915	case PCI_CHIP_MGA1064:
916		feed_div_min = 100;
917		in_div_max   = 31;
918		break;
919	case PCI_CHIP_MGAG400:
920	case PCI_CHIP_MGAG550:
921		feed_div_min = 7;
922		in_div_max   = 31;
923		break;
924	case PCI_CHIP_MGAG200_SE_A_PCI:
925	case PCI_CHIP_MGAG200_SE_B_PCI:
926	case PCI_CHIP_MGAG100:
927	case PCI_CHIP_MGAG100_PCI:
928	case PCI_CHIP_MGAG200:
929	case PCI_CHIP_MGAG200_PCI:
930	default:
931		feed_div_min = 7;
932		in_div_max   = 6;
933		break;
934	}
935
936	/* Make sure that f_min <= f_out */
937	if ( f_out < ( pMga->bios.pixel.min_freq / 8))
938		f_out = pMga->bios.pixel.min_freq / 8;
939
940	/*
941	 * f_pll = f_vco / (p+1)
942	 * Choose p so that
943	 * pMga->bios.pixel.min_freq <= f_vco <= pMga->bios.pixel.max_freq
944	 * we don't have to bother checking for this maximum limit.
945	 */
946	f_vco = ( double ) f_out;
947	for ( *p = 0; *p <= post_div_max && f_vco < pMga->bios.pixel.min_freq;
948		*p = *p * 2 + 1, f_vco *= 2.0);
949
950	/* Initial amount of error for frequency maximum */
951	m_err = f_out;
952
953	/* Search for the different values of ( m ) */
954	for ( m = in_div_min ; m <= in_div_max ; m++ )
955	{
956		/* see values of ( n ) which we can't use */
957		for ( n = feed_div_min; n <= feed_div_max; n++ )
958		{
959			double av;
960			calc_f = ref_freq * (n + 1) / (m + 1) ;
961
962			/*
963			 * Pick the closest frequency.
964			 */
965			if ( fabs(calc_f - f_vco) < m_err ) {
966				m_err = fabs(calc_f - f_vco);
967				*best_m = m;
968				*best_n = n;
969			}
970		}
971	}
972
973	/* Now all the calculations can be completed */
974	f_vco = ref_freq * (*best_n + 1) / (*best_m + 1);
975
976	/* Adjustments for filtering pll feed back */
977	if ( (50000.0 <= f_vco)
978	&& (f_vco < 100000.0) )
979		*s = 0;
980	if ( (100000.0 <= f_vco)
981	&& (f_vco < 140000.0) )
982		*s = 1;
983	if ( (140000.0 <= f_vco)
984	&& (f_vco < 180000.0) )
985		*s = 2;
986	if ( (180000.0 <= f_vco) )
987		*s = 3;
988
989#ifdef DEBUG
990	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
991		   "f_out_requ =%ld f_pll_real=%.1f f_vco=%.1f n=0x%x m=0x%x p=0x%x s=0x%x\n",
992		   f_out, (f_vco / (*p + 1)), f_vco, *best_n, *best_m, *p, *s );
993#endif
994}
995
996/*
997 * MGAGSetPCLK - Set the pixel (PCLK) clock.
998 */
999static void
1000MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out )
1001{
1002	MGAPtr pMga = MGAPTR(pScrn);
1003	MGARegPtr pReg = &pMga->ModeReg;
1004
1005	/* Pixel clock values */
1006	int m, n, p, s;
1007        m = n = p = s = 0;
1008
1009	if(MGAISGx50(pMga)) {
1010	    pReg->Clock = f_out;
1011	    if (pMga->Chipset == PCI_CHIP_MGAG550) {
1012		if (f_out < 45000) {
1013		    pReg->Pan_Ctl = 0x00;
1014		} else if (f_out < 55000) {
1015		    pReg->Pan_Ctl = 0x08;
1016		} else if (f_out < 70000) {
1017		    pReg->Pan_Ctl = 0x10;
1018		} else if (f_out < 85000) {
1019		    pReg->Pan_Ctl = 0x18;
1020		} else if (f_out < 100000) {
1021		    pReg->Pan_Ctl = 0x20;
1022		} else if (f_out < 115000) {
1023		    pReg->Pan_Ctl = 0x28;
1024		} else if (f_out < 125000) {
1025		    pReg->Pan_Ctl = 0x30;
1026		} else {
1027		    pReg->Pan_Ctl = 0x38;
1028		}
1029	    } else {
1030		if (f_out < 45000) {
1031		    pReg->Pan_Ctl = 0x00;
1032		} else if (f_out < 65000) {
1033		    pReg->Pan_Ctl = 0x08;
1034		} else if (f_out < 85000) {
1035		    pReg->Pan_Ctl = 0x10;
1036		} else if (f_out < 105000) {
1037		    pReg->Pan_Ctl = 0x18;
1038		} else if (f_out < 135000) {
1039		    pReg->Pan_Ctl = 0x20;
1040		} else if (f_out < 160000) {
1041		    pReg->Pan_Ctl = 0x28;
1042		} else if (f_out < 175000) {
1043		    pReg->Pan_Ctl = 0x30;
1044		} else {
1045		    pReg->Pan_Ctl = 0x38;
1046		}
1047	    }
1048	    return;
1049	}
1050
1051	if (pMga->is_G200SE) {
1052            if (pMga->reg_1e24 >= 0x04) {
1053                MGAG200E4ComputePLLParam(pScrn, f_out, &m, &n, &p);
1054            } else {
1055                MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p);
1056            }
1057
1058	    pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m;
1059	    pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n;
1060	    pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = p;
1061	} else if (pMga->is_G200EV) {
1062	    MGAG200EVComputePLLParam(pScrn, f_out, &m, &n, &p);
1063
1064	    pReg->PllM = m;
1065	    pReg->PllN = n;
1066	    pReg->PllP = p;
1067	} else if (pMga->is_G200WB) {
1068            if (pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI)
1069            {
1070                 MGAG200EW3ComputePLLParam(pScrn, f_out, &m, &n, &p);
1071            }
1072            else
1073            {
1074	         MGAG200WBComputePLLParam(pScrn, f_out, &m, &n, &p);
1075            }
1076
1077	    pReg->PllM = m;
1078	    pReg->PllN = n;
1079	    pReg->PllP = p;
1080    } else if (pMga->is_G200EH) {
1081            if (pMga->Chipset == PCI_CHIP_MGAG200_EH3_PCI)
1082            {
1083                 MGAG200EH3ComputePLLParam(pScrn, f_out, &m, &n, &p);
1084            }
1085            else
1086            {
1087                 MGAG200EHComputePLLParam(pScrn, f_out, &m, &n, &p);
1088            }
1089
1090	    pReg->PllM = m;
1091	    pReg->PllN = n;
1092	    pReg->PllP = p;
1093	} else if (pMga->is_G200ER) {
1094	    MGAG200ERComputePLLParam(pScrn, f_out, &m, &n, &p);
1095	    pReg->PllM = m;
1096	    pReg->PllN = n;
1097	    pReg->PllP = p;
1098    } else {
1099	    /* Do the calculations for m, n, p and s */
1100	    MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s );
1101
1102	    /* Values for the pixel clock PLL registers */
1103	    pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F;
1104	    pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F;
1105	    pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) |
1106						  ((s & 0x03) << 3);
1107	}
1108}
1109
1110/*
1111 * MGAGInit
1112 */
1113static Bool
1114MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
1115{
1116	/*
1117	 * initial values of the DAC registers
1118	 */
1119	const static unsigned char initDAC[] = {
1120	/* 0x00: */	   0,    0,    0,    0,    0,    0, 0x00,    0,
1121	/* 0x08: */	   0,    0,    0,    0,    0,    0,    0,    0,
1122	/* 0x10: */	   0,    0,    0,    0,    0,    0,    0,    0,
1123	/* 0x18: */	0x00,    0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
1124	/* 0x20: */	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1125	/* 0x28: */	0x00, 0x00, 0x00, 0x00,    0,    0,    0, 0x40,
1126	/* 0x30: */	0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
1127	/* 0x38: */	0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
1128	/* 0x40: */	   0,    0,    0,    0,    0,    0,    0,    0,
1129	/* 0x48: */	   0,    0,    0,    0,    0,    0,    0,    0
1130	};
1131
1132	int i;
1133	int hd, hs, he, ht, vd, vs, ve, vt, wd;
1134	int BppShift;
1135	MGAPtr pMga;
1136	MGARegPtr pReg;
1137	vgaRegPtr pVga;
1138	MGAFBLayout *pLayout;
1139	xMODEINFO ModeInfo;
1140
1141	ModeInfo.ulDispWidth = mode->HDisplay;
1142        ModeInfo.ulDispHeight = mode->VDisplay;
1143        ModeInfo.ulFBPitch = mode->HDisplay;
1144        ModeInfo.ulBpp = pScrn->bitsPerPixel;
1145        ModeInfo.flSignalMode = 0;
1146        ModeInfo.ulPixClock = mode->Clock;
1147        ModeInfo.ulHFPorch = mode->HSyncStart - mode->HDisplay;
1148        ModeInfo.ulHSync = mode->HSyncEnd - mode->HSyncStart;
1149        ModeInfo.ulHBPorch = mode->HTotal - mode->HSyncEnd;
1150        ModeInfo.ulVFPorch = mode->VSyncStart - mode->VDisplay;
1151        ModeInfo.ulVSync = mode->VSyncEnd - mode->VSyncStart;
1152        ModeInfo.ulVBPorch = mode->VTotal - mode->VSyncEnd;
1153
1154	pMga = MGAPTR(pScrn);
1155	pReg = &pMga->ModeReg;
1156	pVga = &VGAHWPTR(pScrn)->ModeReg;
1157	pLayout = &pMga->CurrentLayout;
1158
1159	BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1];
1160
1161	MGA_NOT_HAL(
1162	/* Allocate the DacRegs space if not done already */
1163	if (pReg->DacRegs == NULL) {
1164		pReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
1165	}
1166	for (i = 0; i < DACREGSIZE; i++) {
1167	    pReg->DacRegs[i] = initDAC[i];
1168	}
1169	);	/* MGA_NOT_HAL */
1170
1171	switch(pMga->Chipset)
1172	{
1173	case PCI_CHIP_MGA1064:
1174		pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04;
1175		pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x44;
1176		pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
1177		pReg->Option  = 0x5F094F21;
1178		pReg->Option2 = 0x00000000;
1179		break;
1180	case PCI_CHIP_MGAG100:
1181	case PCI_CHIP_MGAG100_PCI:
1182                pReg->DacRegs[MGA1064_VREF_CTL] = 0x03;
1183
1184		if(pMga->HasSDRAM) {
1185		    if(pMga->OverclockMem) {
1186                        /* 220 Mhz */
1187			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06;
1188			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x38;
1189			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
1190		    } else {
1191                        /* 203 Mhz */
1192			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x01;
1193			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x0E;
1194			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
1195		    }
1196		    pReg->Option = 0x404991a9;
1197		} else {
1198		    if(pMga->OverclockMem) {
1199                        /* 143 Mhz */
1200			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06;
1201			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24;
1202			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10;
1203		    } else {
1204		        /* 124 Mhz */
1205			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04;
1206			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x16;
1207			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08;
1208		    }
1209		    pReg->Option = 0x4049d121;
1210		}
1211		pReg->Option2 = 0x0000007;
1212		break;
1213	case PCI_CHIP_MGAG400:
1214	case PCI_CHIP_MGAG550:
1215	       if (MGAISGx50(pMga))
1216		       break;
1217
1218	       if(pMga->Dac.maxPixelClock == 360000) {  /* G400 MAX */
1219	           if(pMga->OverclockMem) {
1220			/* 150/200  */
1221			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x05;
1222			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x42;
1223			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
1224			pReg->Option3 = 0x019B8419;
1225			pReg->Option = 0x50574120;
1226		   } else {
1227			/* 125/166  */
1228			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02;
1229			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B;
1230			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
1231			pReg->Option3 = 0x019B8419;
1232			pReg->Option = 0x5053C120;
1233		   }
1234		} else {
1235	           if(pMga->OverclockMem) {
1236			/* 125/166  */
1237			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02;
1238			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B;
1239			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
1240			pReg->Option3 = 0x019B8419;
1241			pReg->Option = 0x5053C120;
1242		   } else {
1243			/* 110/166  */
1244			pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13;
1245			pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A;
1246			pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08;
1247			pReg->Option3 = 0x0190a421;
1248			pReg->Option = 0x50044120;
1249		   }
1250		}
1251		if(pMga->HasSDRAM)
1252		   pReg->Option &= ~(1 << 14);
1253		pReg->Option2 = 0x01003000;
1254		break;
1255	case PCI_CHIP_MGAG200_SE_A_PCI:
1256	case PCI_CHIP_MGAG200_SE_B_PCI:
1257        pReg->DacRegs[ MGA1064_VREF_CTL ] = 0x03;
1258                pReg->DacRegs[MGA1064_PIX_CLK_CTL] =
1259                    MGA1064_PIX_CLK_CTL_SEL_PLL;
1260
1261                pReg->DacRegs[MGA1064_MISC_CTL] =
1262                    MGA1064_MISC_CTL_DAC_EN |
1263                    MGA1064_MISC_CTL_VGA8 |
1264                    MGA1064_MISC_CTL_DAC_RAM_CS;
1265
1266		if (pMga->HasSDRAM)
1267		    pReg->Option = 0x40049120;
1268	        pReg->Option2 = 0x00008000;
1269		break;
1270
1271        case PCI_CHIP_MGAG200_WINBOND_PCI:
1272        case PCI_CHIP_MGAG200_EW3_PCI:
1273                pReg->DacRegs[MGA1064_VREF_CTL] = 0x07;
1274                pReg->Option = 0x41049120;
1275                pReg->Option2 = 0x0000b000;
1276                break;
1277
1278        case PCI_CHIP_MGAG200_EV_PCI:
1279                pReg->DacRegs[MGA1064_PIX_CLK_CTL] =
1280                    MGA1064_PIX_CLK_CTL_SEL_PLL;
1281
1282                pReg->DacRegs[MGA1064_MISC_CTL] =
1283                    MGA1064_MISC_CTL_VGA8 |
1284                    MGA1064_MISC_CTL_DAC_RAM_CS;
1285
1286                pReg->Option = 0x00000120;
1287                pReg->Option2 = 0x0000b000;
1288                break;
1289
1290		case PCI_CHIP_MGAG200_ER_PCI:
1291			pReg->Dac_Index90 = 0;
1292			break;
1293
1294        case PCI_CHIP_MGAG200_EH_PCI:
1295        case PCI_CHIP_MGAG200_EH3_PCI:
1296                pReg->DacRegs[MGA1064_MISC_CTL] =
1297                    MGA1064_MISC_CTL_VGA8 |
1298                    MGA1064_MISC_CTL_DAC_RAM_CS;
1299
1300                pReg->Option = 0x00000120;
1301                pReg->Option2 = 0x0000b000;
1302                break;
1303
1304	case PCI_CHIP_MGAG200:
1305	case PCI_CHIP_MGAG200_PCI:
1306	default:
1307		if(pMga->OverclockMem) {
1308                     /* 143 Mhz */
1309		    pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06;
1310		    pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24;
1311		    pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10;
1312		} else {
1313		    /* 124 Mhz */
1314		    pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04;
1315		    pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x2D;
1316		    pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x19;
1317		}
1318	        pReg->Option2 = 0x00008000;
1319		if(pMga->HasSDRAM)
1320		    pReg->Option = 0x40499121;
1321		else
1322		    pReg->Option = 0x4049cd21;
1323		break;
1324	}
1325
1326	MGA_NOT_HAL(
1327	/* must always have the pci retries on but rely on
1328	   polling to keep them from occurring */
1329	pReg->Option &= ~0x20000000;
1330
1331	switch(pLayout->bitsPerPixel)
1332	{
1333	case 8:
1334		pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_8bits;
1335		break;
1336	case 16:
1337		pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_16bits;
1338		if ( (pLayout->weight.red == 5) && (pLayout->weight.green == 5)
1339					&& (pLayout->weight.blue == 5) ) {
1340		    pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_15bits;
1341		}
1342		break;
1343	case 24:
1344		pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_24bits;
1345		break;
1346	case 32:
1347	    pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32_24bits;
1348	    break;
1349	default:
1350		FatalError("MGA: unsupported depth\n");
1351	}
1352	);	/* MGA_NOT_HAL */
1353
1354	/*
1355	 * This will initialize all of the generic VGA registers.
1356	 */
1357	if (!vgaHWInit(pScrn, mode))
1358		return(FALSE);
1359
1360	/*
1361	 * Here all of the MGA registers get filled in.
1362	 */
1363	hd = (mode->CrtcHDisplay	>> 3)	- 1;
1364	hs = (mode->CrtcHSyncStart	>> 3)	- 1;
1365	he = (mode->CrtcHSyncEnd	>> 3)	- 1;
1366	ht = (mode->CrtcHTotal		>> 3)	- 1;
1367	vd = mode->CrtcVDisplay			- 1;
1368	vs = mode->CrtcVSyncStart		- 1;
1369	ve = mode->CrtcVSyncEnd			- 1;
1370	vt = mode->CrtcVTotal			- 2;
1371
1372	/* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange
1373	 * vertical stripes
1374	 */
1375	if((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04)
1376		ht++;
1377
1378	if (pLayout->bitsPerPixel == 24)
1379		wd = (pLayout->displayWidth * 3) >> (4 - BppShift);
1380	else
1381		wd = pLayout->displayWidth >> (4 - BppShift);
1382
1383	pReg->ExtVga[0] = 0;
1384	pReg->ExtVga[5] = 0;
1385
1386	if (mode->Flags & V_INTERLACE)
1387	{
1388		pReg->ExtVga[0] = 0x80;
1389		pReg->ExtVga[5] = (hs + he - ht) >> 1;
1390		wd <<= 1;
1391		vt &= 0xFFFE;
1392	}
1393
1394	pReg->ExtVga[0]	|= (wd & 0x300) >> 4;
1395	pReg->ExtVga[1]	= (((ht - 4) & 0x100) >> 8) |
1396				((hd & 0x100) >> 7) |
1397				((hs & 0x100) >> 6) |
1398				(ht & 0x40);
1399	pReg->ExtVga[2]	= ((vt & 0xc00) >> 10) |
1400				((vd & 0x400) >> 8) |
1401				((vd & 0xc00) >> 7) |
1402				((vs & 0xc00) >> 5) |
1403				((vd & 0x400) >> 3); /* linecomp */
1404	if (pLayout->bitsPerPixel == 24)
1405		pReg->ExtVga[3]	= (((1 << BppShift) * 3) - 1) | 0x80;
1406	else
1407		pReg->ExtVga[3]	= ((1 << BppShift) - 1) | 0x80;
1408
1409        pReg->ExtVga[4]	= 0;
1410
1411        if (pMga->is_G200WB){
1412            pReg->ExtVga[1] |= 0x88;
1413        }
1414	pReg->ExtVga_MgaReq = 0x05;
1415
1416	pVga->CRTC[0]	= ht - 4;
1417	pVga->CRTC[1]	= hd;
1418	pVga->CRTC[2]	= hd;
1419	pVga->CRTC[3]	= (ht & 0x1F) | 0x80;
1420	pVga->CRTC[4]	= hs;
1421	pVga->CRTC[5]	= ((ht & 0x20) << 2) | (he & 0x1F);
1422	pVga->CRTC[6]	= vt & 0xFF;
1423	pVga->CRTC[7]	= ((vt & 0x100) >> 8 ) |
1424				((vd & 0x100) >> 7 ) |
1425				((vs & 0x100) >> 6 ) |
1426				((vd & 0x100) >> 5 ) |
1427				((vd & 0x100) >> 4 ) | /* linecomp */
1428				((vt & 0x200) >> 4 ) |
1429				((vd & 0x200) >> 3 ) |
1430				((vs & 0x200) >> 2 );
1431	pVga->CRTC[9]	= ((vd & 0x200) >> 4) |
1432			  ((vd & 0x200) >> 3); /* linecomp */
1433	pVga->CRTC[16] = vs & 0xFF;
1434	pVga->CRTC[17] = (ve & 0x0F) | 0x20;
1435	pVga->CRTC[18] = vd & 0xFF;
1436	pVga->CRTC[19] = wd & 0xFF;
1437	pVga->CRTC[21] = vd & 0xFF;
1438	pVga->CRTC[22] = (vt + 1) & 0xFF;
1439	pVga->CRTC[24] = vd & 0xFF; /* linecomp */
1440
1441	MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_LOW] = pMga->FbCursorOffset >> 10);
1442	MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_HI] = pMga->FbCursorOffset >> 18);
1443
1444	if (pMga->SyncOnGreen) {
1445	    MGA_NOT_HAL(
1446                pReg->DacRegs[MGA1064_GEN_CTL] &=
1447                    ~MGA1064_GEN_CTL_SYNC_ON_GREEN_DIS;
1448            );
1449
1450	    pReg->ExtVga[3] |= 0x40;
1451	}
1452
1453	/* select external clock */
1454	pVga->MiscOutReg |= 0x0C;
1455
1456	MGA_NOT_HAL(
1457	if (mode->Flags & V_DBLSCAN)
1458		pVga->CRTC[9] |= 0x80;
1459
1460	if(MGAISGx50(pMga)) {
1461		OUTREG(MGAREG_ZORG, 0);
1462	}
1463
1464  	MGAGSetPCLK(pScrn, mode->Clock);
1465	);	/* MGA_NOT_HAL */
1466
1467	/* This disables the VGA memory aperture */
1468	pVga->MiscOutReg &= ~0x02;
1469
1470	/* Urgh. Why do we define our own xMODEINFO structure instead
1471	 * of just passing the blinkin' DisplayModePtr? If we're going to
1472	 * just cut'n'paste routines from the HALlib, it would be better
1473	 * just to strip the MacroVision stuff out of the HALlib and release
1474	 * that, surely?
1475	 */
1476        /*********************  Second Crtc programming **************/
1477        /* Writing values to crtc2[] array */
1478        if (pMga->SecondCrtc)
1479        {
1480            MGACRTC2Get(pScrn, &ModeInfo);
1481            MGACRTC2GetPitch(pScrn, &ModeInfo);
1482            MGACRTC2GetDisplayStart(pScrn, &ModeInfo,0,0,0);
1483        }
1484
1485#if X_BYTE_ORDER == X_BIG_ENDIAN
1486	/* Disable byte-swapping for big-endian architectures - the XFree
1487	   driver seems to like a little-endian framebuffer -ReneR */
1488	/* pReg->Option |= 0x80000000; */
1489	pReg->Option &= ~0x80000000;
1490#endif
1491
1492	return(TRUE);
1493}
1494
1495/*
1496 * MGAGLoadPalette
1497 */
1498
1499static void
1500MGAPaletteLoadCallback(ScrnInfoPtr pScrn)
1501{
1502    MGAPtr pMga = MGAPTR(pScrn);
1503    MGAPaletteInfo *pal = pMga->palinfo;
1504    int i;
1505
1506    while (!(INREG8(0x1FDA) & 0x08));
1507
1508    for(i = 0; i < 256; i++) {
1509	if(pal->update) {
1510	    outMGAdreg(MGA1064_WADR_PAL, i);
1511            outMGAdreg(MGA1064_COL_PAL, pal->red);
1512            outMGAdreg(MGA1064_COL_PAL, pal->green);
1513            outMGAdreg(MGA1064_COL_PAL, pal->blue);
1514	    pal->update = FALSE;
1515	}
1516	pal++;
1517    }
1518    pMga->PaletteLoadCallback = NULL;
1519}
1520
1521void MGAGLoadPalette(
1522    ScrnInfoPtr pScrn,
1523    int numColors,
1524    int *indices,
1525    LOCO *colors,
1526    VisualPtr pVisual
1527){
1528    MGAPtr pMga = MGAPTR(pScrn);
1529
1530     if(pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550){
1531	 /* load them at the retrace in the block handler instead to
1532	    work around some problems with static on the screen */
1533	while(numColors--) {
1534	    pMga->palinfo[*indices].update = TRUE;
1535	    pMga->palinfo[*indices].red   = colors[*indices].red;
1536	    pMga->palinfo[*indices].green = colors[*indices].green;
1537	    pMga->palinfo[*indices].blue  = colors[*indices].blue;
1538	    indices++;
1539	}
1540	pMga->PaletteLoadCallback = MGAPaletteLoadCallback;
1541	return;
1542    } else {
1543	while(numColors--) {
1544            outMGAdreg(MGA1064_WADR_PAL, *indices);
1545            outMGAdreg(MGA1064_COL_PAL, colors[*indices].red);
1546            outMGAdreg(MGA1064_COL_PAL, colors[*indices].green);
1547            outMGAdreg(MGA1064_COL_PAL, colors[*indices].blue);
1548	    indices++;
1549	}
1550    }
1551}
1552
1553/*
1554 * MGAGRestorePalette
1555 */
1556
1557static void
1558MGAGRestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr)
1559{
1560    MGAPtr pMga = MGAPTR(pScrn);
1561    int i = 768;
1562
1563    outMGAdreg(MGA1064_WADR_PAL, 0x00);
1564    while(i--)
1565	outMGAdreg(MGA1064_COL_PAL, *(pntr++));
1566}
1567
1568/*
1569 * MGAGSavePalette
1570 */
1571static void
1572MGAGSavePalette(ScrnInfoPtr pScrn, unsigned char* pntr)
1573{
1574    MGAPtr pMga = MGAPTR(pScrn);
1575    int i = 768;
1576
1577    outMGAdreg(MGA1064_RADR_PAL, 0x00);
1578    while(i--)
1579	*(pntr++) = inMGAdreg(MGA1064_COL_PAL);
1580}
1581
1582/*
1583 * MGAGRestore
1584 *
1585 * This function restores a video mode.	 It basically writes out all of
1586 * the registers that have previously been saved.
1587 */
1588static void
1589MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
1590	       Bool restoreFonts)
1591{
1592	int i;
1593	MGAPtr pMga = MGAPTR(pScrn);
1594	CARD32 optionMask;
1595
1596MGA_NOT_HAL(
1597        if (pMga->is_G200WB)
1598        {
1599            MGAG200WBPrepareForModeSwitch(pScrn);
1600        }
1601);
1602
1603	/*
1604	 * Pixel Clock needs to be restored regardless if we use
1605	 * HALLib or not. HALlib doesn't do a good job restoring
1606	 * VESA modes. MATROX: hint, hint.
1607	 */
1608	if (MGAISGx50(pMga) && mgaReg->Clock) {
1609	    /*
1610	     * With HALlib program only when restoring to console!
1611	     * To test this we check for Clock == 0.
1612	     */
1613	    MGAG450SetPLLFreq(pScrn, mgaReg->Clock);
1614	    outMGAdac(MGA1064_PAN_CTL, mgaReg->Pan_Ctl);
1615	    mgaReg->PIXPLLCSaved = FALSE;
1616	}
1617
1618        if(!pMga->SecondCrtc) {
1619           /* Do not set the memory config for primary cards as it
1620              should be correct already. Only on little endian architectures
1621              since we need to modify the byteswap bit. -ReneR */
1622#if X_BYTE_ORDER == X_BIG_ENDIAN
1623           optionMask = OPTION1_MASK;
1624#else
1625           optionMask = (pMga->Primary) ? OPTION1_MASK_PRIMARY : OPTION1_MASK;
1626#endif
1627
1628MGA_NOT_HAL(
1629	   /*
1630	    * Code is needed to get things back to bank zero.
1631	    */
1632
1633	   /* restore DAC registers
1634	    * according to the docs we shouldn't write to reserved regs*/
1635	   for (i = 0; i < DACREGSIZE; i++) {
1636	      if( (i <= 0x03) ||
1637		  (i == 0x07) ||
1638		  (i == 0x0b) ||
1639		  (i == 0x0f) ||
1640		  ((i >= 0x13) && (i <= 0x17)) ||
1641		  (i == 0x1b) ||
1642		  (i == 0x1c) ||
1643		  ((i >= 0x1f) && (i <= 0x29)) ||
1644		  ((i >= 0x30) && (i <= 0x37)) ||
1645                  (MGAISGx50(pMga) && !mgaReg->PIXPLLCSaved &&
1646		   ((i == 0x2c) || (i == 0x2d) || (i == 0x2e) ||
1647		    (i == 0x4c) || (i == 0x4d) || (i == 0x4e))))
1648		 continue;
1649	      if (pMga->is_G200SE
1650		  && ((i == 0x2C) || (i == 0x2D) || (i == 0x2E)))
1651	         continue;
1652	      if ( (pMga->is_G200EV || pMga->is_G200WB || pMga->is_G200EH) &&
1653		   (i >= 0x44) && (i <= 0x4E))
1654	         continue;
1655
1656	      outMGAdac(i, mgaReg->DacRegs[i]);
1657	   }
1658
1659		if (pMga->is_G200ER)
1660        {
1661			outMGAdac(0x90, mgaReg->Dac_Index90);
1662        }
1663           if (pMga->is_G200SE && (pMga->reg_1e24 >= 0x04)) {
1664              outMGAdac( 0x1a, 0x09);
1665              usleep(500);
1666              outMGAdac( 0x1a, 0x01);
1667           }
1668
1669	   if (!MGAISGx50(pMga)) {
1670	       /* restore pci_option register */
1671#ifdef XSERVER_LIBPCIACCESS
1672	       pci_device_cfg_write_bits(pMga->PciInfo, optionMask,
1673					 mgaReg->Option, PCI_OPTION_REG);
1674
1675	      if (pMga->Chipset != PCI_CHIP_MGA1064) {
1676		  pci_device_cfg_write_bits(pMga->PciInfo, OPTION2_MASK,
1677					    mgaReg->Option2, PCI_MGA_OPTION2);
1678
1679		  if (pMga->Chipset == PCI_CHIP_MGAG400
1680		      || pMga->Chipset == PCI_CHIP_MGAG550) {
1681		      pci_device_cfg_write_bits(pMga->PciInfo, OPTION3_MASK,
1682						mgaReg->Option3,
1683						PCI_MGA_OPTION3);
1684		  }
1685	      }
1686#else
1687	      /* restore pci_option register */
1688	      pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, optionMask,
1689			     mgaReg->Option);
1690	      if (pMga->Chipset != PCI_CHIP_MGA1064)
1691		 pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION2, OPTION2_MASK,
1692				mgaReg->Option2);
1693	      if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550)
1694		 pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK,
1695				mgaReg->Option3);
1696#endif
1697	   }
1698
1699           if (pMga->is_G200ER) {
1700               MGAG200ERPIXPLLSET(pScrn, mgaReg);
1701           } else  if (pMga->is_G200EV) {
1702               MGAG200EVPIXPLLSET(pScrn, mgaReg);
1703           } else if (pMga->is_G200WB) {
1704               MGAG200WBPIXPLLSET(pScrn, mgaReg);
1705           } else if (pMga->is_G200EH) {
1706               MGAG200EHPIXPLLSET(pScrn, mgaReg);
1707           }
1708);	/* MGA_NOT_HAL */
1709	   /* restore CRTCEXT regs */
1710           for (i = 0; i < 6; i++)
1711	      OUTREG16(MGAREG_CRTCEXT_INDEX, (mgaReg->ExtVga[i] << 8) | i);
1712
1713           if (pMga->is_G200ER) {
1714               OUTREG8(MGAREG_CRTCEXT_INDEX, 0x24);
1715               OUTREG8(MGAREG_CRTCEXT_DATA,  mgaReg->ExtVga_MgaReq);
1716           }
1717
1718           if (pMga->is_G200WB) {
1719               if(pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI)
1720               {
1721                   OUTREG8(MGAREG_CRTCEXT_INDEX, 0x34);
1722                   OUTREG8(MGAREG_CRTCEXT_DATA,  mgaReg->ExtVga_MgaReq);
1723               }
1724           }
1725
1726	   /* This handles restoring the generic VGA registers. */
1727	   if (pMga->is_G200SE) {
1728 	      MGAG200SERestoreMode(pScrn, vgaReg);
1729	      if (restoreFonts)
1730	         MGAG200SERestoreFonts(pScrn, vgaReg);
1731	   } else {
1732	      vgaHWRestore(pScrn, vgaReg,
1733			VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0));
1734	   }
1735  	   MGAGRestorePalette(pScrn, vgaReg->DAC);
1736
1737
1738           if (pMga->is_G200EV) {
1739               OUTREG16(MGAREG_CRTCEXT_INDEX, 6);
1740               OUTREG16(MGAREG_CRTCEXT_DATA, 0);
1741           }
1742
1743	   /*
1744	    * this is needed to properly restore start address
1745	    */
1746	   OUTREG16(MGAREG_CRTCEXT_INDEX, (mgaReg->ExtVga[0] << 8) | 0);
1747
1748MGA_NOT_HAL(
1749           if (pMga->is_G200WB)
1750           {
1751               MGAG200WBRestoreFromModeSwitch(pScrn);
1752           }
1753);
1754
1755	} else {
1756	   /* Second Crtc */
1757	   xMODEINFO ModeInfo;
1758	   memset( &ModeInfo, 0, sizeof(ModeInfo) );
1759
1760MGA_NOT_HAL(
1761	   /* Enable Dual Head */
1762	   MGACRTC2Set(pScrn, &ModeInfo);
1763	   MGAEnableSecondOutPut(pScrn, &ModeInfo);
1764	   MGACRTC2SetPitch(pScrn, &ModeInfo);
1765	   MGACRTC2SetDisplayStart(pScrn, &ModeInfo,0,0,0);
1766
1767	   for (i = 0x80; i <= 0xa0; i ++) {
1768                if (i== 0x8d) {
1769		   i = 0x8f;
1770		   continue;
1771		}
1772                outMGAdac(i,   mgaReg->dac2[ i - 0x80]);
1773	   }
1774
1775); /* MGA_NOT_HAL */
1776
1777        }
1778
1779#ifdef DEBUG
1780	ErrorF("Setting DAC:");
1781	for (i=0; i<DACREGSIZE; i++) {
1782#if 1
1783		if(!(i%16)) ErrorF("\n%02X: ",i);
1784		ErrorF("%02X ", mgaReg->DacRegs[i]);
1785#else
1786		if(!(i%8)) ErrorF("\n%02X: ",i);
1787		ErrorF("0x%02X, ", mgaReg->DacRegs[i]);
1788#endif
1789	}
1790	ErrorF("\nOPTION  = %08X\n", (unsigned)mgaReg->Option);
1791	ErrorF("OPTION2 = %08X\n", (unsigned)mgaReg->Option2);
1792	ErrorF("CRTCEXT:");
1793	for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]);
1794	ErrorF("\n");
1795#endif
1796
1797}
1798
1799/*
1800 * MGAGSave
1801 *
1802 * This function saves the video state.
1803 */
1804static void
1805MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
1806	    Bool saveFonts)
1807{
1808	int i;
1809	MGAPtr pMga = MGAPTR(pScrn);
1810
1811	/*
1812	 * Pixel Clock needs to be restored regardless if we use
1813	 * HALLib or not. HALlib doesn't do a good job restoring
1814	 * VESA modes (s.o.). MATROX: hint, hint.
1815	 */
1816	if (MGAISGx50(pMga)) {
1817	    mgaReg->Pan_Ctl = inMGAdac(MGA1064_PAN_CTL);
1818	    mgaReg->Clock = MGAG450SavePLLFreq(pScrn);
1819	}
1820
1821	if(pMga->SecondCrtc == TRUE) {
1822	   for(i = 0x80; i < 0xa0; i++)
1823	      mgaReg->dac2[i-0x80] = inMGAdac(i);
1824
1825	   return;
1826	}
1827
1828	MGA_NOT_HAL(
1829	/* Allocate the DacRegs space if not done already */
1830	if (mgaReg->DacRegs == NULL) {
1831		mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
1832	}
1833	);	/* MGA_NOT_HAL */
1834
1835	/*
1836	 * Code is needed to get back to bank zero.
1837	 */
1838	OUTREG16(MGAREG_CRTCEXT_INDEX, 0x0004);
1839
1840	/*
1841	 * This function will handle creating the data structure and filling
1842	 * in the generic VGA portion.
1843	 */
1844	if (pMga->is_G200SE) {
1845 	    MGAG200SESaveMode(pScrn, vgaReg);
1846	    if (saveFonts)
1847		MGAG200SESaveFonts(pScrn, vgaReg);
1848	} else {
1849	    vgaHWSave(pScrn, vgaReg, VGA_SR_MODE |
1850				     (saveFonts ? VGA_SR_FONTS : 0));
1851	}
1852	MGAGSavePalette(pScrn, vgaReg->DAC);
1853	/*
1854	 * Work around another bug in HALlib: it doesn't restore the
1855	 * DAC width register correctly.
1856	 */
1857
1858	MGA_NOT_HAL(
1859	/*
1860	 * The port I/O code necessary to read in the extended registers.
1861	 */
1862	for (i = 0; i < DACREGSIZE; i++)
1863		mgaReg->DacRegs[i] = inMGAdac(i);
1864
1865        if (pMga->is_G200WB) {
1866            mgaReg->PllM = inMGAdac(MGA1064_WB_PIX_PLLC_M);
1867            mgaReg->PllN = inMGAdac(MGA1064_WB_PIX_PLLC_N);
1868            mgaReg->PllP = inMGAdac(MGA1064_WB_PIX_PLLC_P);
1869        } else if (pMga->is_G200EV) {
1870            mgaReg->PllM = inMGAdac(MGA1064_EV_PIX_PLLC_M);
1871            mgaReg->PllN = inMGAdac(MGA1064_EV_PIX_PLLC_N);
1872            mgaReg->PllP = inMGAdac(MGA1064_EV_PIX_PLLC_P);
1873        } else if (pMga->is_G200EH) {
1874            mgaReg->PllM = inMGAdac(MGA1064_EH_PIX_PLLC_M);
1875            mgaReg->PllN = inMGAdac(MGA1064_EH_PIX_PLLC_N);
1876            mgaReg->PllP = inMGAdac(MGA1064_EH_PIX_PLLC_P);
1877        } else if (pMga->is_G200ER) {
1878            mgaReg->PllM = inMGAdac(MGA1064_ER_PIX_PLLC_M);
1879            mgaReg->PllN = inMGAdac(MGA1064_ER_PIX_PLLC_N);
1880            mgaReg->PllP = inMGAdac(MGA1064_ER_PIX_PLLC_P);
1881            mgaReg->Dac_Index90 = inMGAdac(0x90);
1882        }
1883
1884        mgaReg->PIXPLLCSaved = TRUE;
1885
1886#ifdef XSERVER_LIBPCIACCESS
1887	pci_device_cfg_read_u32(pMga->PciInfo, & mgaReg->Option,
1888				PCI_OPTION_REG);
1889	pci_device_cfg_read_u32(pMga->PciInfo, & mgaReg->Option2,
1890				PCI_MGA_OPTION2);
1891#else
1892	mgaReg->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
1893
1894	mgaReg->Option2 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION2);
1895#endif
1896	if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550)
1897#ifdef XSERVER_LIBPCIACCESS
1898		    pci_device_cfg_read_u32(pMga->PciInfo, & mgaReg->Option3,
1899					    PCI_MGA_OPTION3);
1900#else
1901	    mgaReg->Option3 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION3);
1902#endif
1903	);	/* MGA_NOT_HAL */
1904
1905	for (i = 0; i < 6; i++)
1906	{
1907		OUTREG8(MGAREG_CRTCEXT_INDEX, i);
1908		mgaReg->ExtVga[i] = INREG8(MGAREG_CRTCEXT_DATA);
1909	}
1910	if (pMga->is_G200ER)
1911	{
1912		OUTREG8(MGAREG_CRTCEXT_INDEX, 0x24);
1913		mgaReg->ExtVga_MgaReq = INREG8(MGAREG_CRTCEXT_DATA);
1914 	}
1915        if (pMga->is_G200WB)
1916        {
1917            if(pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI)
1918            {
1919                OUTREG8(MGAREG_CRTCEXT_INDEX, 0x34);
1920                mgaReg->ExtVga_MgaReq = INREG8(MGAREG_CRTCEXT_DATA);
1921            }
1922        }
1923
1924#ifdef DEBUG
1925	ErrorF("Saved values:\nDAC:");
1926	for (i=0; i<DACREGSIZE; i++) {
1927#if 1
1928		if(!(i%16)) ErrorF("\n%02X: ",i);
1929		ErrorF("%02X ", mgaReg->DacRegs[i]);
1930#else
1931		if(!(i%8)) ErrorF("\n%02X: ",i);
1932		ErrorF("0x%02X, ", mgaReg->DacRegs[i]);
1933#endif
1934	}
1935	ErrorF("\nOPTION  = %08X\n:", (unsigned)mgaReg->Option);
1936	ErrorF("OPTION2 = %08X\nCRTCEXT:", (unsigned)mgaReg->Option2);
1937	for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]);
1938	ErrorF("\n");
1939#endif
1940}
1941
1942/****
1943 ***  HW Cursor
1944 */
1945static void
1946MGAGLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
1947{
1948    MGAPtr pMga = MGAPTR(pScrn);
1949    CARD32 *dst = (CARD32*)(pMga->FbBase + pMga->FbCursorOffset);
1950    int i = 128;
1951
1952    /* swap bytes in each line */
1953    while( i-- ) {
1954        *dst++ = (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
1955        *dst++ = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
1956        src += 8;
1957    }
1958}
1959
1960static void
1961MGAGShowCursor(ScrnInfoPtr pScrn)
1962{
1963    MGAPtr pMga = MGAPTR(pScrn);
1964    /* Enable cursor - X-Windows mode */
1965    outMGAdac(MGA1064_CURSOR_CTL, 0x03);
1966}
1967
1968static void
1969MGAGShowCursorG100(ScrnInfoPtr pScrn)
1970{
1971    MGAPtr pMga = MGAPTR(pScrn);
1972    /* Enable cursor - X-Windows mode */
1973    outMGAdac(MGA1064_CURSOR_CTL, 0x01);
1974}
1975
1976static void
1977MGAGHideCursor(ScrnInfoPtr pScrn)
1978{
1979    MGAPtr pMga = MGAPTR(pScrn);
1980    /* Disable cursor */
1981    outMGAdac(MGA1064_CURSOR_CTL, 0x00);
1982}
1983
1984static void
1985MGAGSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
1986{
1987    MGAPtr pMga = MGAPTR(pScrn);
1988    x += 64;
1989    y += 64;
1990
1991    /* cursor update must never occurs during a retrace period (pp 4-160) */
1992    while( INREG( MGAREG_Status ) & 0x08 );
1993
1994    /* Output position - "only" 12 bits of location documented */
1995    OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_XLOW, (x & 0xFF));
1996    OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_XHI, (x & 0xF00) >> 8);
1997    OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_YLOW, (y & 0xFF));
1998    OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_YHI, (y & 0xF00) >> 8);
1999}
2000
2001
2002static void
2003MGAGSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
2004{
2005    MGAPtr pMga = MGAPTR(pScrn);
2006
2007    /* Background color */
2008    outMGAdac(MGA1064_CURSOR_COL0_RED,   (bg & 0x00FF0000) >> 16);
2009    outMGAdac(MGA1064_CURSOR_COL0_GREEN, (bg & 0x0000FF00) >> 8);
2010    outMGAdac(MGA1064_CURSOR_COL0_BLUE,  (bg & 0x000000FF));
2011
2012    /* Foreground color */
2013    outMGAdac(MGA1064_CURSOR_COL1_RED,   (fg & 0x00FF0000) >> 16);
2014    outMGAdac(MGA1064_CURSOR_COL1_GREEN, (fg & 0x0000FF00) >> 8);
2015    outMGAdac(MGA1064_CURSOR_COL1_BLUE,  (fg & 0x000000FF));
2016}
2017
2018static void
2019MGAGSetCursorColorsG100(ScrnInfoPtr pScrn, int bg, int fg)
2020{
2021    MGAPtr pMga = MGAPTR(pScrn);
2022
2023    /* Background color */
2024    outMGAdac(MGA1064_CURSOR_COL1_RED,   (bg & 0x00FF0000) >> 16);
2025    outMGAdac(MGA1064_CURSOR_COL1_GREEN, (bg & 0x0000FF00) >> 8);
2026    outMGAdac(MGA1064_CURSOR_COL1_BLUE,  (bg & 0x000000FF));
2027
2028    /* Foreground color */
2029    outMGAdac(MGA1064_CURSOR_COL2_RED,   (fg & 0x00FF0000) >> 16);
2030    outMGAdac(MGA1064_CURSOR_COL2_GREEN, (fg & 0x0000FF00) >> 8);
2031    outMGAdac(MGA1064_CURSOR_COL2_BLUE,  (fg & 0x000000FF));
2032}
2033
2034static Bool
2035MGAGUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
2036{
2037    MGAPtr pMga = MGAPTR(xf86ScreenToScrn(pScrn));
2038   /* This needs to detect if its on the second dac */
2039    if( XF86SCRNINFO(pScrn)->currentMode->Flags & V_DBLSCAN )
2040    	return FALSE;
2041    if( pMga->SecondCrtc == TRUE )
2042     	return FALSE;
2043    return TRUE;
2044}
2045
2046
2047/*
2048 * According to mga-1064g.pdf pp215-216 (4-179 & 4-180) the low bits of
2049 * XGENIODATA and XGENIOCTL are connected to the 4 DDC pins, but don't say
2050 * which VGA line is connected to each DDC pin, so I've had to guess.
2051 *
2052 * DDC1 support only requires DDC_SDA_MASK,
2053 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
2054 *
2055 * If we want DDC on second head (P2) then we must use DDC2 protocol (I2C)
2056 *
2057 * Be careful, DDC1 and DDC2 refer to protocols, DDC_P1 and DDC_P2 refer to
2058 * DDC data coming in on which videoport on the card
2059 */
2060#define DDC_P1_SDA_MASK (1 << 1)
2061#define DDC_P1_SCL_MASK (1 << 3)
2062
2063static const struct mgag_i2c_private {
2064    unsigned sda_mask;
2065    unsigned scl_mask;
2066} i2c_priv[] = {
2067    { (1 << 1), (1 << 3) },
2068    { (1 << 0), (1 << 2) },
2069    { (1 << 4), (1 << 5) },
2070    { (1 << 0), (1 << 1) },  /* G200SE, G200EV and G200WB I2C bits */
2071    { (1 << 1), (1 << 0) },  /* G200EH, G200ER I2C bits */
2072};
2073
2074
2075static unsigned int
2076MGAG_ddc1Read(ScrnInfoPtr pScrn)
2077{
2078  MGAPtr pMga = MGAPTR(pScrn);
2079  unsigned char val;
2080  int i2c_index;
2081
2082  if (pMga->is_G200SE || pMga->is_G200WB || pMga->is_G200EV)
2083    i2c_index = 3;
2084  else if (pMga->is_G200EH || pMga->is_G200ER)
2085    i2c_index = 4;
2086  else
2087    i2c_index = 0;
2088
2089  const struct mgag_i2c_private *p = & i2c_priv[i2c_index];
2090
2091  /* Define the SDA as an input */
2092  outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(p->scl_mask | p->sda_mask), 0);
2093
2094  /* wait for Vsync */
2095  if (pMga->is_G200SE) {
2096    usleep(4);
2097  } else {
2098    while( INREG( MGAREG_Status ) & 0x08 );
2099    while( ! (INREG( MGAREG_Status ) & 0x08) );
2100  }
2101
2102  /* Get the result */
2103  val = (inMGAdac(MGA1064_GEN_IO_DATA) & p->sda_mask);
2104  return val;
2105}
2106
2107static void
2108MGAG_I2CGetBits(I2CBusPtr b, int *clock, int *data)
2109{
2110  ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
2111  MGAPtr pMga = MGAPTR(pScrn);
2112    const struct mgag_i2c_private *p =
2113	(struct mgag_i2c_private *) b->DriverPrivate.ptr;
2114  unsigned char val;
2115
2116   /* Get the result. */
2117   val = inMGAdac(MGA1064_GEN_IO_DATA);
2118
2119   *clock = (val & p->scl_mask) != 0;
2120   *data  = (val & p->sda_mask) != 0;
2121#ifdef DEBUG
2122  ErrorF("MGAG_I2CGetBits(%p,...) val=0x%x, returns clock %d, data %d\n", b, val, *clock, *data);
2123#endif
2124}
2125
2126/*
2127 * ATTENTION! - the DATA and CLOCK lines need to be tri-stated when
2128 * high. Therefore turn off output driver for the line to set line
2129 * to high. High signal is maintained by a 15k Ohm pull-up resistor.
2130 */
2131static void
2132MGAG_I2CPutBits(I2CBusPtr b, int clock, int data)
2133{
2134  ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
2135  MGAPtr pMga = MGAPTR(pScrn);
2136    const struct mgag_i2c_private *p =
2137	(struct mgag_i2c_private *) b->DriverPrivate.ptr;
2138  unsigned char drv, val;
2139
2140  val = (clock ? p->scl_mask : 0) | (data ? p->sda_mask : 0);
2141  drv = ((!clock) ? p->scl_mask : 0) | ((!data) ? p->sda_mask : 0);
2142
2143  /* Write the values */
2144  outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(p->scl_mask | p->sda_mask) , drv);
2145  outMGAdacmsk(MGA1064_GEN_IO_DATA, ~(p->scl_mask | p->sda_mask) , val);
2146#ifdef DEBUG
2147  ErrorF("MGAG_I2CPutBits(%p, %d, %d) val=0x%x\n", b, clock, data, val);
2148#endif
2149}
2150
2151
2152static I2CBusPtr
2153mgag_create_i2c_bus(char *name, unsigned bus_index, unsigned scrn_index)
2154{
2155    I2CBusPtr I2CPtr = xf86CreateI2CBusRec();
2156
2157    if (I2CPtr != NULL) {
2158	I2CPtr->BusName = name;
2159	I2CPtr->scrnIndex = scrn_index;
2160	I2CPtr->I2CPutBits = MGAG_I2CPutBits;
2161	I2CPtr->I2CGetBits = MGAG_I2CGetBits;
2162	I2CPtr->AcknTimeout = 5;
2163	I2CPtr->DriverPrivate.ptr = (void *) &i2c_priv[bus_index];
2164
2165	if (!xf86I2CBusInit(I2CPtr)) {
2166	    xf86DestroyI2CBusRec(I2CPtr, TRUE, TRUE);
2167	    I2CPtr = NULL;
2168	}
2169    }
2170
2171    return I2CPtr;
2172}
2173
2174
2175Bool
2176MGAG_i2cInit(ScrnInfoPtr pScrn)
2177{
2178    MGAPtr pMga = MGAPTR(pScrn);
2179
2180    if (pMga->SecondCrtc == FALSE) {
2181        int i2c_index;
2182
2183        if (pMga->is_G200SE || pMga->is_G200WB || pMga->is_G200EV)
2184            i2c_index = 3;
2185        else if (pMga->is_G200EH || pMga->is_G200ER)
2186            i2c_index = 4;
2187        else
2188            i2c_index = 0;
2189
2190	pMga->DDC_Bus1 = mgag_create_i2c_bus("DDC P1",
2191					     i2c_index, pScrn->scrnIndex);
2192	return (pMga->DDC_Bus1 != NULL);
2193    } else {
2194	/* We have a dual head setup on G-series, set up DDC #2. */
2195	pMga->DDC_Bus2 = mgag_create_i2c_bus("DDC P2", 1, pScrn->scrnIndex);
2196
2197	if (pMga->DDC_Bus2 != NULL) {
2198	    /* 0xA0 is DDC EEPROM address */
2199	    if (!xf86I2CProbeAddress(pMga->DDC_Bus2, 0xA0)) {
2200		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC #2 unavailable -> TV cable connected or no monitor connected!\n");
2201		pMga->Crtc2IsTV = TRUE;  /* assume for now.  We need to fix HAL interactions. */
2202	    }
2203	}
2204
2205	/* Then try to set up MAVEN bus. */
2206	pMga->Maven_Bus = mgag_create_i2c_bus("MAVEN", 2, pScrn->scrnIndex);
2207	if (pMga->Maven_Bus != NULL) {
2208	    pMga->Maven = NULL;
2209	    pMga->Maven_Version = 0;
2210
2211	    /* Try to detect the MAVEN. */
2212	    if (xf86I2CProbeAddress(pMga->Maven_Bus, MAVEN_READ)) {
2213		I2CDevPtr dp = xf86CreateI2CDevRec();
2214		if (dp) {
2215		    I2CByte maven_ver;
2216
2217		    dp->DevName = "MGA-TVO";
2218		    dp->SlaveAddr = MAVEN_WRITE;
2219		    dp->pI2CBus = pMga->Maven_Bus;
2220		    if (!xf86I2CDevInit(dp)) {
2221			xf86DestroyI2CDevRec(dp, TRUE);
2222		    } else {
2223			pMga->Maven = dp;
2224			if (MGAMavenRead(pScrn, 0xB2, &maven_ver)) {
2225			    /* heuristic stolen from matroxfb */
2226			    pMga->Maven_Version = (maven_ver < 0x14)
2227				? 'B' : 'C';
2228
2229			    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2230				       "MAVEN revision MGA-TVO-%c detected (0x%x)\n",
2231				       pMga->Maven_Version, maven_ver);
2232			} else {
2233			    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to determine MAVEN hardware version!\n");
2234			}
2235		    }
2236		}
2237	    }
2238
2239	    if (pMga->Maven == NULL) {
2240		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
2241			   "Failed to register MGA-TVO I2C device!\n");
2242	    }
2243	}
2244    }
2245
2246    return TRUE;
2247}
2248
2249
2250/*
2251 * MGAGRamdacInit
2252 * Handle broken G100 special.
2253 */
2254static void
2255MGAGRamdacInit(ScrnInfoPtr pScrn)
2256{
2257    MGAPtr pMga = MGAPTR(pScrn);
2258    MGARamdacPtr MGAdac = &pMga->Dac;
2259
2260    MGAdac->isHwCursor             = TRUE;
2261    MGAdac->CursorOffscreenMemSize = 1024;
2262    MGAdac->CursorMaxWidth         = 64;
2263    MGAdac->CursorMaxHeight        = 64;
2264    MGAdac->SetCursorPosition      = MGAGSetCursorPosition;
2265    MGAdac->LoadCursorImage        = MGAGLoadCursorImage;
2266    MGAdac->HideCursor             = MGAGHideCursor;
2267    if ((pMga->Chipset == PCI_CHIP_MGAG100)
2268	|| (pMga->Chipset == PCI_CHIP_MGAG100)) {
2269      MGAdac->SetCursorColors        = MGAGSetCursorColorsG100;
2270      MGAdac->ShowCursor             = MGAGShowCursorG100;
2271    } else {
2272      MGAdac->SetCursorColors        = MGAGSetCursorColors;
2273      MGAdac->ShowCursor             = MGAGShowCursor;
2274    }
2275    MGAdac->UseHWCursor            = MGAGUseHWCursor;
2276    MGAdac->CursorFlags            =
2277#if X_BYTE_ORDER == X_LITTLE_ENDIAN
2278    				HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
2279#endif
2280    				HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
2281    				HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
2282
2283    MGAdac->LoadPalette 	   = MGAGLoadPalette;
2284    MGAdac->RestorePalette	   = MGAGRestorePalette;
2285
2286
2287    MGAdac->maxPixelClock = pMga->bios.pixel.max_freq;
2288    MGAdac->ClockFrom = X_PROBED;
2289
2290    /* Disable interleaving and set the rounding value */
2291    pMga->Interleave = FALSE;
2292
2293    pMga->Roundings[0] = 64;
2294    pMga->Roundings[1] = 32;
2295    pMga->Roundings[2] = 64;
2296    pMga->Roundings[3] = 32;
2297
2298    /* Clear Fast bitblt flag */
2299    pMga->HasFBitBlt = FALSE;
2300}
2301
2302void MGAGSetupFuncs(ScrnInfoPtr pScrn)
2303{
2304    MGAPtr pMga = MGAPTR(pScrn);
2305
2306    pMga->PreInit = MGAGRamdacInit;
2307    pMga->Save = MGAGSave;
2308    pMga->Restore = MGAGRestore;
2309    pMga->ModeInit = MGAGInit;
2310    if ((!pMga->is_G200WB) && (!pMga->is_G200ER)) {
2311        pMga->ddc1Read = MGAG_ddc1Read;
2312        /* vgaHWddc1SetSpeed will only work if the card is in VGA mode */
2313        pMga->DDC1SetSpeed = vgaHWddc1SetSpeedWeak();
2314    } else {
2315        pMga->ddc1Read = NULL;
2316        pMga->DDC1SetSpeed = NULL;
2317    }
2318    pMga->i2cInit = MGAG_i2cInit;
2319}
2320
2321