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