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 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 120static void 121MGAG200SEComputePLLParam(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 162static void 163MGAG200EVComputePLLParam(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 210static void 211MGAG200WBComputePLLParam(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 267void 268MGAG200EW3ComputePLLParam(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 332static void 333MGAG200EHComputePLLParam(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 378void 379MGAG200EH3ComputePLLParam(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 421static void 422MGAG200EVPIXPLLSET(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 486static void 487MGAG200WBPIXPLLSET(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 610static 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 677static void 678MGAG200ERPIXPLLSET(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 716static void 717MGAG200WBPrepareForModeSwitch(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 765static void 766MGAG200WBRestoreFromModeSwitch(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 804static void 805MGAG200EHPIXPLLSET(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 897static void 898MGAGCalcClock ( 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 double av; 960 calc_f = ref_freq * (n + 1) / (m + 1) ; 961 962 /* 963 * Pick the closest frequency. 964 */ 965 if ( fabs(calc_f - f_vco) < m_err ) { 966 m_err = fabs(calc_f - f_vco); 967 *best_m = m; 968 *best_n = n; 969 } 970 } 971 } 972 973 /* Now all the calculations can be completed */ 974 f_vco = ref_freq * (*best_n + 1) / (*best_m + 1); 975 976 /* Adjustments for filtering pll feed back */ 977 if ( (50000.0 <= f_vco) 978 && (f_vco < 100000.0) ) 979 *s = 0; 980 if ( (100000.0 <= f_vco) 981 && (f_vco < 140000.0) ) 982 *s = 1; 983 if ( (140000.0 <= f_vco) 984 && (f_vco < 180000.0) ) 985 *s = 2; 986 if ( (180000.0 <= f_vco) ) 987 *s = 3; 988 989#ifdef DEBUG 990 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 991 "f_out_requ =%ld f_pll_real=%.1f f_vco=%.1f n=0x%x m=0x%x p=0x%x s=0x%x\n", 992 f_out, (f_vco / (*p + 1)), f_vco, *best_n, *best_m, *p, *s ); 993#endif 994} 995 996/* 997 * MGAGSetPCLK - Set the pixel (PCLK) clock. 998 */ 999static void 1000MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) 1001{ 1002 MGAPtr pMga = MGAPTR(pScrn); 1003 MGARegPtr pReg = &pMga->ModeReg; 1004 1005 /* Pixel clock values */ 1006 int m, n, p, s; 1007 m = n = p = s = 0; 1008 1009 if(MGAISGx50(pMga)) { 1010 pReg->Clock = f_out; 1011 if (pMga->Chipset == PCI_CHIP_MGAG550) { 1012 if (f_out < 45000) { 1013 pReg->Pan_Ctl = 0x00; 1014 } else if (f_out < 55000) { 1015 pReg->Pan_Ctl = 0x08; 1016 } else if (f_out < 70000) { 1017 pReg->Pan_Ctl = 0x10; 1018 } else if (f_out < 85000) { 1019 pReg->Pan_Ctl = 0x18; 1020 } else if (f_out < 100000) { 1021 pReg->Pan_Ctl = 0x20; 1022 } else if (f_out < 115000) { 1023 pReg->Pan_Ctl = 0x28; 1024 } else if (f_out < 125000) { 1025 pReg->Pan_Ctl = 0x30; 1026 } else { 1027 pReg->Pan_Ctl = 0x38; 1028 } 1029 } else { 1030 if (f_out < 45000) { 1031 pReg->Pan_Ctl = 0x00; 1032 } else if (f_out < 65000) { 1033 pReg->Pan_Ctl = 0x08; 1034 } else if (f_out < 85000) { 1035 pReg->Pan_Ctl = 0x10; 1036 } else if (f_out < 105000) { 1037 pReg->Pan_Ctl = 0x18; 1038 } else if (f_out < 135000) { 1039 pReg->Pan_Ctl = 0x20; 1040 } else if (f_out < 160000) { 1041 pReg->Pan_Ctl = 0x28; 1042 } else if (f_out < 175000) { 1043 pReg->Pan_Ctl = 0x30; 1044 } else { 1045 pReg->Pan_Ctl = 0x38; 1046 } 1047 } 1048 return; 1049 } 1050 1051 if (pMga->is_G200SE) { 1052 if (pMga->reg_1e24 >= 0x04) { 1053 MGAG200E4ComputePLLParam(pScrn, f_out, &m, &n, &p); 1054 } else { 1055 MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p); 1056 } 1057 1058 pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m; 1059 pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n; 1060 pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = p; 1061 } else if (pMga->is_G200EV) { 1062 MGAG200EVComputePLLParam(pScrn, f_out, &m, &n, &p); 1063 1064 pReg->PllM = m; 1065 pReg->PllN = n; 1066 pReg->PllP = p; 1067 } else if (pMga->is_G200WB) { 1068 if (pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI) 1069 { 1070 MGAG200EW3ComputePLLParam(pScrn, f_out, &m, &n, &p); 1071 } 1072 else 1073 { 1074 MGAG200WBComputePLLParam(pScrn, f_out, &m, &n, &p); 1075 } 1076 1077 pReg->PllM = m; 1078 pReg->PllN = n; 1079 pReg->PllP = p; 1080 } else if (pMga->is_G200EH) { 1081 if (pMga->Chipset == PCI_CHIP_MGAG200_EH3_PCI) 1082 { 1083 MGAG200EH3ComputePLLParam(pScrn, f_out, &m, &n, &p); 1084 } 1085 else 1086 { 1087 MGAG200EHComputePLLParam(pScrn, f_out, &m, &n, &p); 1088 } 1089 1090 pReg->PllM = m; 1091 pReg->PllN = n; 1092 pReg->PllP = p; 1093 } else if (pMga->is_G200ER) { 1094 MGAG200ERComputePLLParam(pScrn, f_out, &m, &n, &p); 1095 pReg->PllM = m; 1096 pReg->PllN = n; 1097 pReg->PllP = p; 1098 } else { 1099 /* Do the calculations for m, n, p and s */ 1100 MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); 1101 1102 /* Values for the pixel clock PLL registers */ 1103 pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F; 1104 pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F; 1105 pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | 1106 ((s & 0x03) << 3); 1107 } 1108} 1109 1110/* 1111 * MGAGInit 1112 */ 1113static Bool 1114MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1115{ 1116 /* 1117 * initial values of the DAC registers 1118 */ 1119 const static unsigned char initDAC[] = { 1120 /* 0x00: */ 0, 0, 0, 0, 0, 0, 0x00, 0, 1121 /* 0x08: */ 0, 0, 0, 0, 0, 0, 0, 0, 1122 /* 0x10: */ 0, 0, 0, 0, 0, 0, 0, 0, 1123 /* 0x18: */ 0x00, 0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20, 1124 /* 0x20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1125 /* 0x28: */ 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x40, 1126 /* 0x30: */ 0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83, 1127 /* 0x38: */ 0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A, 1128 /* 0x40: */ 0, 0, 0, 0, 0, 0, 0, 0, 1129 /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0 1130 }; 1131 1132 int i; 1133 int hd, hs, he, ht, vd, vs, ve, vt, wd; 1134 int BppShift; 1135 MGAPtr pMga; 1136 MGARegPtr pReg; 1137 vgaRegPtr pVga; 1138 MGAFBLayout *pLayout; 1139 xMODEINFO ModeInfo; 1140 1141 ModeInfo.ulDispWidth = mode->HDisplay; 1142 ModeInfo.ulDispHeight = mode->VDisplay; 1143 ModeInfo.ulFBPitch = mode->HDisplay; 1144 ModeInfo.ulBpp = pScrn->bitsPerPixel; 1145 ModeInfo.flSignalMode = 0; 1146 ModeInfo.ulPixClock = mode->Clock; 1147 ModeInfo.ulHFPorch = mode->HSyncStart - mode->HDisplay; 1148 ModeInfo.ulHSync = mode->HSyncEnd - mode->HSyncStart; 1149 ModeInfo.ulHBPorch = mode->HTotal - mode->HSyncEnd; 1150 ModeInfo.ulVFPorch = mode->VSyncStart - mode->VDisplay; 1151 ModeInfo.ulVSync = mode->VSyncEnd - mode->VSyncStart; 1152 ModeInfo.ulVBPorch = mode->VTotal - mode->VSyncEnd; 1153 1154 pMga = MGAPTR(pScrn); 1155 pReg = &pMga->ModeReg; 1156 pVga = &VGAHWPTR(pScrn)->ModeReg; 1157 pLayout = &pMga->CurrentLayout; 1158 1159 BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]; 1160 1161 MGA_NOT_HAL( 1162 /* Allocate the DacRegs space if not done already */ 1163 if (pReg->DacRegs == NULL) { 1164 pReg->DacRegs = xnfcalloc(DACREGSIZE, 1); 1165 } 1166 for (i = 0; i < DACREGSIZE; i++) { 1167 pReg->DacRegs[i] = initDAC[i]; 1168 } 1169 ); /* MGA_NOT_HAL */ 1170 1171 switch(pMga->Chipset) 1172 { 1173 case PCI_CHIP_MGA1064: 1174 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04; 1175 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x44; 1176 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; 1177 pReg->Option = 0x5F094F21; 1178 pReg->Option2 = 0x00000000; 1179 break; 1180 case PCI_CHIP_MGAG100: 1181 case PCI_CHIP_MGAG100_PCI: 1182 pReg->DacRegs[MGA1064_VREF_CTL] = 0x03; 1183 1184 if(pMga->HasSDRAM) { 1185 if(pMga->OverclockMem) { 1186 /* 220 Mhz */ 1187 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06; 1188 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x38; 1189 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; 1190 } else { 1191 /* 203 Mhz */ 1192 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x01; 1193 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x0E; 1194 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; 1195 } 1196 pReg->Option = 0x404991a9; 1197 } else { 1198 if(pMga->OverclockMem) { 1199 /* 143 Mhz */ 1200 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06; 1201 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24; 1202 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10; 1203 } else { 1204 /* 124 Mhz */ 1205 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04; 1206 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x16; 1207 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08; 1208 } 1209 pReg->Option = 0x4049d121; 1210 } 1211 pReg->Option2 = 0x0000007; 1212 break; 1213 case PCI_CHIP_MGAG400: 1214 case PCI_CHIP_MGAG550: 1215 if (MGAISGx50(pMga)) 1216 break; 1217 1218 if(pMga->Dac.maxPixelClock == 360000) { /* G400 MAX */ 1219 if(pMga->OverclockMem) { 1220 /* 150/200 */ 1221 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x05; 1222 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x42; 1223 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; 1224 pReg->Option3 = 0x019B8419; 1225 pReg->Option = 0x50574120; 1226 } else { 1227 /* 125/166 */ 1228 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02; 1229 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B; 1230 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; 1231 pReg->Option3 = 0x019B8419; 1232 pReg->Option = 0x5053C120; 1233 } 1234 } else { 1235 if(pMga->OverclockMem) { 1236 /* 125/166 */ 1237 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x02; 1238 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x1B; 1239 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18; 1240 pReg->Option3 = 0x019B8419; 1241 pReg->Option = 0x5053C120; 1242 } else { 1243 /* 110/166 */ 1244 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13; 1245 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A; 1246 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08; 1247 pReg->Option3 = 0x0190a421; 1248 pReg->Option = 0x50044120; 1249 } 1250 } 1251 if(pMga->HasSDRAM) 1252 pReg->Option &= ~(1 << 14); 1253 pReg->Option2 = 0x01003000; 1254 break; 1255 case PCI_CHIP_MGAG200_SE_A_PCI: 1256 case PCI_CHIP_MGAG200_SE_B_PCI: 1257 pReg->DacRegs[ MGA1064_VREF_CTL ] = 0x03; 1258 pReg->DacRegs[MGA1064_PIX_CLK_CTL] = 1259 MGA1064_PIX_CLK_CTL_SEL_PLL; 1260 1261 pReg->DacRegs[MGA1064_MISC_CTL] = 1262 MGA1064_MISC_CTL_DAC_EN | 1263 MGA1064_MISC_CTL_VGA8 | 1264 MGA1064_MISC_CTL_DAC_RAM_CS; 1265 1266 if (pMga->HasSDRAM) 1267 pReg->Option = 0x40049120; 1268 pReg->Option2 = 0x00008000; 1269 break; 1270 1271 case PCI_CHIP_MGAG200_WINBOND_PCI: 1272 case PCI_CHIP_MGAG200_EW3_PCI: 1273 pReg->DacRegs[MGA1064_VREF_CTL] = 0x07; 1274 pReg->Option = 0x41049120; 1275 pReg->Option2 = 0x0000b000; 1276 break; 1277 1278 case PCI_CHIP_MGAG200_EV_PCI: 1279 pReg->DacRegs[MGA1064_PIX_CLK_CTL] = 1280 MGA1064_PIX_CLK_CTL_SEL_PLL; 1281 1282 pReg->DacRegs[MGA1064_MISC_CTL] = 1283 MGA1064_MISC_CTL_VGA8 | 1284 MGA1064_MISC_CTL_DAC_RAM_CS; 1285 1286 pReg->Option = 0x00000120; 1287 pReg->Option2 = 0x0000b000; 1288 break; 1289 1290 case PCI_CHIP_MGAG200_ER_PCI: 1291 pReg->Dac_Index90 = 0; 1292 break; 1293 1294 case PCI_CHIP_MGAG200_EH_PCI: 1295 case PCI_CHIP_MGAG200_EH3_PCI: 1296 pReg->DacRegs[MGA1064_MISC_CTL] = 1297 MGA1064_MISC_CTL_VGA8 | 1298 MGA1064_MISC_CTL_DAC_RAM_CS; 1299 1300 pReg->Option = 0x00000120; 1301 pReg->Option2 = 0x0000b000; 1302 break; 1303 1304 case PCI_CHIP_MGAG200: 1305 case PCI_CHIP_MGAG200_PCI: 1306 default: 1307 if(pMga->OverclockMem) { 1308 /* 143 Mhz */ 1309 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06; 1310 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24; 1311 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10; 1312 } else { 1313 /* 124 Mhz */ 1314 pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04; 1315 pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x2D; 1316 pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x19; 1317 } 1318 pReg->Option2 = 0x00008000; 1319 if(pMga->HasSDRAM) 1320 pReg->Option = 0x40499121; 1321 else 1322 pReg->Option = 0x4049cd21; 1323 break; 1324 } 1325 1326 MGA_NOT_HAL( 1327 /* must always have the pci retries on but rely on 1328 polling to keep them from occurring */ 1329 pReg->Option &= ~0x20000000; 1330 1331 switch(pLayout->bitsPerPixel) 1332 { 1333 case 8: 1334 pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_8bits; 1335 break; 1336 case 16: 1337 pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_16bits; 1338 if ( (pLayout->weight.red == 5) && (pLayout->weight.green == 5) 1339 && (pLayout->weight.blue == 5) ) { 1340 pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_15bits; 1341 } 1342 break; 1343 case 24: 1344 pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_24bits; 1345 break; 1346 case 32: 1347 pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32_24bits; 1348 break; 1349 default: 1350 FatalError("MGA: unsupported depth\n"); 1351 } 1352 ); /* MGA_NOT_HAL */ 1353 1354 /* 1355 * This will initialize all of the generic VGA registers. 1356 */ 1357 if (!vgaHWInit(pScrn, mode)) 1358 return(FALSE); 1359 1360 /* 1361 * Here all of the MGA registers get filled in. 1362 */ 1363 hd = (mode->CrtcHDisplay >> 3) - 1; 1364 hs = (mode->CrtcHSyncStart >> 3) - 1; 1365 he = (mode->CrtcHSyncEnd >> 3) - 1; 1366 ht = (mode->CrtcHTotal >> 3) - 1; 1367 vd = mode->CrtcVDisplay - 1; 1368 vs = mode->CrtcVSyncStart - 1; 1369 ve = mode->CrtcVSyncEnd - 1; 1370 vt = mode->CrtcVTotal - 2; 1371 1372 /* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange 1373 * vertical stripes 1374 */ 1375 if((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04) 1376 ht++; 1377 1378 if (pLayout->bitsPerPixel == 24) 1379 wd = (pLayout->displayWidth * 3) >> (4 - BppShift); 1380 else 1381 wd = pLayout->displayWidth >> (4 - BppShift); 1382 1383 pReg->ExtVga[0] = 0; 1384 pReg->ExtVga[5] = 0; 1385 1386 if (mode->Flags & V_INTERLACE) 1387 { 1388 pReg->ExtVga[0] = 0x80; 1389 pReg->ExtVga[5] = (hs + he - ht) >> 1; 1390 wd <<= 1; 1391 vt &= 0xFFFE; 1392 } 1393 1394 pReg->ExtVga[0] |= (wd & 0x300) >> 4; 1395 pReg->ExtVga[1] = (((ht - 4) & 0x100) >> 8) | 1396 ((hd & 0x100) >> 7) | 1397 ((hs & 0x100) >> 6) | 1398 (ht & 0x40); 1399 pReg->ExtVga[2] = ((vt & 0xc00) >> 10) | 1400 ((vd & 0x400) >> 8) | 1401 ((vd & 0xc00) >> 7) | 1402 ((vs & 0xc00) >> 5) | 1403 ((vd & 0x400) >> 3); /* linecomp */ 1404 if (pLayout->bitsPerPixel == 24) 1405 pReg->ExtVga[3] = (((1 << BppShift) * 3) - 1) | 0x80; 1406 else 1407 pReg->ExtVga[3] = ((1 << BppShift) - 1) | 0x80; 1408 1409 pReg->ExtVga[4] = 0; 1410 1411 if (pMga->is_G200WB){ 1412 pReg->ExtVga[1] |= 0x88; 1413 } 1414 pReg->ExtVga_MgaReq = 0x05; 1415 1416 pVga->CRTC[0] = ht - 4; 1417 pVga->CRTC[1] = hd; 1418 pVga->CRTC[2] = hd; 1419 pVga->CRTC[3] = (ht & 0x1F) | 0x80; 1420 pVga->CRTC[4] = hs; 1421 pVga->CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F); 1422 pVga->CRTC[6] = vt & 0xFF; 1423 pVga->CRTC[7] = ((vt & 0x100) >> 8 ) | 1424 ((vd & 0x100) >> 7 ) | 1425 ((vs & 0x100) >> 6 ) | 1426 ((vd & 0x100) >> 5 ) | 1427 ((vd & 0x100) >> 4 ) | /* linecomp */ 1428 ((vt & 0x200) >> 4 ) | 1429 ((vd & 0x200) >> 3 ) | 1430 ((vs & 0x200) >> 2 ); 1431 pVga->CRTC[9] = ((vd & 0x200) >> 4) | 1432 ((vd & 0x200) >> 3); /* linecomp */ 1433 pVga->CRTC[16] = vs & 0xFF; 1434 pVga->CRTC[17] = (ve & 0x0F) | 0x20; 1435 pVga->CRTC[18] = vd & 0xFF; 1436 pVga->CRTC[19] = wd & 0xFF; 1437 pVga->CRTC[21] = vd & 0xFF; 1438 pVga->CRTC[22] = (vt + 1) & 0xFF; 1439 pVga->CRTC[24] = vd & 0xFF; /* linecomp */ 1440 1441 MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_LOW] = pMga->FbCursorOffset >> 10); 1442 MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_HI] = pMga->FbCursorOffset >> 18); 1443 1444 if (pMga->SyncOnGreen) { 1445 MGA_NOT_HAL( 1446 pReg->DacRegs[MGA1064_GEN_CTL] &= 1447 ~MGA1064_GEN_CTL_SYNC_ON_GREEN_DIS; 1448 ); 1449 1450 pReg->ExtVga[3] |= 0x40; 1451 } 1452 1453 /* select external clock */ 1454 pVga->MiscOutReg |= 0x0C; 1455 1456 MGA_NOT_HAL( 1457 if (mode->Flags & V_DBLSCAN) 1458 pVga->CRTC[9] |= 0x80; 1459 1460 if(MGAISGx50(pMga)) { 1461 OUTREG(MGAREG_ZORG, 0); 1462 } 1463 1464 MGAGSetPCLK(pScrn, mode->Clock); 1465 ); /* MGA_NOT_HAL */ 1466 1467 /* This disables the VGA memory aperture */ 1468 pVga->MiscOutReg &= ~0x02; 1469 1470 /* Urgh. Why do we define our own xMODEINFO structure instead 1471 * of just passing the blinkin' DisplayModePtr? If we're going to 1472 * just cut'n'paste routines from the HALlib, it would be better 1473 * just to strip the MacroVision stuff out of the HALlib and release 1474 * that, surely? 1475 */ 1476 /********************* Second Crtc programming **************/ 1477 /* Writing values to crtc2[] array */ 1478 if (pMga->SecondCrtc) 1479 { 1480 MGACRTC2Get(pScrn, &ModeInfo); 1481 MGACRTC2GetPitch(pScrn, &ModeInfo); 1482 MGACRTC2GetDisplayStart(pScrn, &ModeInfo,0,0,0); 1483 } 1484 1485#if X_BYTE_ORDER == X_BIG_ENDIAN 1486 /* Disable byte-swapping for big-endian architectures - the XFree 1487 driver seems to like a little-endian framebuffer -ReneR */ 1488 /* pReg->Option |= 0x80000000; */ 1489 pReg->Option &= ~0x80000000; 1490#endif 1491 1492 return(TRUE); 1493} 1494 1495/* 1496 * MGAGLoadPalette 1497 */ 1498 1499static void 1500MGAPaletteLoadCallback(ScrnInfoPtr pScrn) 1501{ 1502 MGAPtr pMga = MGAPTR(pScrn); 1503 MGAPaletteInfo *pal = pMga->palinfo; 1504 int i; 1505 1506 while (!(INREG8(0x1FDA) & 0x08)); 1507 1508 for(i = 0; i < 256; i++) { 1509 if(pal->update) { 1510 outMGAdreg(MGA1064_WADR_PAL, i); 1511 outMGAdreg(MGA1064_COL_PAL, pal->red); 1512 outMGAdreg(MGA1064_COL_PAL, pal->green); 1513 outMGAdreg(MGA1064_COL_PAL, pal->blue); 1514 pal->update = FALSE; 1515 } 1516 pal++; 1517 } 1518 pMga->PaletteLoadCallback = NULL; 1519} 1520 1521void MGAGLoadPalette( 1522 ScrnInfoPtr pScrn, 1523 int numColors, 1524 int *indices, 1525 LOCO *colors, 1526 VisualPtr pVisual 1527){ 1528 MGAPtr pMga = MGAPTR(pScrn); 1529 1530 if(pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550){ 1531 /* load them at the retrace in the block handler instead to 1532 work around some problems with static on the screen */ 1533 while(numColors--) { 1534 pMga->palinfo[*indices].update = TRUE; 1535 pMga->palinfo[*indices].red = colors[*indices].red; 1536 pMga->palinfo[*indices].green = colors[*indices].green; 1537 pMga->palinfo[*indices].blue = colors[*indices].blue; 1538 indices++; 1539 } 1540 pMga->PaletteLoadCallback = MGAPaletteLoadCallback; 1541 return; 1542 } else { 1543 while(numColors--) { 1544 outMGAdreg(MGA1064_WADR_PAL, *indices); 1545 outMGAdreg(MGA1064_COL_PAL, colors[*indices].red); 1546 outMGAdreg(MGA1064_COL_PAL, colors[*indices].green); 1547 outMGAdreg(MGA1064_COL_PAL, colors[*indices].blue); 1548 indices++; 1549 } 1550 } 1551} 1552 1553/* 1554 * MGAGRestorePalette 1555 */ 1556 1557static void 1558MGAGRestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr) 1559{ 1560 MGAPtr pMga = MGAPTR(pScrn); 1561 int i = 768; 1562 1563 outMGAdreg(MGA1064_WADR_PAL, 0x00); 1564 while(i--) 1565 outMGAdreg(MGA1064_COL_PAL, *(pntr++)); 1566} 1567 1568/* 1569 * MGAGSavePalette 1570 */ 1571static void 1572MGAGSavePalette(ScrnInfoPtr pScrn, unsigned char* pntr) 1573{ 1574 MGAPtr pMga = MGAPTR(pScrn); 1575 int i = 768; 1576 1577 outMGAdreg(MGA1064_RADR_PAL, 0x00); 1578 while(i--) 1579 *(pntr++) = inMGAdreg(MGA1064_COL_PAL); 1580} 1581 1582/* 1583 * MGAGRestore 1584 * 1585 * This function restores a video mode. It basically writes out all of 1586 * the registers that have previously been saved. 1587 */ 1588static void 1589MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, 1590 Bool restoreFonts) 1591{ 1592 int i; 1593 MGAPtr pMga = MGAPTR(pScrn); 1594 CARD32 optionMask; 1595 1596MGA_NOT_HAL( 1597 if (pMga->is_G200WB) 1598 { 1599 MGAG200WBPrepareForModeSwitch(pScrn); 1600 } 1601); 1602 1603 /* 1604 * Pixel Clock needs to be restored regardless if we use 1605 * HALLib or not. HALlib doesn't do a good job restoring 1606 * VESA modes. MATROX: hint, hint. 1607 */ 1608 if (MGAISGx50(pMga) && mgaReg->Clock) { 1609 /* 1610 * With HALlib program only when restoring to console! 1611 * To test this we check for Clock == 0. 1612 */ 1613 MGAG450SetPLLFreq(pScrn, mgaReg->Clock); 1614 outMGAdac(MGA1064_PAN_CTL, mgaReg->Pan_Ctl); 1615 mgaReg->PIXPLLCSaved = FALSE; 1616 } 1617 1618 if(!pMga->SecondCrtc) { 1619 /* Do not set the memory config for primary cards as it 1620 should be correct already. Only on little endian architectures 1621 since we need to modify the byteswap bit. -ReneR */ 1622#if X_BYTE_ORDER == X_BIG_ENDIAN 1623 optionMask = OPTION1_MASK; 1624#else 1625 optionMask = (pMga->Primary) ? OPTION1_MASK_PRIMARY : OPTION1_MASK; 1626#endif 1627 1628MGA_NOT_HAL( 1629 /* 1630 * Code is needed to get things back to bank zero. 1631 */ 1632 1633 /* restore DAC registers 1634 * according to the docs we shouldn't write to reserved regs*/ 1635 for (i = 0; i < DACREGSIZE; i++) { 1636 if( (i <= 0x03) || 1637 (i == 0x07) || 1638 (i == 0x0b) || 1639 (i == 0x0f) || 1640 ((i >= 0x13) && (i <= 0x17)) || 1641 (i == 0x1b) || 1642 (i == 0x1c) || 1643 ((i >= 0x1f) && (i <= 0x29)) || 1644 ((i >= 0x30) && (i <= 0x37)) || 1645 (MGAISGx50(pMga) && !mgaReg->PIXPLLCSaved && 1646 ((i == 0x2c) || (i == 0x2d) || (i == 0x2e) || 1647 (i == 0x4c) || (i == 0x4d) || (i == 0x4e)))) 1648 continue; 1649 if (pMga->is_G200SE 1650 && ((i == 0x2C) || (i == 0x2D) || (i == 0x2E))) 1651 continue; 1652 if ( (pMga->is_G200EV || pMga->is_G200WB || pMga->is_G200EH) && 1653 (i >= 0x44) && (i <= 0x4E)) 1654 continue; 1655 1656 outMGAdac(i, mgaReg->DacRegs[i]); 1657 } 1658 1659 if (pMga->is_G200ER) 1660 { 1661 outMGAdac(0x90, mgaReg->Dac_Index90); 1662 } 1663 if (pMga->is_G200SE && (pMga->reg_1e24 >= 0x04)) { 1664 outMGAdac( 0x1a, 0x09); 1665 usleep(500); 1666 outMGAdac( 0x1a, 0x01); 1667 } 1668 1669 if (!MGAISGx50(pMga)) { 1670 /* restore pci_option register */ 1671#ifdef XSERVER_LIBPCIACCESS 1672 pci_device_cfg_write_bits(pMga->PciInfo, optionMask, 1673 mgaReg->Option, PCI_OPTION_REG); 1674 1675 if (pMga->Chipset != PCI_CHIP_MGA1064) { 1676 pci_device_cfg_write_bits(pMga->PciInfo, OPTION2_MASK, 1677 mgaReg->Option2, PCI_MGA_OPTION2); 1678 1679 if (pMga->Chipset == PCI_CHIP_MGAG400 1680 || pMga->Chipset == PCI_CHIP_MGAG550) { 1681 pci_device_cfg_write_bits(pMga->PciInfo, OPTION3_MASK, 1682 mgaReg->Option3, 1683 PCI_MGA_OPTION3); 1684 } 1685 } 1686#else 1687 /* restore pci_option register */ 1688 pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, optionMask, 1689 mgaReg->Option); 1690 if (pMga->Chipset != PCI_CHIP_MGA1064) 1691 pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION2, OPTION2_MASK, 1692 mgaReg->Option2); 1693 if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) 1694 pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK, 1695 mgaReg->Option3); 1696#endif 1697 } 1698 1699 if (pMga->is_G200ER) { 1700 MGAG200ERPIXPLLSET(pScrn, mgaReg); 1701 } else if (pMga->is_G200EV) { 1702 MGAG200EVPIXPLLSET(pScrn, mgaReg); 1703 } else if (pMga->is_G200WB) { 1704 MGAG200WBPIXPLLSET(pScrn, mgaReg); 1705 } else if (pMga->is_G200EH) { 1706 MGAG200EHPIXPLLSET(pScrn, mgaReg); 1707 } 1708); /* MGA_NOT_HAL */ 1709 /* restore CRTCEXT regs */ 1710 for (i = 0; i < 6; i++) 1711 OUTREG16(MGAREG_CRTCEXT_INDEX, (mgaReg->ExtVga[i] << 8) | i); 1712 1713 if (pMga->is_G200ER) { 1714 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x24); 1715 OUTREG8(MGAREG_CRTCEXT_DATA, mgaReg->ExtVga_MgaReq); 1716 } 1717 1718 if (pMga->is_G200WB) { 1719 if(pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI) 1720 { 1721 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x34); 1722 OUTREG8(MGAREG_CRTCEXT_DATA, mgaReg->ExtVga_MgaReq); 1723 } 1724 } 1725 1726 /* This handles restoring the generic VGA registers. */ 1727 if (pMga->is_G200SE) { 1728 MGAG200SERestoreMode(pScrn, vgaReg); 1729 if (restoreFonts) 1730 MGAG200SERestoreFonts(pScrn, vgaReg); 1731 } else { 1732 vgaHWRestore(pScrn, vgaReg, 1733 VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0)); 1734 } 1735 MGAGRestorePalette(pScrn, vgaReg->DAC); 1736 1737 1738 if (pMga->is_G200EV) { 1739 OUTREG16(MGAREG_CRTCEXT_INDEX, 6); 1740 OUTREG16(MGAREG_CRTCEXT_DATA, 0); 1741 } 1742 1743 /* 1744 * this is needed to properly restore start address 1745 */ 1746 OUTREG16(MGAREG_CRTCEXT_INDEX, (mgaReg->ExtVga[0] << 8) | 0); 1747 1748MGA_NOT_HAL( 1749 if (pMga->is_G200WB) 1750 { 1751 MGAG200WBRestoreFromModeSwitch(pScrn); 1752 } 1753); 1754 1755 } else { 1756 /* Second Crtc */ 1757 xMODEINFO ModeInfo; 1758 memset( &ModeInfo, 0, sizeof(ModeInfo) ); 1759 1760MGA_NOT_HAL( 1761 /* Enable Dual Head */ 1762 MGACRTC2Set(pScrn, &ModeInfo); 1763 MGAEnableSecondOutPut(pScrn, &ModeInfo); 1764 MGACRTC2SetPitch(pScrn, &ModeInfo); 1765 MGACRTC2SetDisplayStart(pScrn, &ModeInfo,0,0,0); 1766 1767 for (i = 0x80; i <= 0xa0; i ++) { 1768 if (i== 0x8d) { 1769 i = 0x8f; 1770 continue; 1771 } 1772 outMGAdac(i, mgaReg->dac2[ i - 0x80]); 1773 } 1774 1775); /* MGA_NOT_HAL */ 1776 1777 } 1778 1779#ifdef DEBUG 1780 ErrorF("Setting DAC:"); 1781 for (i=0; i<DACREGSIZE; i++) { 1782#if 1 1783 if(!(i%16)) ErrorF("\n%02X: ",i); 1784 ErrorF("%02X ", mgaReg->DacRegs[i]); 1785#else 1786 if(!(i%8)) ErrorF("\n%02X: ",i); 1787 ErrorF("0x%02X, ", mgaReg->DacRegs[i]); 1788#endif 1789 } 1790 ErrorF("\nOPTION = %08X\n", (unsigned)mgaReg->Option); 1791 ErrorF("OPTION2 = %08X\n", (unsigned)mgaReg->Option2); 1792 ErrorF("CRTCEXT:"); 1793 for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]); 1794 ErrorF("\n"); 1795#endif 1796 1797} 1798 1799/* 1800 * MGAGSave 1801 * 1802 * This function saves the video state. 1803 */ 1804static void 1805MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, 1806 Bool saveFonts) 1807{ 1808 int i; 1809 MGAPtr pMga = MGAPTR(pScrn); 1810 1811 /* 1812 * Pixel Clock needs to be restored regardless if we use 1813 * HALLib or not. HALlib doesn't do a good job restoring 1814 * VESA modes (s.o.). MATROX: hint, hint. 1815 */ 1816 if (MGAISGx50(pMga)) { 1817 mgaReg->Pan_Ctl = inMGAdac(MGA1064_PAN_CTL); 1818 mgaReg->Clock = MGAG450SavePLLFreq(pScrn); 1819 } 1820 1821 if(pMga->SecondCrtc == TRUE) { 1822 for(i = 0x80; i < 0xa0; i++) 1823 mgaReg->dac2[i-0x80] = inMGAdac(i); 1824 1825 return; 1826 } 1827 1828 MGA_NOT_HAL( 1829 /* Allocate the DacRegs space if not done already */ 1830 if (mgaReg->DacRegs == NULL) { 1831 mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1); 1832 } 1833 ); /* MGA_NOT_HAL */ 1834 1835 /* 1836 * Code is needed to get back to bank zero. 1837 */ 1838 OUTREG16(MGAREG_CRTCEXT_INDEX, 0x0004); 1839 1840 /* 1841 * This function will handle creating the data structure and filling 1842 * in the generic VGA portion. 1843 */ 1844 if (pMga->is_G200SE) { 1845 MGAG200SESaveMode(pScrn, vgaReg); 1846 if (saveFonts) 1847 MGAG200SESaveFonts(pScrn, vgaReg); 1848 } else { 1849 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | 1850 (saveFonts ? VGA_SR_FONTS : 0)); 1851 } 1852 MGAGSavePalette(pScrn, vgaReg->DAC); 1853 /* 1854 * Work around another bug in HALlib: it doesn't restore the 1855 * DAC width register correctly. 1856 */ 1857 1858 MGA_NOT_HAL( 1859 /* 1860 * The port I/O code necessary to read in the extended registers. 1861 */ 1862 for (i = 0; i < DACREGSIZE; i++) 1863 mgaReg->DacRegs[i] = inMGAdac(i); 1864 1865 if (pMga->is_G200WB) { 1866 mgaReg->PllM = inMGAdac(MGA1064_WB_PIX_PLLC_M); 1867 mgaReg->PllN = inMGAdac(MGA1064_WB_PIX_PLLC_N); 1868 mgaReg->PllP = inMGAdac(MGA1064_WB_PIX_PLLC_P); 1869 } else if (pMga->is_G200EV) { 1870 mgaReg->PllM = inMGAdac(MGA1064_EV_PIX_PLLC_M); 1871 mgaReg->PllN = inMGAdac(MGA1064_EV_PIX_PLLC_N); 1872 mgaReg->PllP = inMGAdac(MGA1064_EV_PIX_PLLC_P); 1873 } else if (pMga->is_G200EH) { 1874 mgaReg->PllM = inMGAdac(MGA1064_EH_PIX_PLLC_M); 1875 mgaReg->PllN = inMGAdac(MGA1064_EH_PIX_PLLC_N); 1876 mgaReg->PllP = inMGAdac(MGA1064_EH_PIX_PLLC_P); 1877 } else if (pMga->is_G200ER) { 1878 mgaReg->PllM = inMGAdac(MGA1064_ER_PIX_PLLC_M); 1879 mgaReg->PllN = inMGAdac(MGA1064_ER_PIX_PLLC_N); 1880 mgaReg->PllP = inMGAdac(MGA1064_ER_PIX_PLLC_P); 1881 mgaReg->Dac_Index90 = inMGAdac(0x90); 1882 } 1883 1884 mgaReg->PIXPLLCSaved = TRUE; 1885 1886#ifdef XSERVER_LIBPCIACCESS 1887 pci_device_cfg_read_u32(pMga->PciInfo, & mgaReg->Option, 1888 PCI_OPTION_REG); 1889 pci_device_cfg_read_u32(pMga->PciInfo, & mgaReg->Option2, 1890 PCI_MGA_OPTION2); 1891#else 1892 mgaReg->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG); 1893 1894 mgaReg->Option2 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION2); 1895#endif 1896 if (pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) 1897#ifdef XSERVER_LIBPCIACCESS 1898 pci_device_cfg_read_u32(pMga->PciInfo, & mgaReg->Option3, 1899 PCI_MGA_OPTION3); 1900#else 1901 mgaReg->Option3 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION3); 1902#endif 1903 ); /* MGA_NOT_HAL */ 1904 1905 for (i = 0; i < 6; i++) 1906 { 1907 OUTREG8(MGAREG_CRTCEXT_INDEX, i); 1908 mgaReg->ExtVga[i] = INREG8(MGAREG_CRTCEXT_DATA); 1909 } 1910 if (pMga->is_G200ER) 1911 { 1912 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x24); 1913 mgaReg->ExtVga_MgaReq = INREG8(MGAREG_CRTCEXT_DATA); 1914 } 1915 if (pMga->is_G200WB) 1916 { 1917 if(pMga->Chipset == PCI_CHIP_MGAG200_EW3_PCI) 1918 { 1919 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x34); 1920 mgaReg->ExtVga_MgaReq = INREG8(MGAREG_CRTCEXT_DATA); 1921 } 1922 } 1923 1924#ifdef DEBUG 1925 ErrorF("Saved values:\nDAC:"); 1926 for (i=0; i<DACREGSIZE; i++) { 1927#if 1 1928 if(!(i%16)) ErrorF("\n%02X: ",i); 1929 ErrorF("%02X ", mgaReg->DacRegs[i]); 1930#else 1931 if(!(i%8)) ErrorF("\n%02X: ",i); 1932 ErrorF("0x%02X, ", mgaReg->DacRegs[i]); 1933#endif 1934 } 1935 ErrorF("\nOPTION = %08X\n:", (unsigned)mgaReg->Option); 1936 ErrorF("OPTION2 = %08X\nCRTCEXT:", (unsigned)mgaReg->Option2); 1937 for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]); 1938 ErrorF("\n"); 1939#endif 1940} 1941 1942/**** 1943 *** HW Cursor 1944 */ 1945static void 1946MGAGLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 1947{ 1948 MGAPtr pMga = MGAPTR(pScrn); 1949 CARD32 *dst = (CARD32*)(pMga->FbBase + pMga->FbCursorOffset); 1950 int i = 128; 1951 1952 /* swap bytes in each line */ 1953 while( i-- ) { 1954 *dst++ = (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7]; 1955 *dst++ = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; 1956 src += 8; 1957 } 1958} 1959 1960static void 1961MGAGShowCursor(ScrnInfoPtr pScrn) 1962{ 1963 MGAPtr pMga = MGAPTR(pScrn); 1964 /* Enable cursor - X-Windows mode */ 1965 outMGAdac(MGA1064_CURSOR_CTL, 0x03); 1966} 1967 1968static void 1969MGAGShowCursorG100(ScrnInfoPtr pScrn) 1970{ 1971 MGAPtr pMga = MGAPTR(pScrn); 1972 /* Enable cursor - X-Windows mode */ 1973 outMGAdac(MGA1064_CURSOR_CTL, 0x01); 1974} 1975 1976static void 1977MGAGHideCursor(ScrnInfoPtr pScrn) 1978{ 1979 MGAPtr pMga = MGAPTR(pScrn); 1980 /* Disable cursor */ 1981 outMGAdac(MGA1064_CURSOR_CTL, 0x00); 1982} 1983 1984static void 1985MGAGSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 1986{ 1987 MGAPtr pMga = MGAPTR(pScrn); 1988 x += 64; 1989 y += 64; 1990 1991 /* cursor update must never occurs during a retrace period (pp 4-160) */ 1992 while( INREG( MGAREG_Status ) & 0x08 ); 1993 1994 /* Output position - "only" 12 bits of location documented */ 1995 OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_XLOW, (x & 0xFF)); 1996 OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_XHI, (x & 0xF00) >> 8); 1997 OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_YLOW, (y & 0xFF)); 1998 OUTREG8( RAMDAC_OFFSET + MGA1064_CUR_YHI, (y & 0xF00) >> 8); 1999} 2000 2001 2002static void 2003MGAGSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 2004{ 2005 MGAPtr pMga = MGAPTR(pScrn); 2006 2007 /* Background color */ 2008 outMGAdac(MGA1064_CURSOR_COL0_RED, (bg & 0x00FF0000) >> 16); 2009 outMGAdac(MGA1064_CURSOR_COL0_GREEN, (bg & 0x0000FF00) >> 8); 2010 outMGAdac(MGA1064_CURSOR_COL0_BLUE, (bg & 0x000000FF)); 2011 2012 /* Foreground color */ 2013 outMGAdac(MGA1064_CURSOR_COL1_RED, (fg & 0x00FF0000) >> 16); 2014 outMGAdac(MGA1064_CURSOR_COL1_GREEN, (fg & 0x0000FF00) >> 8); 2015 outMGAdac(MGA1064_CURSOR_COL1_BLUE, (fg & 0x000000FF)); 2016} 2017 2018static void 2019MGAGSetCursorColorsG100(ScrnInfoPtr pScrn, int bg, int fg) 2020{ 2021 MGAPtr pMga = MGAPTR(pScrn); 2022 2023 /* Background color */ 2024 outMGAdac(MGA1064_CURSOR_COL1_RED, (bg & 0x00FF0000) >> 16); 2025 outMGAdac(MGA1064_CURSOR_COL1_GREEN, (bg & 0x0000FF00) >> 8); 2026 outMGAdac(MGA1064_CURSOR_COL1_BLUE, (bg & 0x000000FF)); 2027 2028 /* Foreground color */ 2029 outMGAdac(MGA1064_CURSOR_COL2_RED, (fg & 0x00FF0000) >> 16); 2030 outMGAdac(MGA1064_CURSOR_COL2_GREEN, (fg & 0x0000FF00) >> 8); 2031 outMGAdac(MGA1064_CURSOR_COL2_BLUE, (fg & 0x000000FF)); 2032} 2033 2034static Bool 2035MGAGUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs) 2036{ 2037 MGAPtr pMga = MGAPTR(xf86ScreenToScrn(pScrn)); 2038 /* This needs to detect if its on the second dac */ 2039 if( XF86SCRNINFO(pScrn)->currentMode->Flags & V_DBLSCAN ) 2040 return FALSE; 2041 if( pMga->SecondCrtc == TRUE ) 2042 return FALSE; 2043 return TRUE; 2044} 2045 2046 2047/* 2048 * According to mga-1064g.pdf pp215-216 (4-179 & 4-180) the low bits of 2049 * XGENIODATA and XGENIOCTL are connected to the 4 DDC pins, but don't say 2050 * which VGA line is connected to each DDC pin, so I've had to guess. 2051 * 2052 * DDC1 support only requires DDC_SDA_MASK, 2053 * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK 2054 * 2055 * If we want DDC on second head (P2) then we must use DDC2 protocol (I2C) 2056 * 2057 * Be careful, DDC1 and DDC2 refer to protocols, DDC_P1 and DDC_P2 refer to 2058 * DDC data coming in on which videoport on the card 2059 */ 2060#define DDC_P1_SDA_MASK (1 << 1) 2061#define DDC_P1_SCL_MASK (1 << 3) 2062 2063static const struct mgag_i2c_private { 2064 unsigned sda_mask; 2065 unsigned scl_mask; 2066} i2c_priv[] = { 2067 { (1 << 1), (1 << 3) }, 2068 { (1 << 0), (1 << 2) }, 2069 { (1 << 4), (1 << 5) }, 2070 { (1 << 0), (1 << 1) }, /* G200SE, G200EV and G200WB I2C bits */ 2071 { (1 << 1), (1 << 0) }, /* G200EH, G200ER I2C bits */ 2072}; 2073 2074 2075static unsigned int 2076MGAG_ddc1Read(ScrnInfoPtr pScrn) 2077{ 2078 MGAPtr pMga = MGAPTR(pScrn); 2079 unsigned char val; 2080 int i2c_index; 2081 2082 if (pMga->is_G200SE || pMga->is_G200WB || pMga->is_G200EV) 2083 i2c_index = 3; 2084 else if (pMga->is_G200EH || pMga->is_G200ER) 2085 i2c_index = 4; 2086 else 2087 i2c_index = 0; 2088 2089 const struct mgag_i2c_private *p = & i2c_priv[i2c_index]; 2090 2091 /* Define the SDA as an input */ 2092 outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(p->scl_mask | p->sda_mask), 0); 2093 2094 /* wait for Vsync */ 2095 if (pMga->is_G200SE) { 2096 usleep(4); 2097 } else { 2098 while( INREG( MGAREG_Status ) & 0x08 ); 2099 while( ! (INREG( MGAREG_Status ) & 0x08) ); 2100 } 2101 2102 /* Get the result */ 2103 val = (inMGAdac(MGA1064_GEN_IO_DATA) & p->sda_mask); 2104 return val; 2105} 2106 2107static void 2108MGAG_I2CGetBits(I2CBusPtr b, int *clock, int *data) 2109{ 2110 ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; 2111 MGAPtr pMga = MGAPTR(pScrn); 2112 const struct mgag_i2c_private *p = 2113 (struct mgag_i2c_private *) b->DriverPrivate.ptr; 2114 unsigned char val; 2115 2116 /* Get the result. */ 2117 val = inMGAdac(MGA1064_GEN_IO_DATA); 2118 2119 *clock = (val & p->scl_mask) != 0; 2120 *data = (val & p->sda_mask) != 0; 2121#ifdef DEBUG 2122 ErrorF("MGAG_I2CGetBits(%p,...) val=0x%x, returns clock %d, data %d\n", b, val, *clock, *data); 2123#endif 2124} 2125 2126/* 2127 * ATTENTION! - the DATA and CLOCK lines need to be tri-stated when 2128 * high. Therefore turn off output driver for the line to set line 2129 * to high. High signal is maintained by a 15k Ohm pull-up resistor. 2130 */ 2131static void 2132MGAG_I2CPutBits(I2CBusPtr b, int clock, int data) 2133{ 2134 ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; 2135 MGAPtr pMga = MGAPTR(pScrn); 2136 const struct mgag_i2c_private *p = 2137 (struct mgag_i2c_private *) b->DriverPrivate.ptr; 2138 unsigned char drv, val; 2139 2140 val = (clock ? p->scl_mask : 0) | (data ? p->sda_mask : 0); 2141 drv = ((!clock) ? p->scl_mask : 0) | ((!data) ? p->sda_mask : 0); 2142 2143 /* Write the values */ 2144 outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(p->scl_mask | p->sda_mask) , drv); 2145 outMGAdacmsk(MGA1064_GEN_IO_DATA, ~(p->scl_mask | p->sda_mask) , val); 2146#ifdef DEBUG 2147 ErrorF("MGAG_I2CPutBits(%p, %d, %d) val=0x%x\n", b, clock, data, val); 2148#endif 2149} 2150 2151 2152static I2CBusPtr 2153mgag_create_i2c_bus(char *name, unsigned bus_index, unsigned scrn_index) 2154{ 2155 I2CBusPtr I2CPtr = xf86CreateI2CBusRec(); 2156 2157 if (I2CPtr != NULL) { 2158 I2CPtr->BusName = name; 2159 I2CPtr->scrnIndex = scrn_index; 2160 I2CPtr->I2CPutBits = MGAG_I2CPutBits; 2161 I2CPtr->I2CGetBits = MGAG_I2CGetBits; 2162 I2CPtr->AcknTimeout = 5; 2163 I2CPtr->DriverPrivate.ptr = (void *) &i2c_priv[bus_index]; 2164 2165 if (!xf86I2CBusInit(I2CPtr)) { 2166 xf86DestroyI2CBusRec(I2CPtr, TRUE, TRUE); 2167 I2CPtr = NULL; 2168 } 2169 } 2170 2171 return I2CPtr; 2172} 2173 2174 2175Bool 2176MGAG_i2cInit(ScrnInfoPtr pScrn) 2177{ 2178 MGAPtr pMga = MGAPTR(pScrn); 2179 2180 if (pMga->SecondCrtc == FALSE) { 2181 int i2c_index; 2182 2183 if (pMga->is_G200SE || pMga->is_G200WB || pMga->is_G200EV) 2184 i2c_index = 3; 2185 else if (pMga->is_G200EH || pMga->is_G200ER) 2186 i2c_index = 4; 2187 else 2188 i2c_index = 0; 2189 2190 pMga->DDC_Bus1 = mgag_create_i2c_bus("DDC P1", 2191 i2c_index, pScrn->scrnIndex); 2192 return (pMga->DDC_Bus1 != NULL); 2193 } else { 2194 /* We have a dual head setup on G-series, set up DDC #2. */ 2195 pMga->DDC_Bus2 = mgag_create_i2c_bus("DDC P2", 1, pScrn->scrnIndex); 2196 2197 if (pMga->DDC_Bus2 != NULL) { 2198 /* 0xA0 is DDC EEPROM address */ 2199 if (!xf86I2CProbeAddress(pMga->DDC_Bus2, 0xA0)) { 2200 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC #2 unavailable -> TV cable connected or no monitor connected!\n"); 2201 pMga->Crtc2IsTV = TRUE; /* assume for now. We need to fix HAL interactions. */ 2202 } 2203 } 2204 2205 /* Then try to set up MAVEN bus. */ 2206 pMga->Maven_Bus = mgag_create_i2c_bus("MAVEN", 2, pScrn->scrnIndex); 2207 if (pMga->Maven_Bus != NULL) { 2208 pMga->Maven = NULL; 2209 pMga->Maven_Version = 0; 2210 2211 /* Try to detect the MAVEN. */ 2212 if (xf86I2CProbeAddress(pMga->Maven_Bus, MAVEN_READ)) { 2213 I2CDevPtr dp = xf86CreateI2CDevRec(); 2214 if (dp) { 2215 I2CByte maven_ver; 2216 2217 dp->DevName = "MGA-TVO"; 2218 dp->SlaveAddr = MAVEN_WRITE; 2219 dp->pI2CBus = pMga->Maven_Bus; 2220 if (!xf86I2CDevInit(dp)) { 2221 xf86DestroyI2CDevRec(dp, TRUE); 2222 } else { 2223 pMga->Maven = dp; 2224 if (MGAMavenRead(pScrn, 0xB2, &maven_ver)) { 2225 /* heuristic stolen from matroxfb */ 2226 pMga->Maven_Version = (maven_ver < 0x14) 2227 ? 'B' : 'C'; 2228 2229 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2230 "MAVEN revision MGA-TVO-%c detected (0x%x)\n", 2231 pMga->Maven_Version, maven_ver); 2232 } else { 2233 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to determine MAVEN hardware version!\n"); 2234 } 2235 } 2236 } 2237 } 2238 2239 if (pMga->Maven == NULL) { 2240 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2241 "Failed to register MGA-TVO I2C device!\n"); 2242 } 2243 } 2244 } 2245 2246 return TRUE; 2247} 2248 2249 2250/* 2251 * MGAGRamdacInit 2252 * Handle broken G100 special. 2253 */ 2254static void 2255MGAGRamdacInit(ScrnInfoPtr pScrn) 2256{ 2257 MGAPtr pMga = MGAPTR(pScrn); 2258 MGARamdacPtr MGAdac = &pMga->Dac; 2259 2260 MGAdac->isHwCursor = TRUE; 2261 MGAdac->CursorOffscreenMemSize = 1024; 2262 MGAdac->CursorMaxWidth = 64; 2263 MGAdac->CursorMaxHeight = 64; 2264 MGAdac->SetCursorPosition = MGAGSetCursorPosition; 2265 MGAdac->LoadCursorImage = MGAGLoadCursorImage; 2266 MGAdac->HideCursor = MGAGHideCursor; 2267 if ((pMga->Chipset == PCI_CHIP_MGAG100) 2268 || (pMga->Chipset == PCI_CHIP_MGAG100)) { 2269 MGAdac->SetCursorColors = MGAGSetCursorColorsG100; 2270 MGAdac->ShowCursor = MGAGShowCursorG100; 2271 } else { 2272 MGAdac->SetCursorColors = MGAGSetCursorColors; 2273 MGAdac->ShowCursor = MGAGShowCursor; 2274 } 2275 MGAdac->UseHWCursor = MGAGUseHWCursor; 2276 MGAdac->CursorFlags = 2277#if X_BYTE_ORDER == X_LITTLE_ENDIAN 2278 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 2279#endif 2280 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 2281 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 2282 2283 MGAdac->LoadPalette = MGAGLoadPalette; 2284 MGAdac->RestorePalette = MGAGRestorePalette; 2285 2286 2287 MGAdac->maxPixelClock = pMga->bios.pixel.max_freq; 2288 MGAdac->ClockFrom = X_PROBED; 2289 2290 /* Disable interleaving and set the rounding value */ 2291 pMga->Interleave = FALSE; 2292 2293 pMga->Roundings[0] = 64; 2294 pMga->Roundings[1] = 32; 2295 pMga->Roundings[2] = 64; 2296 pMga->Roundings[3] = 32; 2297 2298 /* Clear Fast bitblt flag */ 2299 pMga->HasFBitBlt = FALSE; 2300} 2301 2302void MGAGSetupFuncs(ScrnInfoPtr pScrn) 2303{ 2304 MGAPtr pMga = MGAPTR(pScrn); 2305 2306 pMga->PreInit = MGAGRamdacInit; 2307 pMga->Save = MGAGSave; 2308 pMga->Restore = MGAGRestore; 2309 pMga->ModeInit = MGAGInit; 2310 if ((!pMga->is_G200WB) && (!pMga->is_G200ER)) { 2311 pMga->ddc1Read = MGAG_ddc1Read; 2312 /* vgaHWddc1SetSpeed will only work if the card is in VGA mode */ 2313 pMga->DDC1SetSpeed = vgaHWddc1SetSpeedWeak(); 2314 } else { 2315 pMga->ddc1Read = NULL; 2316 pMga->DDC1SetSpeed = NULL; 2317 } 2318 pMga->i2cInit = MGAG_i2cInit; 2319} 2320 2321