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