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