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