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