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