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