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