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