via_outputs.c revision 963d66ac
1/* 2 * Copyright 2005-2015 The Openchrome Project 3 * [http://www.freedesktop.org/wiki/Openchrome] 4 * Copyright 2004-2005 The Unichrome Project [unichrome.sf.net] 5 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 6 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sub license, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 * DEALINGS IN THE SOFTWARE. 26 */ 27 28/* 29 * via_outputs.c 30 * 31 * Everything to do with setting and changing xf86Outputs. 32 * 33 */ 34 35#ifdef HAVE_CONFIG_H 36#include "config.h" 37#endif 38 39#include "via_driver.h" 40#include <unistd.h> 41 42/* 43 * Modetable nonsense. 44 * 45 */ 46#include "via_mode.h" 47 48static void 49ViaPrintMode(ScrnInfoPtr pScrn, DisplayModePtr mode) 50{ 51 xf86PrintModeline(pScrn->scrnIndex, mode); 52 53 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHDisplay: 0x%x\n", 54 mode->CrtcHDisplay); 55 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankStart: 0x%x\n", 56 mode->CrtcHBlankStart); 57 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncStart: 0x%x\n", 58 mode->CrtcHSyncStart); 59 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSyncEnd: 0x%x\n", 60 mode->CrtcHSyncEnd); 61 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHBlankEnd: 0x%x\n", 62 mode->CrtcHBlankEnd); 63 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHTotal: 0x%x\n", 64 mode->CrtcHTotal); 65 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcHSkew: 0x%x\n", 66 mode->CrtcHSkew); 67 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVDisplay: 0x%x\n", 68 mode->CrtcVDisplay); 69 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankStart: 0x%x\n", 70 mode->CrtcVBlankStart); 71 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncStart: 0x%x\n", 72 mode->CrtcVSyncStart); 73 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVSyncEnd: 0x%x\n", 74 mode->CrtcVSyncEnd); 75 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVBlankEnd: 0x%x\n", 76 mode->CrtcVBlankEnd); 77 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CrtcVTotal: 0x%x\n", 78 mode->CrtcVTotal); 79 80} 81 82/* 83 * 84 * TV specific code. 85 * 86 */ 87void 88ViaTVSave(ScrnInfoPtr pScrn) 89{ 90 VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 91 92 if (pBIOSInfo->TVSave) 93 pBIOSInfo->TVSave(pScrn); 94} 95 96void 97ViaTVRestore(ScrnInfoPtr pScrn) 98{ 99 VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 100 101 if (pBIOSInfo->TVRestore) 102 pBIOSInfo->TVRestore(pScrn); 103} 104 105static Bool 106ViaTVDACSense(ScrnInfoPtr pScrn) 107{ 108 VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 109 110 if (pBIOSInfo->TVDACSense) 111 return pBIOSInfo->TVDACSense(pScrn); 112 return FALSE; 113} 114 115static void 116ViaTVSetMode(xf86CrtcPtr crtc, DisplayModePtr mode) 117{ 118 ScrnInfoPtr pScrn = crtc->scrn; 119 VIAPtr pVia = VIAPTR(pScrn); 120 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 121 122 if (pBIOSInfo->TVModeI2C) 123 pBIOSInfo->TVModeI2C(pScrn, mode); 124 125 if (pBIOSInfo->TVModeCrtc) 126 pBIOSInfo->TVModeCrtc(crtc, mode); 127 128 /* TV reset. */ 129 xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1D, 0x00); 130 xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1D, 0x80); 131} 132 133void 134ViaTVPower(ScrnInfoPtr pScrn, Bool On) 135{ 136 VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 137 138#ifdef HAVE_DEBUG 139 if (On) 140 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVPower: On.\n"); 141 else 142 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaTVPower: Off.\n"); 143#endif 144 145 if (pBIOSInfo->TVPower) 146 pBIOSInfo->TVPower(pScrn, On); 147} 148 149#ifdef HAVE_DEBUG 150void 151ViaTVPrintRegs(ScrnInfoPtr pScrn) 152{ 153 VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; 154 155 if (pBIOSInfo->TVPrintRegs) 156 pBIOSInfo->TVPrintRegs(pScrn); 157} 158#endif /* HAVE_DEBUG */ 159 160static void 161via_tv_create_resources(xf86OutputPtr output) 162{ 163} 164 165#ifdef RANDR_12_INTERFACE 166static Bool 167via_tv_set_property(xf86OutputPtr output, Atom property, 168 RRPropertyValuePtr value) 169{ 170 return TRUE; 171} 172 173static Bool 174via_tv_get_property(xf86OutputPtr output, Atom property) 175{ 176 return FALSE; 177} 178#endif 179 180static void 181via_tv_dpms(xf86OutputPtr output, int mode) 182{ 183 ScrnInfoPtr pScrn = output->scrn; 184 185 switch (mode) { 186 case DPMSModeOn: 187 ViaTVPower(pScrn, TRUE); 188 break; 189 190 case DPMSModeStandby: 191 case DPMSModeSuspend: 192 case DPMSModeOff: 193 ViaTVPower(pScrn, FALSE); 194 break; 195 } 196} 197 198static void 199via_tv_save(xf86OutputPtr output) 200{ 201 ScrnInfoPtr pScrn = output->scrn; 202 203 ViaTVSave(pScrn); 204} 205 206static void 207via_tv_restore(xf86OutputPtr output) 208{ 209 ScrnInfoPtr pScrn = output->scrn; 210 211 ViaTVRestore(pScrn); 212} 213 214static int 215via_tv_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) 216{ 217 ScrnInfoPtr pScrn = output->scrn; 218 VIAPtr pVia = VIAPTR(pScrn); 219 int ret = MODE_OK; 220 221 if (!ViaModeDotClockTranslate(pScrn, pMode)) 222 return MODE_NOCLOCK; 223 224 return ret; 225} 226 227static Bool 228via_tv_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, 229 DisplayModePtr adjusted_mode) 230{ 231 return TRUE; 232} 233 234static void 235via_tv_prepare(xf86OutputPtr output) 236{ 237 via_tv_dpms(output, DPMSModeOff); 238} 239 240static void 241via_tv_commit(xf86OutputPtr output) 242{ 243 via_tv_dpms(output, DPMSModeOn); 244} 245 246static void 247ViaDisplayEnableDVO(ScrnInfoPtr pScrn, int port) 248{ 249 vgaHWPtr hwp = VGAHWPTR(pScrn); 250 251 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayEnableDVO, port: %d\n", 252 port)); 253 switch (port) { 254 case VIA_DI_PORT_DVP0: 255 ViaSeqMask(hwp, 0x1E, 0xC0, 0xC0); 256 break; 257 case VIA_DI_PORT_DVP1: 258 ViaSeqMask(hwp, 0x1E, 0x30, 0x30); 259 break; 260 } 261} 262 263static void 264ViaDisplayDisableDVO(ScrnInfoPtr pScrn, int port) 265{ 266 vgaHWPtr hwp = VGAHWPTR(pScrn); 267 268 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayDisableDVO, port: %d\n", 269 port)); 270 switch (port) { 271 case VIA_DI_PORT_DVP0: 272 ViaSeqMask(hwp, 0x1E, 0x00, 0xC0); 273 break; 274 case VIA_DI_PORT_DVP1: 275 ViaSeqMask(hwp, 0x1E, 0x00, 0x30); 276 break; 277 } 278} 279 280static void 281ViaDisplaySetStreamOnDVO(ScrnInfoPtr pScrn, int port, int iga) 282{ 283 vgaHWPtr hwp = VGAHWPTR(pScrn); 284 int regNum; 285 286 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplaySetStreamOnDVO, port: %d\n", 287 port)); 288 289 switch (port) { 290 case VIA_DI_PORT_DVP0: 291 regNum = 0x96; 292 break; 293 case VIA_DI_PORT_DVP1: 294 regNum = 0x9B; 295 break; 296 case VIA_DI_PORT_DFPLOW: 297 regNum = 0x97; 298 break; 299 case VIA_DI_PORT_DFPHIGH: 300 regNum = 0x99; 301 break; 302 } 303 304 if (!iga) 305 ViaCrtcMask(hwp, regNum, 0x00, 0x10); 306 else 307 ViaCrtcMask(hwp, regNum, 0x10, 0x10); 308} 309 310static void 311via_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode, 312 DisplayModePtr adjusted_mode) 313{ 314 ScrnInfoPtr pScrn = output->scrn; 315 VIAPtr pVia = VIAPTR(pScrn); 316 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 317 318 /* TV on FirstCrtc */ 319 if (output->crtc) { 320 drmmode_crtc_private_ptr iga = output->crtc->driver_private; 321 322 ViaDisplaySetStreamOnDVO(pScrn, pBIOSInfo->TVDIPort, iga->index); 323 } 324 ViaDisplayEnableDVO(pScrn, pBIOSInfo->TVDIPort); 325 326 ViaTVSetMode(output->crtc, adjusted_mode); 327 328 pVia->FirstInit = FALSE; 329} 330 331static xf86OutputStatus 332via_tv_detect(xf86OutputPtr output) 333{ 334 xf86OutputStatus status = XF86OutputStatusDisconnected; 335 ScrnInfoPtr pScrn = output->scrn; 336 337 if (ViaTVDACSense(pScrn)) 338 status = XF86OutputStatusConnected; 339 return status; 340} 341 342static DisplayModePtr 343via_tv_get_modes(xf86OutputPtr output) 344{ 345 DisplayModePtr modes = NULL, mode = NULL; 346 ScrnInfoPtr pScrn = output->scrn; 347 VIAPtr pVia = VIAPTR(pScrn); 348 int i; 349 350 for (i = 0; i < pVia->pBIOSInfo->TVNumModes; i++) { 351 mode = xf86DuplicateMode(&pVia->pBIOSInfo->TVModes[i]); 352 modes = xf86ModesAdd(modes, mode); 353 } 354 return modes; 355} 356 357static void 358via_tv_destroy(xf86OutputPtr output) 359{ 360} 361 362static const xf86OutputFuncsRec via_tv_funcs = { 363 .create_resources = via_tv_create_resources, 364#ifdef RANDR_12_INTERFACE 365 .set_property = via_tv_set_property, 366#endif 367#ifdef RANDR_13_INTERFACE 368 .get_property = via_tv_get_property, 369#endif 370 .dpms = via_tv_dpms, 371 .save = via_tv_save, 372 .restore = via_tv_restore, 373 .mode_valid = via_tv_mode_valid, 374 .mode_fixup = via_tv_mode_fixup, 375 .prepare = via_tv_prepare, 376 .commit = via_tv_commit, 377 .mode_set = via_tv_mode_set, 378 .detect = via_tv_detect, 379 .get_modes = via_tv_get_modes, 380 .destroy = via_tv_destroy, 381}; 382 383/* 384 * 385 */ 386static Bool 387via_tv_init(ScrnInfoPtr pScrn) 388{ 389 VIAPtr pVia = VIAPTR(pScrn); 390 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 391 xf86OutputPtr output = NULL; 392 393 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 394 "Entered via_tv_init.\n")); 395 396 /* preset some pBIOSInfo TV related values -- move up */ 397 pBIOSInfo->TVEncoder = VIA_NONETV; 398 pBIOSInfo->TVI2CDev = NULL; 399 pBIOSInfo->TVSave = NULL; 400 pBIOSInfo->TVRestore = NULL; 401 pBIOSInfo->TVDACSense = NULL; 402 pBIOSInfo->TVModeValid = NULL; 403 pBIOSInfo->TVModeI2C = NULL; 404 pBIOSInfo->TVModeCrtc = NULL; 405 pBIOSInfo->TVPower = NULL; 406 pBIOSInfo->TVModes = NULL; 407 pBIOSInfo->TVPrintRegs = NULL; 408 pBIOSInfo->LCDPower = NULL; 409 pBIOSInfo->TVNumRegs = 0; 410 411 /* 412 * On an SK43G (KM400/Ch7011), false positive detections at a VT162x 413 * chip were observed, so try to detect the Ch7011 first. 414 */ 415 if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0xEC)) 416 pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus2, 0xEC); 417 else if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0x40)) 418 pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus2, 0x40); 419 else if (pVia->pI2CBus3 && xf86I2CProbeAddress(pVia->pI2CBus3, 0x40)) 420 pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus3, 0x40); 421 else if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0xEA)) 422 pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus2, 0xEA); 423 else if (pVia->pI2CBus3 && xf86I2CProbeAddress(pVia->pI2CBus3, 0xEA)) 424 pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus3, 0xEA); 425 426 if (!pBIOSInfo->TVI2CDev) { 427 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 428 "Did not detect a TV encoder.\n"); 429 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 430 "Exiting via_tv_init.\n")); 431 432 return FALSE; 433 } 434 435 switch (pBIOSInfo->TVEncoder) { 436 case VIA_VT1621: 437 case VIA_VT1622: 438 case VIA_VT1623: 439 case VIA_VT1625: 440 ViaVT162xInit(pScrn); 441 break; 442 case VIA_CH7011: 443 case VIA_CH7019A: 444 case VIA_CH7019B: 445 ViaCH7xxxInit(pScrn); 446 break; 447 default: 448 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 449 "Was not able to initialize a known TV encoder.\n"); 450 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 451 "Exiting via_tv_init.\n")); 452 return FALSE; 453 break; 454 } 455 456 if (!pBIOSInfo->TVSave || !pBIOSInfo->TVRestore 457 || !pBIOSInfo->TVDACSense || !pBIOSInfo->TVModeValid 458 || !pBIOSInfo->TVModeI2C || !pBIOSInfo->TVModeCrtc 459 || !pBIOSInfo->TVPower || !pBIOSInfo->TVModes 460 || !pBIOSInfo->TVPrintRegs) { 461 462 xf86DestroyI2CDevRec(pBIOSInfo->TVI2CDev, TRUE); 463 464 pBIOSInfo->TVI2CDev = NULL; 465 pBIOSInfo->TVOutput = TVOUTPUT_NONE; 466 pBIOSInfo->TVEncoder = VIA_NONETV; 467 pBIOSInfo->TVI2CDev = NULL; 468 pBIOSInfo->TVSave = NULL; 469 pBIOSInfo->TVRestore = NULL; 470 pBIOSInfo->TVDACSense = NULL; 471 pBIOSInfo->TVModeValid = NULL; 472 pBIOSInfo->TVModeI2C = NULL; 473 pBIOSInfo->TVModeCrtc = NULL; 474 pBIOSInfo->TVPower = NULL; 475 pBIOSInfo->TVModes = NULL; 476 pBIOSInfo->TVPrintRegs = NULL; 477 pBIOSInfo->TVNumRegs = 0; 478 479 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 480 "TV encoder was not properly initialized.\n"); 481 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 482 "Exiting via_tv_init.\n")); 483 return FALSE; 484 } 485 486 output = xf86OutputCreate(pScrn, &via_tv_funcs, "TV-1"); 487 pVia->FirstInit = TRUE; 488 489 if (output) { 490 /* Allow tv output on both crtcs, set bit 0 and 1. */ 491 output->possible_crtcs = 0x3; 492 } else { 493 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 494 "Failed to register TV-1.\n"); 495 } 496 497 pBIOSInfo->tv = output; 498 /* Save now */ 499 pBIOSInfo->TVSave(pScrn); 500 501#ifdef HAVE_DEBUG 502 if (VIAPTR(pScrn)->PrintTVRegs) 503 pBIOSInfo->TVPrintRegs(pScrn); 504#endif 505 506 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 507 "Exiting via_tv_init.\n")); 508 return TRUE; 509} 510 511/* 512 * Enables CRT using DPMS registers. 513 */ 514static void 515ViaDisplayEnableCRT(ScrnInfoPtr pScrn) 516{ 517 vgaHWPtr hwp = VGAHWPTR(pScrn); 518 519 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayEnableCRT\n")); 520 ViaCrtcMask(hwp, 0x36, 0x00, 0x30); 521} 522 523/* 524 * Disables CRT using DPMS registers. 525 */ 526static void 527ViaDisplayDisableCRT(ScrnInfoPtr pScrn) 528{ 529 vgaHWPtr hwp = VGAHWPTR(pScrn); 530 531 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDisplayDisableCRT\n")); 532 ViaCrtcMask(hwp, 0x36, 0x30, 0x30); 533} 534 535static void 536via_analog_create_resources(xf86OutputPtr output) 537{ 538} 539 540#ifdef RANDR_12_INTERFACE 541static Bool 542via_analog_set_property(xf86OutputPtr output, Atom property, 543 RRPropertyValuePtr value) 544{ 545 return TRUE; 546} 547 548static Bool 549via_analog_get_property(xf86OutputPtr output, Atom property) 550{ 551 return FALSE; 552} 553#endif 554 555static void 556via_analog_dpms(xf86OutputPtr output, int mode) 557{ 558 ScrnInfoPtr pScrn = output->scrn; 559 560 switch (mode) { 561 case DPMSModeOn: 562 ViaDisplayEnableCRT(pScrn); 563 break; 564 565 case DPMSModeStandby: 566 case DPMSModeSuspend: 567 case DPMSModeOff: 568 ViaDisplayDisableCRT(pScrn); 569 break; 570 } 571} 572 573static void 574via_analog_save(xf86OutputPtr output) 575{ 576} 577 578static void 579via_analog_restore(xf86OutputPtr output) 580{ 581} 582 583static int 584via_analog_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) 585{ 586 ScrnInfoPtr pScrn = output->scrn; 587 588 if (!ViaModeDotClockTranslate(pScrn, pMode)) 589 return MODE_NOCLOCK; 590 return MODE_OK; 591} 592 593static Bool 594via_analog_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, 595 DisplayModePtr adjusted_mode) 596{ 597 return TRUE; 598} 599 600static void 601via_analog_prepare(xf86OutputPtr output) 602{ 603 via_analog_dpms(output, DPMSModeOff); 604} 605 606static void 607via_analog_commit(xf86OutputPtr output) 608{ 609 via_analog_dpms(output, DPMSModeOn); 610} 611 612static void 613via_analog_mode_set(xf86OutputPtr output, DisplayModePtr mode, 614 DisplayModePtr adjusted_mode) 615{ 616 ScrnInfoPtr pScrn = output->scrn; 617 618 if (output->crtc) { 619 drmmode_crtc_private_ptr iga = output->crtc->driver_private; 620 CARD8 value = 0x00; /* Value for IGA 1 */ 621 vgaHWPtr hwp = VGAHWPTR(pScrn); 622 623 /* IGA 2 */ 624 if (iga->index) 625 value = 0x40; 626 ViaSeqMask(hwp, 0x16, value, 0x40); 627 } 628 ViaDisplayEnableCRT(pScrn); 629} 630 631static xf86OutputStatus 632via_analog_detect(xf86OutputPtr output) 633{ 634 xf86OutputStatus status = XF86OutputStatusDisconnected; 635 ScrnInfoPtr pScrn = output->scrn; 636 VIAPtr pVia = VIAPTR(pScrn); 637 xf86MonPtr mon; 638 639 /* Probe I2C Bus 1 to see if a VGA monitor is connected. */ 640 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 641 "Probing for a VGA monitor on I2C Bus 1.\n"); 642 mon = xf86OutputGetEDID(output, pVia->pI2CBus1); 643 if (mon && (!mon->features.input_type)) { 644 xf86OutputSetEDID(output, mon); 645 status = XF86OutputStatusConnected; 646 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 647 "Detected a VGA monitor on I2C Bus 1.\n"); 648 } else { 649 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 650 "Did not detect a VGA monitor on I2C Bus 1.\n"); 651 652 /* Probe I2C Bus 2 to see if a VGA monitor is connected. */ 653 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 654 "Probing for a VGA monitor on I2C Bus 2.\n"); 655 mon = xf86OutputGetEDID(output, pVia->pI2CBus2); 656 if (mon && (!mon->features.input_type)) { 657 xf86OutputSetEDID(output, mon); 658 status = XF86OutputStatusConnected; 659 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 660 "Detected a VGA monitor on I2C Bus 2.\n"); 661 } else { 662 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 663 "Did not detect a VGA monitor on I2C Bus 2.\n"); 664 665 /* Perform manual detection of a VGA monitor since */ 666 /* it was not detected via I2C buses. */ 667 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 668 "Now perform manual detection of a VGA " 669 "monitor.\n"); 670 vgaHWPtr hwp = VGAHWPTR(pScrn); 671 CARD8 SR01 = hwp->readSeq(hwp, 0x01); 672 CARD8 SR40 = hwp->readSeq(hwp, 0x40); 673 CARD8 CR36 = hwp->readCrtc(hwp, 0x36); 674 675 /* We have to power on the display to detect it */ 676 ViaSeqMask(hwp, 0x01, 0x00, 0x20); 677 ViaCrtcMask(hwp, 0x36, 0x00, 0xF0); 678 679 /* Wait for vblank */ 680 usleep(16); 681 682 /* Detect the load on pins */ 683 ViaSeqMask(hwp, 0x40, 0x80, 0x80); 684 685 if ((VIA_CX700 == pVia->Chipset) || 686 (VIA_VX800 == pVia->Chipset) || 687 (VIA_VX855 == pVia->Chipset) || 688 (VIA_VX900 == pVia->Chipset)) 689 ViaSeqMask(hwp, 0x40, 0x00, 0x80); 690 691 if (ViaVgahwIn(hwp, 0x3C2) & 0x20) { 692 status = XF86OutputStatusConnected; 693 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 694 "Detected a VGA monitor using manual " 695 "detection method.\n"); 696 } 697 698 if ((VIA_CX700 == pVia->Chipset) || 699 (VIA_VX800 == pVia->Chipset) || 700 (VIA_VX855 == pVia->Chipset) || 701 (VIA_VX900 == pVia->Chipset)) 702 ViaSeqMask(hwp, 0x40, 0x00, 0x80); 703 704 /* Restore previous state */ 705 hwp->writeSeq(hwp, 0x40, SR40); 706 hwp->writeSeq(hwp, 0x01, SR01); 707 hwp->writeCrtc(hwp, 0x36, CR36); 708 } 709 } 710 711 return status; 712} 713 714static void 715via_analog_destroy(xf86OutputPtr output) 716{ 717} 718 719static const xf86OutputFuncsRec via_analog_funcs = { 720 .create_resources = via_analog_create_resources, 721#ifdef RANDR_12_INTERFACE 722 .set_property = via_analog_set_property, 723#endif 724#ifdef RANDR_13_INTERFACE 725 .get_property = via_analog_get_property, 726#endif 727 .dpms = via_analog_dpms, 728 .save = via_analog_save, 729 .restore = via_analog_restore, 730 .mode_valid = via_analog_mode_valid, 731 .mode_fixup = via_analog_mode_fixup, 732 .prepare = via_analog_prepare, 733 .commit = via_analog_commit, 734 .mode_set = via_analog_mode_set, 735 .detect = via_analog_detect, 736 .get_modes = xf86OutputGetEDIDModes, 737 .destroy = via_analog_destroy, 738}; 739 740void 741via_analog_init(ScrnInfoPtr pScrn) 742{ 743 VIAPtr pVia = VIAPTR(pScrn); 744 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 745 xf86OutputPtr output = NULL; 746 747 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 748 "Entered via_analog_init.\n")); 749 750 if (!pVia->pI2CBus1 || !pVia->pI2CBus2) { 751 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 752 "I2C Bus 1 or I2C Bus 2 does not exist.\n"); 753 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 754 "Exiting via_analog_init.\n")); 755 return; 756 } 757 758 output = xf86OutputCreate(pScrn, &via_analog_funcs, "VGA-1"); 759 760 output->possible_crtcs = 0x3; 761 output->possible_clones = 0; 762 output->interlaceAllowed = TRUE; 763 output->doubleScanAllowed = FALSE; 764 pBIOSInfo->analog = output; 765 766 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 767 "Exiting via_analog_init.\n")); 768} 769 770static void 771via_dvi_create_resources(xf86OutputPtr output) 772{ 773} 774 775#ifdef RANDR_12_INTERFACE 776static Bool 777via_dvi_set_property(xf86OutputPtr output, Atom property, 778 RRPropertyValuePtr value) 779{ 780 return TRUE; 781} 782 783static Bool 784via_dvi_get_property(xf86OutputPtr output, Atom property) 785{ 786 return FALSE; 787} 788#endif 789 790static void 791via_dvi_dpms(xf86OutputPtr output, int mode) 792{ 793 ScrnInfoPtr pScrn = output->scrn; 794 795 switch (mode) { 796 case DPMSModeOn: 797 ViaDFPPower(pScrn, TRUE); 798 break; 799 800 case DPMSModeStandby: 801 case DPMSModeSuspend: 802 case DPMSModeOff: 803 ViaDFPPower(pScrn, FALSE); 804 break; 805 } 806 807} 808 809static void 810via_dvi_save(xf86OutputPtr output) 811{ 812 via_vt1632_save(output); 813} 814 815static void 816via_dvi_restore(xf86OutputPtr output) 817{ 818 via_vt1632_restore(output); 819} 820 821static int 822via_dvi_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) 823{ 824 return via_vt1632_mode_valid(output, pMode); 825} 826 827static Bool 828via_dvi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, 829 DisplayModePtr adjusted_mode) 830{ 831 return TRUE; 832} 833 834static void 835via_dvi_prepare(xf86OutputPtr output) 836{ 837} 838 839static void 840via_dvi_commit(xf86OutputPtr output) 841{ 842} 843 844static void 845via_dvi_mode_set(xf86OutputPtr output, DisplayModePtr mode, 846 DisplayModePtr adjusted_mode) 847{ 848 ScrnInfoPtr pScrn = output->scrn; 849 vgaHWPtr hwp = VGAHWPTR(pScrn); 850 851 via_vt1632_power(output, FALSE); 852 ViaModeSecondCRTC(pScrn, mode); 853 via_vt1632_mode_set(output, mode, adjusted_mode); 854 via_vt1632_power(output, TRUE); 855} 856 857static xf86OutputStatus 858via_dvi_detect(xf86OutputPtr output) 859{ 860 xf86OutputStatus status = XF86OutputStatusDisconnected; 861 ScrnInfoPtr pScrn = output->scrn; 862 VIAPtr pVia = VIAPTR(pScrn); 863 xf86MonPtr mon; 864 865 mon = xf86OutputGetEDID(output, pVia->pI2CBus2); 866 if (mon && DIGITAL(mon->features.input_type)) { 867 xf86OutputSetEDID(output, mon); 868 status = XF86OutputStatusConnected; 869 } else { 870 status = via_vt1632_detect(output); 871 } 872 return status; 873} 874 875static void 876via_dvi_destroy(xf86OutputPtr output) 877{ 878} 879 880static const xf86OutputFuncsRec via_dvi_funcs = { 881 .create_resources = via_dvi_create_resources, 882#ifdef RANDR_12_INTERFACE 883 .set_property = via_dvi_set_property, 884#endif 885#ifdef RANDR_13_INTERFACE 886 .get_property = via_dvi_get_property, 887#endif 888 .dpms = via_dvi_dpms, 889 .save = via_dvi_save, 890 .restore = via_dvi_restore, 891 .mode_valid = via_dvi_mode_valid, 892 .mode_fixup = via_dvi_mode_fixup, 893 .prepare = via_dvi_prepare, 894 .commit = via_dvi_commit, 895 .mode_set = via_dvi_mode_set, 896 .detect = via_dvi_detect, 897 .get_modes = xf86OutputGetEDIDModes, 898 .destroy = via_dvi_destroy, 899}; 900 901void 902via_dvi_init(ScrnInfoPtr pScrn) 903{ 904 VIAPtr pVia = VIAPTR(pScrn); 905 xf86OutputPtr output = NULL; 906 struct ViaVT1632PrivateData *private_data = NULL; 907 I2CBusPtr pBus = NULL; 908 I2CDevPtr pDev = NULL; 909 I2CSlaveAddr addr = 0x10; 910 911 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 912 "Entered via_dvi_init.\n")); 913 914 if (!pVia->pI2CBus2 || !pVia->pI2CBus3) { 915 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 916 "I2C Bus 2 or I2C Bus 3 does not exist.\n"); 917 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 918 "Exiting via_dvi_init.\n")); 919 return; 920 } 921 922 if (xf86I2CProbeAddress(pVia->pI2CBus3, addr)) { 923 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 924 "Will probe I2C Bus 3 for a possible " 925 "external TMDS transmitter.\n")); 926 pBus = pVia->pI2CBus3; 927 } else if (xf86I2CProbeAddress(pVia->pI2CBus2, addr)) { 928 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 929 "Will probe I2C Bus 2 for a possible " 930 "external TMDS transmitter.\n")); 931 pBus = pVia->pI2CBus2; 932 } else { 933 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 934 "Did not find a possible external TMDS transmitter " 935 "on I2C Bus 2 or I2C Bus 3.\n"); 936 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 937 "Exiting via_dvi_init.\n")); 938 return; 939 } 940 941 pDev = xf86CreateI2CDevRec(); 942 if (!pDev) { 943 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 944 "Failed to create an I2C bus structure.\n"); 945 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 946 "Exiting via_dvi_init.\n")); 947 return; 948 } 949 950 pDev->DevName = "VT1632A"; 951 pDev->SlaveAddr = addr; 952 pDev->pI2CBus = pBus; 953 if (!xf86I2CDevInit(pDev)) { 954 xf86DestroyI2CDevRec(pDev, TRUE); 955 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 956 "Failed to initialize a device on I2C bus.\n"); 957 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 958 "Exiting via_dvi_init.\n")); 959 return; 960 } 961 962 if (!via_vt1632_probe(pScrn, pDev)) { 963 xf86DestroyI2CDevRec(pDev, TRUE); 964 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 965 "Exiting via_dvi_init.\n")); 966 return; 967 } 968 969 private_data = via_vt1632_init(pScrn, pDev); 970 if (!private_data) { 971 xf86DestroyI2CDevRec(pDev, TRUE); 972 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 973 "Exiting via_dvi_init.\n")); 974 return; 975 } 976 977 output = xf86OutputCreate(pScrn, &via_dvi_funcs, "DVI-1"); 978 if (output) { 979 output->driver_private = private_data; 980 output->possible_crtcs = 0x2; 981 output->possible_clones = 0; 982 output->interlaceAllowed = FALSE; 983 output->doubleScanAllowed = FALSE; 984 } 985 986 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 987 "Exiting via_dvi_init.\n")); 988} 989 990void 991ViaOutputsDetect(ScrnInfoPtr pScrn) 992{ 993 VIAPtr pVia = VIAPTR(pScrn); 994 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 995 996 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 997 "Entered ViaOutputsDetect.\n")); 998 999 pBIOSInfo->analog = NULL; 1000 1001 /* LVDS */ 1002 via_lvds_init(pScrn); 1003 1004 /* VGA */ 1005 via_analog_init(pScrn); 1006 1007 /* TV */ 1008 via_tv_init(pScrn); 1009 1010 /* 1011 * via_dvi_init function to initialize VT1632A TMDS transmitter 1012 * is disabled for now. 1013 */ 1014 /* External TMDS Transmitter (DVI) */ 1015/* 1016 via_dvi_init(pScrn); 1017*/ 1018 1019 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1020 "Exiting ViaOutputsDetect.\n")); 1021} 1022 1023#ifdef HAVE_DEBUG 1024/* 1025 * Returns: 1026 * Bit[7] 2nd Path 1027 * Bit[6] 1/0 MHS Enable/Disable 1028 * Bit[5] 0 = Bypass Callback, 1 = Enable Callback 1029 * Bit[4] 0 = Hot-Key Sequence Control (OEM Specific) 1030 * Bit[3] LCD 1031 * Bit[2] TV 1032 * Bit[1] CRT 1033 * Bit[0] DVI 1034 */ 1035static CARD8 1036VIAGetActiveDisplay(ScrnInfoPtr pScrn) 1037{ 1038 vgaHWPtr hwp = VGAHWPTR(pScrn); 1039 CARD8 tmp; 1040 1041 tmp = (hwp->readCrtc(hwp, 0x3E) >> 4); 1042 tmp |= ((hwp->readCrtc(hwp, 0x3B) & 0x18) << 3); 1043 1044 return tmp; 1045} 1046#endif /* HAVE_DEBUG */ 1047 1048/* 1049 * 1050 */ 1051CARD32 1052ViaGetMemoryBandwidth(ScrnInfoPtr pScrn) 1053{ 1054 VIAPtr pVia = VIAPTR(pScrn); 1055 1056 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1057 "ViaGetMemoryBandwidth. Memory type: %d\n", 1058 pVia->MemClk)); 1059 1060 switch (pVia->MemClk) { 1061 case VIA_MEM_SDR66: 1062 case VIA_MEM_SDR100: 1063 case VIA_MEM_SDR133: 1064 return VIA_BW_MIN; 1065 case VIA_MEM_DDR200: 1066 return VIA_BW_DDR200; 1067 case VIA_MEM_DDR266: 1068 case VIA_MEM_DDR333: 1069 case VIA_MEM_DDR400: 1070 return VIA_BW_DDR400; 1071 case VIA_MEM_DDR533: 1072 case VIA_MEM_DDR667: 1073 return VIA_BW_DDR667; 1074 case VIA_MEM_DDR800: 1075 case VIA_MEM_DDR1066: 1076 return VIA_BW_DDR1066; 1077 default: 1078 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1079 "ViaBandwidthAllowed: Unknown memory type: %d\n", 1080 pVia->MemClk); 1081 return VIA_BW_MIN; 1082 } 1083} 1084 1085/* 1086 * 1087 * Some very common abstractions. 1088 * 1089 */ 1090 1091/* 1092 * Standard vga call really. 1093 * Needs to be called to reset the dotclock (after SR40:2/1 reset) 1094 */ 1095void 1096ViaSetUseExternalClock(vgaHWPtr hwp) 1097{ 1098 CARD8 data; 1099 1100 DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, 1101 "ViaSetUseExternalClock\n")); 1102 1103 data = hwp->readMiscOut(hwp); 1104 hwp->writeMiscOut(hwp, data | 0x0C); 1105} 1106 1107/* 1108 * 1109 */ 1110static void 1111ViaSetDotclock(ScrnInfoPtr pScrn, CARD32 clock, int base, int probase) 1112{ 1113 vgaHWPtr hwp = VGAHWPTR(pScrn); 1114 VIAPtr pVia = VIAPTR(pScrn); 1115 1116 DEBUG(xf86DrvMsg(hwp->pScrn->scrnIndex, X_INFO, 1117 "ViaSetDotclock to 0x%06x\n", (unsigned)clock)); 1118 1119 if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) { 1120 hwp->writeSeq(hwp, base, clock >> 8); 1121 hwp->writeSeq(hwp, base+1, clock & 0xFF); 1122 } else { /* unichrome pro */ 1123 union pllparams pll; 1124 int dtz, dr, dn, dm; 1125 pll.packed = clock; 1126 dtz = pll.params.dtz; 1127 dr = pll.params.dr; 1128 dn = pll.params.dn; 1129 dm = pll.params.dm; 1130 1131 /* The VX855 and VX900 do not modify dm/dn, but earlier chipsets do. */ 1132 if ((pVia->Chipset != VIA_VX855) && (pVia->Chipset != VIA_VX900)) { 1133 dm -= 2; 1134 dn -= 2; 1135 } 1136 1137 hwp->writeSeq(hwp, probase, dm & 0xff); 1138 hwp->writeSeq(hwp, probase+1, 1139 ((dm >> 8) & 0x03) | (dr << 2) | ((dtz & 1) << 7)); 1140 hwp->writeSeq(hwp, probase+2, (dn & 0x7f) | ((dtz & 2) << 6)); 1141 } 1142} 1143 1144/* 1145 * 1146 */ 1147static void 1148ViaSetPrimaryDotclock(ScrnInfoPtr pScrn, CARD32 clock) 1149{ 1150 vgaHWPtr hwp = VGAHWPTR(pScrn); 1151 1152 ViaSetDotclock(pScrn, clock, 0x46, 0x44); 1153 1154 ViaSeqMask(hwp, 0x40, 0x02, 0x02); 1155 ViaSeqMask(hwp, 0x40, 0x00, 0x02); 1156} 1157 1158/* 1159 * 1160 */ 1161void 1162ViaSetSecondaryDotclock(ScrnInfoPtr pScrn, CARD32 clock) 1163{ 1164 vgaHWPtr hwp = VGAHWPTR(pScrn); 1165 1166 ViaSetDotclock(pScrn, clock, 0x44, 0x4A); 1167 1168 ViaSeqMask(hwp, 0x40, 0x04, 0x04); 1169 ViaSeqMask(hwp, 0x40, 0x00, 0x04); 1170} 1171 1172/* 1173 * 1174 */ 1175static void 1176ViaSetECKDotclock(ScrnInfoPtr pScrn, CARD32 clock) 1177{ 1178 /* Does the non-pro chip have an ECK clock ? */ 1179 ViaSetDotclock(pScrn, clock, 0, 0x47); 1180} 1181 1182static CARD32 1183ViaComputeDotClock(unsigned clock) 1184{ 1185 double fout, fref, err, minErr; 1186 CARD32 dr, dn, dm, maxdm, maxdn; 1187 CARD32 factual, best; 1188 1189 fref = 14.31818e6; 1190 fout = (double)clock * 1.e3; 1191 1192 factual = ~0; 1193 maxdm = 127; 1194 maxdn = 7; 1195 minErr = 1e10; 1196 best = 0; 1197 1198 for (dr = 0; dr < 4; ++dr) { 1199 for (dn = (dr == 0) ? 2 : 1; dn <= maxdn; ++dn) { 1200 for (dm = 1; dm <= maxdm; ++dm) { 1201 factual = fref * dm; 1202 factual /= (dn << dr); 1203 err = fabs((double)factual / fout - 1.); 1204 if (err < minErr) { 1205 minErr = err; 1206 best = (dm & 127) | ((dn & 31) << 8) | (dr << 14); 1207 } 1208 } 1209 } 1210 } 1211 return best; 1212} 1213 1214static CARD32 1215ViaComputeProDotClock(unsigned clock) 1216{ 1217 double fvco, fout, fref, err, minErr; 1218 CARD32 dr = 0, dn, dm, maxdm, maxdn; 1219 CARD32 factual; 1220 union pllparams bestClock; 1221 1222 fref = 14.318e6; 1223 fout = (double)clock * 1.e3; 1224 1225 factual = ~0; 1226 maxdm = factual / 14318000U; 1227 minErr = 1.e10; 1228 bestClock.packed = 0U; 1229 1230 do { 1231 fvco = fout * (1 << dr); 1232 } while (fvco < 300.e6 && dr++ < 8); 1233 1234 if (dr == 8) { 1235 return 0; 1236 } 1237 1238 if (clock < 30000) 1239 maxdn = 8; 1240 else if (clock < 45000) 1241 maxdn = 7; 1242 else if (clock < 170000) 1243 maxdn = 6; 1244 else 1245 maxdn = 5; 1246 1247 for (dn = 2; dn < maxdn; ++dn) { 1248 for (dm = 2; dm < maxdm; ++dm) { 1249 factual = 14318000U * dm; 1250 factual /= dn << dr; 1251 if ((err = fabs((double)factual / fout - 1.)) < 0.005) { 1252 if (err < minErr) { 1253 minErr = err; 1254 bestClock.params.dtz = 1; 1255 bestClock.params.dr = dr; 1256 bestClock.params.dn = dn; 1257 bestClock.params.dm = dm; 1258 } 1259 } 1260 } 1261 } 1262 1263 return bestClock.packed; 1264} 1265 1266/* 1267 * 1268 */ 1269CARD32 1270ViaModeDotClockTranslate(ScrnInfoPtr pScrn, DisplayModePtr mode) 1271{ 1272 VIAPtr pVia = VIAPTR(pScrn); 1273 int i; 1274 1275 if ((pVia->Chipset == VIA_CLE266) || (pVia->Chipset == VIA_KM400)) { 1276 CARD32 best1 = 0, best2; 1277 1278 for (i = 0; ViaDotClocks[i].DotClock; i++) 1279 if (ViaDotClocks[i].DotClock == mode->Clock) { 1280 best1 = ViaDotClocks[i].UniChrome; 1281 break; 1282 } 1283 1284 best2 = ViaComputeDotClock(mode->Clock); 1285 1286 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1287 "ViaComputeDotClock %d : %04x : %04x\n", 1288 mode->Clock, (unsigned int)best1, 1289 (unsigned int)best2)); 1290 1291 return best2; 1292 } else { 1293 for (i = 0; ViaDotClocks[i].DotClock; i++) 1294 if (ViaDotClocks[i].DotClock == mode->Clock) 1295 return ViaDotClocks[i].UniChromePro.packed; 1296 return ViaComputeProDotClock(mode->Clock); 1297 } 1298 1299 return 0; 1300} 1301 1302void 1303ViaDFPPower(ScrnInfoPtr pScrn, Bool On) 1304{ 1305#ifdef HAVE_DEBUG 1306 if (On) 1307 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDFPPower: On.\n"); 1308 else 1309 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaDFPPower: Off.\n"); 1310#endif 1311 vgaHWPtr hwp = VGAHWPTR(pScrn); 1312 1313 /* Display Channel Select */ 1314 ViaCrtcMask(hwp, 0xD2, 0x30, 0x30); 1315 1316 if (On) 1317 /* Power on TMDS */ 1318 ViaCrtcMask(hwp, 0xD2, 0x00, 0x08); 1319 else 1320 /* Power off TMDS */ 1321 ViaCrtcMask(hwp, 0xD2, 0x08, 0x08); 1322} 1323 1324void 1325ViaModeFirstCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode) 1326{ 1327 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeFirstCRTC\n"); 1328 vgaHWPtr hwp = VGAHWPTR(pScrn); 1329 VIAPtr pVia = VIAPTR(pScrn); 1330 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 1331 1332 /* Turn off Screen */ 1333 ViaCrtcMask(hwp, 0x17, 0x00, 0x80); 1334 1335 ViaFirstCRTCSetMode(pScrn, mode); 1336 pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, mode); 1337 pBIOSInfo->ClockExternal = FALSE; 1338 1339 /* Enable Extended Mode Memory Access. */ 1340 ViaSeqMask(hwp, 0x1A, 0x08, 0x08); 1341 1342 ViaSetPrimaryFIFO(pScrn, mode); 1343 1344 ViaSetPrimaryDotclock(pScrn, pBIOSInfo->Clock); 1345 ViaSetUseExternalClock(hwp); 1346 ViaCrtcMask(hwp, 0x6B, 0x00, 0x01); 1347 1348 hwp->disablePalette(hwp); 1349 1350 /* Turn on Screen */ 1351 ViaCrtcMask(hwp, 0x17, 0x80, 0x80); 1352} 1353 1354void 1355ViaModeSecondCRTC(ScrnInfoPtr pScrn, DisplayModePtr mode) 1356{ 1357 VIAPtr pVia = VIAPTR(pScrn); 1358 VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; 1359 vgaHWPtr hwp = VGAHWPTR(pScrn); 1360 DisplayModePtr realMode = mode; 1361 1362 DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaModeSecondCRTC\n")); 1363 1364 ViaSecondCRTCSetMode(pScrn, realMode); 1365 ViaSetSecondaryFIFO(pScrn, realMode); 1366 pBIOSInfo->Clock = ViaModeDotClockTranslate(pScrn, realMode); 1367 1368 /* Fix LCD scaling */ 1369 ViaSecondCRTCHorizontalQWCount(pScrn, mode->CrtcHDisplay); 1370 1371 pBIOSInfo->ClockExternal = FALSE; 1372 ViaSetSecondaryDotclock(pScrn, pBIOSInfo->Clock); 1373 ViaSetUseExternalClock(hwp); 1374 1375 hwp->disablePalette(hwp); 1376} 1377 1378