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