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