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