xgi_driver.c revision ce2d3770
1/* 2 * XGI driver main code 3 * 4 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1) Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2) Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3) The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Author: Thomas Winischhofer <thomas@winischhofer.net> 29 * - driver entirely rewritten since 2001, only basic structure taken from 30 * old code (except xgi_dri.c, xgi_shadow.c, xgi_accel.c and parts of 31 * xgi_dga.c; these were mostly taken over; xgi_dri.c was changed for 32 * new versions of the DRI layer) 33 * 34 * This notice covers the entire driver code unless otherwise indicated. 35 * 36 * Formerly based on code which is 37 * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England. 38 * Written by: 39 * Alan Hourihane <alanh@fairlite.demon.co.uk>, 40 * Mike Chapman <mike@paranoia.com>, 41 * Juanjo Santamarta <santamarta@ctv.es>, 42 * Mitani Hiroshi <hmitani@drl.mei.co.jp>, 43 * David Thomas <davtom@dream.org.uk>. 44 */ 45 46#ifdef HAVE_CONFIG_H 47#include "config.h" 48#endif 49 50#define PACKAGE_VERSION_MAJOR 1 51#define PACKAGE_VERSION_MINOR 6 52#define PACKAGE_VERSION_PATCHLEVEL 0 53 54#include "fb.h" 55#include "micmap.h" 56#include "xf86.h" 57#include "xf86Priv.h" 58#include "xf86_OSproc.h" 59#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 60#include "xf86Resources.h" 61#include "xf86RAC.h" 62#endif 63#include "dixstruct.h" 64#include "xorgVersion.h" 65#include "xf86PciInfo.h" 66#include "xf86Pci.h" 67#include "xf86cmap.h" 68#include "vgaHW.h" 69#include "shadowfb.h" 70#include "vbe.h" 71 72#include "mipointer.h" 73 74#include "xgi.h" 75#include "xgi_regs.h" 76#include "xgi_vb.h" 77#include "xgi_dac.h" 78#include "vb_def.h" 79#include "vb_ext.h" 80#include "vb_i2c.h" 81#include "vb_setmode.h" 82#include "xgi_driver.h" 83#include "xgi_accel.h" 84#include "valid_mode.h" 85 86#define _XF86DGA_SERVER_ 87#include <X11/extensions/xf86dgaproto.h> 88 89#include "globals.h" 90 91#ifdef HAVE_XEXTPROTO_71 92#include <X11/extensions/dpmsconst.h> 93#else 94#define DPMS_SERVER 95#include <X11/extensions/dpms.h> 96#endif 97 98 99#if defined(XvExtension) 100#include "xf86xv.h" 101#include <X11/extensions/Xv.h> 102#endif 103 104#ifdef XF86DRI 105#include "dri.h" 106#endif 107 108#ifdef HAVE_UNISTD_H 109#include <unistd.h> 110#endif 111 112#include <fcntl.h> 113#include <sys/ioctl.h> 114 115#ifdef XSERVER_LIBPCIACCESS 116static Bool XGIPciProbe(DriverPtr drv, int entity_num, 117 struct pci_device *dev, intptr_t match_data); 118#else 119static Bool XGIProbe(DriverPtr drv, int flags); 120#endif 121 122void Volari_EnableAccelerator(ScrnInfoPtr pScrn); 123/* Globals (yes, these ARE really required to be global) */ 124 125#ifdef XGIDUALHEAD 126static int XGIEntityIndex = -1; 127#endif 128 129/* Jong 09/19/2007; support modeline */ 130int g_CountOfUserDefinedModes=0; 131xf86MonPtr g_pMonitorDVI=NULL; /* Jong 12/04/2007; used for filtering of CRT1 modes */ 132 133/* Jong 07/27/2009; use run-time debug instead except for HW acceleration routines */ 134/* Set Option "RunTimeDebug" to "true" in X configuration file */ 135Bool g_bRunTimeDebug=0; 136 137/* Jong@09072009 */ 138unsigned char g_DVI_I_SignalType = 0x00; 139 140/* 141 * This is intentionally screen-independent. It indicates the binding 142 * choice made in the first PreInit. 143 */ 144static int pix24bpp = 0; 145int FbDevExist; 146 147#define FBIOGET_FSCREENINFO 0x4602 148#define FB_ACCEL_XGI_GLAMOUR 41 149 150struct fb_fix_screeninfo 151{ 152 char id[16]; /* identification string eg "TT Builtin" */ 153 unsigned long smem_start; /* Start of frame buffer mem */ 154 /* (physical address) */ 155 unsigned long smem_len; /* Length of frame buffer mem */ 156 unsigned long type; /* see FB_TYPE_* */ 157 unsigned long type_aux; /* Interleave for interleaved Planes */ 158 unsigned long visual; /* see FB_VISUAL_* */ 159 unsigned short xpanstep; /* zero if no hardware panning */ 160 unsigned short ypanstep; /* zero if no hardware panning */ 161 unsigned short ywrapstep; /* zero if no hardware ywrap */ 162 unsigned long line_length; /* length of a line in bytes */ 163 unsigned long mmio_start; /* Start of Memory Mapped I/O */ 164 /* (physical address) */ 165 unsigned long mmio_len; /* Length of Memory Mapped I/O */ 166 unsigned long accel; /* Type of acceleration available */ 167 unsigned short reserved[3]; /* Reserved for future compatibility */ 168}; 169 170#ifdef XSERVER_LIBPCIACCESS 171#define XGI_DEVICE_MATCH(d, i) \ 172 { 0x18ca, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) } 173 174static const struct pci_id_match xgi_device_match[] = { 175 XGI_DEVICE_MATCH(PCI_CHIP_XGIXG40, 0), 176 XGI_DEVICE_MATCH(PCI_CHIP_XGIXG20, 1), 177 XGI_DEVICE_MATCH(PCI_CHIP_XGIXG21, 2), 178 XGI_DEVICE_MATCH(PCI_CHIP_XGIXG27, 3), 179 { 0, 0, 0 }, 180}; 181#endif 182 183/* 184 * This contains the functions needed by the server after loading the driver 185 * module. It must be supplied, and gets passed back by the SetupProc 186 * function in the dynamic case. In the static case, a reference to this 187 * is compiled in, and this requires that the name of this DriverRec be 188 * an upper-case version of the driver name. 189 */ 190 191DriverRec XGI = { 192 XGI_CURRENT_VERSION, 193 XGI_DRIVER_NAME, 194 XGIIdentify, 195#ifdef XSERVER_LIBPCIACCESS 196 NULL, 197#else 198 XGIProbe, 199#endif 200 XGIAvailableOptions, 201 NULL, 202 0, 203 NULL, 204 205#ifdef XSERVER_LIBPCIACCESS 206 xgi_device_match, 207 XGIPciProbe 208#endif 209}; 210 211static SymTabRec XGIChipsets[] = { 212 {PCI_CHIP_XGIXG40, "Volari V8_V5_V3XT"}, 213 {PCI_CHIP_XGIXG20, "Volari Z7_Z9_Z9s"}, 214 {PCI_CHIP_XGIXG21, "Volari Z9_Z9s"}, 215 {PCI_CHIP_XGIXG27, "Volari Z11"}, 216 {-1, NULL} 217}; 218 219static PciChipsets XGIPciChipsets[] = { 220 {PCI_CHIP_XGIXG40, PCI_CHIP_XGIXG40, RES_SHARED_VGA}, 221 {PCI_CHIP_XGIXG20, PCI_CHIP_XGIXG20, RES_SHARED_VGA}, 222 {PCI_CHIP_XGIXG21, PCI_CHIP_XGIXG21, RES_SHARED_VGA }, 223 {PCI_CHIP_XGIXG27, PCI_CHIP_XGIXG27, RES_SHARED_VGA }, 224 {-1, -1, RES_UNDEFINED} 225}; 226 227static const char *xaaSymbols[] = { 228 "XAACopyROP", 229 "XAACreateInfoRec", 230 "XAADestroyInfoRec", 231 "XAAFillMono8x8PatternRects", 232 "XAAPatternROP", 233 "XAAHelpPatternROP", 234 "XAAInit", 235 NULL 236}; 237 238#ifdef XGI_USE_EXA 239static const char *exaSymbols[] = { 240 "exaGetVersion", 241 "exaDriverInit", 242 "exaDriverFini", 243 "exaOffscreenAlloc", 244 "exaOffscreenFree", 245 NULL 246}; 247#endif 248 249static const char *vgahwSymbols[] = { 250 "vgaHWFreeHWRec", 251 "vgaHWGetHWRec", 252 "vgaHWGetIOBase", 253 "vgaHWGetIndex", 254 "vgaHWInit", 255 "vgaHWLock", 256 "vgaHWMapMem", 257 "vgaHWUnmapMem", 258 "vgaHWProtect", 259 "vgaHWRestore", 260 "vgaHWSave", 261 "vgaHWSaveScreen", 262 "vgaHWUnlock", 263 NULL 264}; 265 266static const char *fbSymbols[] = { 267 "fbPictureInit", 268 "fbScreenInit", 269 NULL 270}; 271 272static const char *shadowSymbols[] = { 273 "ShadowFBInit", 274 NULL 275}; 276 277static const char *ramdacSymbols[] = { 278 "xf86CreateCursorInfoRec", 279 "xf86DestroyCursorInfoRec", 280 "xf86InitCursor", 281 NULL 282}; 283 284 285static const char *ddcSymbols[] = { 286 "xf86PrintEDID", 287 "xf86SetDDCproperties", 288 "xf86InterpretEDID", 289 NULL 290}; 291 292 293/* static const char *i2cSymbols[] = { 294 "xf86I2CBusInit", 295 "xf86CreateI2CBusRec", 296 NULL 297}; */ 298 299static const char *int10Symbols[] = { 300 "xf86FreeInt10", 301 "xf86InitInt10", 302 "xf86ExecX86int10", 303 NULL 304}; 305 306static const char *vbeSymbols[] = { 307 "VBEExtendedInit", 308 "vbeDoEDID", 309 "vbeFree", 310 "VBEGetVBEInfo", 311 "VBEFreeVBEInfo", 312 "VBEGetModeInfo", 313 "VBEFreeModeInfo", 314 "VBESaveRestore", 315 "VBESetVBEMode", 316 "VBEGetVBEMode", 317 "VBESetDisplayStart", 318 "VBESetGetLogicalScanlineLength", 319 NULL 320}; 321 322#ifdef XF86DRI 323static const char *drmSymbols[] = { 324 "drmAddMap", 325 "drmAgpAcquire", 326 "drmAgpAlloc", 327 "drmAgpBase", 328 "drmAgpBind", 329 "drmAgpEnable", 330 "drmAgpFree", 331 "drmAgpGetMode", 332 "drmAgpRelease", 333 "drmCtlInstHandler", 334 "drmGetInterruptFromBusID", 335 "drmXGIAgpInit", 336 NULL 337}; 338 339static const char *driSymbols[] = { 340 "DRICloseScreen", 341 "DRICreateInfoRec", 342 "DRIDestroyInfoRec", 343 "DRIFinishScreenInit", 344 "DRIGetSAREAPrivate", 345 "DRILock", 346 "DRIQueryVersion", 347 "DRIScreenInit", 348 "DRIUnlock", 349#ifdef XGINEWDRI2 350 "GlxSetVisualConfigs", 351 "DRICreatePCIBusID", 352#endif 353 NULL 354}; 355#endif 356 357static MODULESETUPPROTO(xgiSetup); 358 359static XF86ModuleVersionInfo xgiVersRec = { 360 XGI_DRIVER_NAME, 361 MODULEVENDORSTRING, 362 MODINFOSTRING1, 363 MODINFOSTRING2, 364#ifdef XORG_VERSION_CURRENT 365 XORG_VERSION_CURRENT, 366#else 367 XF86_VERSION_CURRENT, 368#endif 369 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, 370 ABI_CLASS_VIDEODRV, /* This is a video driver */ 371#ifdef ABI_VIDEODRV_VERSION 372 ABI_VIDEODRV_VERSION, 373#else 374 6, 375#endif 376 MOD_CLASS_VIDEODRV, 377 {0, 0, 0, 0} 378}; 379 380XF86ModuleData xgiModuleData = { &xgiVersRec, xgiSetup, NULL }; 381 382/*** static string ***/ 383#ifdef XGIMERGED 384static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n"; 385static const char *mergednocrt2 = 386 "No CRT2 output selected or no bridge detected. %s.\n"; 387static const char *mergeddisstr = "MergedFB mode disabled"; 388static const char *modesforstr = 389 "Modes for CRT%d: *********************************************\n"; 390static const char *crtsetupstr = 391 "------------------------ CRT%d setup -------------------------\n"; 392#endif 393 394typedef struct 395{ 396 int width, height; 397 float VRefresh, HSync, DCLK; 398} ModeTiming; 399 400static const ModeTiming establish_timing[] = { 401 {800, 600, 60, 37.9, 40}, /* t1 D[0] */ 402 {800, 600, 56, 35.1, 36}, /* t1 D[1] */ 403 {640, 480, 75, 37.5, 31.5}, /* t1 D[2] */ 404 {640, 480, 72, 37.9, 31.5}, /* t1 D[3] */ 405 {-1, -1, -1, -1}, /* t1 D[4] 640x480@67Hz, ignore */ 406 {640, 480, 60, 31.5, 25.175}, /* t1 D[5] */ 407 {-1, -1, -1, -1}, /* t1 D[6] */ 408 {-1, -1, -1, -1}, /* t1 D[7] */ 409 {1280, 1024, 75, 80.0, 135}, /* t2 D[0] */ 410 {1024, 768, 75, 60.0, 78.75}, /* t2 D[1] */ 411 {1024, 768, 70, 56.5, 75}, /* t2 D[2] */ 412 {1024, 768, 60, 48.4, 65}, /* t2 D[3] */ 413 {-1, -1, -1, -1}, /* t2 D[4] 1024x768@87I, ignore */ 414 {-1, -1, -1, -1}, /* t2 D[5] 832x624@75Hz, ignore */ 415 {800, 600, 75, 46.9, 49.5}, /* t2 D[6] */ 416 {800, 600, 72, 48.1, 50} /* t2 D[7] */ 417}; 418 419static const ModeTiming StdTiming[] = { 420 {640, 480, 60, 31.5, 25.175}, 421 {640, 480, 72, 37.9, 31.5}, 422 {640, 480, 75, 37.5, 31.5}, 423 {640, 480, 85, 43.3, 36.0}, 424 425 {800, 600, 56, 35.1, 36}, 426 {800, 600, 60, 37.9, 40}, 427 {800, 600, 72, 48.1, 50}, 428 {800, 600, 75, 46.9, 49.5}, 429 {800, 600, 85, 53.7, 56.25}, 430 431 {1024, 768, 43, 35.5, 44.9}, 432 {1024, 768, 60, 48.4, 65}, 433 {1024, 768, 70, 56.5, 75}, 434 {1024, 768, 75, 60, 78.75}, 435 {1024, 768, 85, 68.7, 94.5}, 436 437 {1152, 864, 75, 67.5, 108}, 438 439 {1280, 960, 60, 60, 108}, 440 {1280, 960, 85, 85.9, 148.5}, 441 {1280, 1024, 60, 64.0, 108}, 442 {1280, 1024, 75, 80, 135}, 443 {1280, 1024, 85, 91.1, 157.5}, 444 445 {1600, 1200, 60, 75, 162.0}, 446 {1600, 1200, 65, 81.3, 175.5}, 447 {1600, 1200, 70, 87.5, 189}, 448 {1600, 1200, 75, 93.8, 202}, 449 {1600, 1200, 85, 106.3, 229.5}, 450 451 {1792, 1344, 60, 83.64, 204.75}, 452 {1792, 1344, 75, 106.27, 261}, 453 454 {1856, 1392, 60, 86.33, 218.25}, 455 {1856, 1392, 75, 112.50, 288}, 456 457 {1920, 1440, 60, 90, 234}, 458 {1920, 1440, 75, 112.5, 297}, 459 {-1, -1, -1, -1, -1}, 460}; 461 462 463static void XGIDumpPalette(ScrnInfoPtr pScrn); 464#ifdef DEBUG 465void XGIDumpSR(ScrnInfoPtr pScrn); 466void XGIDumpCR(ScrnInfoPtr pScrn); 467static void XGIDumpGR(ScrnInfoPtr pScrn); 468static void XGIDumpPart1(ScrnInfoPtr pScrn); 469static void XGIDumpPart2(ScrnInfoPtr pScrn); 470static void XGIDumpPart3(ScrnInfoPtr pScrn); 471static void XGIDumpPart4(ScrnInfoPtr pScrn); 472static void XGIDumpMMIO(ScrnInfoPtr pScrn); 473#endif 474 475static int XGICalcVRate(DisplayModePtr mode); 476static unsigned char XGISearchCRT1Rate(ScrnInfoPtr pScrn, 477 DisplayModePtr mode); 478static void xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1, 479 unsigned char *reg2); 480static void xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1, 481 unsigned char reg2); 482 483/* Jong 12/05/2007; check mode with monitor DDC */ 484static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC); 485 486/* Jong 12/05/2007; filter mode list by monitor DDC */ 487static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC); 488 489static pointer 490xgiSetup(pointer module, pointer opts, int *errmaj, int *errmin) 491{ 492 static Bool setupDone = FALSE; 493 494 if (!setupDone) { 495 setupDone = TRUE; 496/* Jong@09022009 */ 497#if (XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(6,9,0,0,0) ) 498 xf86AddDriver(&XGI, module, HaveDriverFuncs); 499#else 500 xf86AddDriver(&XGI, module, 0); 501#endif 502 503#if 0 504 LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, 505 shadowSymbols, ramdacSymbols, ddcSymbols, 506 vbeSymbols, int10Symbols, 507#ifdef XF86DRI 508 drmSymbols, driSymbols, 509#endif 510 NULL); 511#endif 512 return (pointer) TRUE; 513 } 514 515 if (errmaj) 516 *errmaj = LDR_ONCEONLY; 517 return NULL; 518} 519 520 521static XGIPtr 522XGIGetRec(ScrnInfoPtr pScrn) 523{ 524 /* 525 * Allocate an XGIRec, and hook it into pScrn->driverPrivate. 526 * pScrn->driverPrivate is initialised to NULL, so we can check if 527 * the allocation has already been done. 528 */ 529 if (pScrn->driverPrivate == NULL) { 530 XGIPtr pXGI = xnfcalloc(sizeof(XGIRec), 1); 531 532 /* Initialise it to 0 */ 533 memset(pXGI, 0, sizeof(XGIRec)); 534 535 pScrn->driverPrivate = pXGI; 536 pXGI->pScrn = pScrn; 537 } 538 539 return (XGIPtr) pScrn->driverPrivate; 540} 541 542static void 543XGIFreeRec(ScrnInfoPtr pScrn) 544{ 545 XGIPtr pXGI = XGIPTR(pScrn); 546 XGIEntPtr pXGIEnt = NULL; 547 548 /* Just to make sure... */ 549 if (!pXGI) 550 return; 551 552 pXGIEnt = ENTITY_PRIVATE(pXGI); 553 if (pXGIEnt) { 554 if (!IS_SECOND_HEAD(pXGI)) { 555 /* Free memory only if we are first head; in case of an error 556 * during init of the second head, the server will continue - 557 * and we need the BIOS image and VB_DEVICE_INFO for the first 558 * head. 559 */ 560 if (pXGIEnt->BIOS) 561 xfree(pXGIEnt->BIOS); 562 pXGIEnt->BIOS = pXGI->BIOS = NULL; 563 if (pXGIEnt->XGI_Pr) 564 xfree(pXGIEnt->XGI_Pr); 565 pXGIEnt->XGI_Pr = pXGI->XGI_Pr = NULL; 566 if (pXGIEnt->RenderAccelArray) 567 xfree(pXGIEnt->RenderAccelArray); 568 pXGIEnt->RenderAccelArray = pXGI->RenderAccelArray = NULL; 569 } 570 else { 571 pXGI->BIOS = NULL; 572 pXGI->XGI_Pr = NULL; 573 pXGI->RenderAccelArray = NULL; 574 } 575 } 576 else { 577 if (pXGI->BIOS) 578 xfree(pXGI->BIOS); 579 pXGI->BIOS = NULL; 580 if (pXGI->XGI_Pr) 581 xfree(pXGI->XGI_Pr); 582 pXGI->XGI_Pr = NULL; 583 if (pXGI->RenderAccelArray) 584 xfree(pXGI->RenderAccelArray); 585 pXGI->RenderAccelArray = NULL; 586 } 587 588#ifdef XGIMERGED 589 if (pXGI->MetaModes) 590 xfree(pXGI->MetaModes); 591 pXGI->MetaModes = NULL; 592 593 if (pXGI->CRT1Modes) { 594 if (pXGI->CRT1Modes != pScrn->modes) { 595 if (pScrn->modes) { 596 pScrn->currentMode = pScrn->modes; 597 do { 598 DisplayModePtr p = pScrn->currentMode->next; 599 if (pScrn->currentMode->Private) 600 xfree(pScrn->currentMode->Private); 601 xfree(pScrn->currentMode); 602 pScrn->currentMode = p; 603 } while (pScrn->currentMode != pScrn->modes); 604 } 605 pScrn->currentMode = pXGI->CRT1CurrentMode; 606 pScrn->modes = pXGI->CRT1Modes; 607 pXGI->CRT1CurrentMode = NULL; 608 pXGI->CRT1Modes = NULL; 609 } 610 } 611#endif 612 if (pXGI->pVbe) 613 vbeFree(pXGI->pVbe); 614 pXGI->pVbe = NULL; 615 if (pScrn->driverPrivate == NULL) 616 return; 617 xfree(pScrn->driverPrivate); 618 pScrn->driverPrivate = NULL; 619} 620 621/* 622 SR1F Power management register 623 D7 Force CRT1 into DPMS suspend mode 624 0: disable 625 1: enable 626 D6 Force CRT1 into DPMS stand-by mode 627 0: disable 628 1: enable 629*/ 630static void 631XGIDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 632 int flags) 633{ 634 XGIPtr pXGI = XGIPTR(pScrn); 635 BOOLEAN docrt1 = TRUE, docrt2 = TRUE; 636 unsigned char sr1 = 0, cr17 = 0, cr63 = 0, sr11 = 0, pmreg = 0, sr7 = 0; 637 unsigned char p1_13 = 0, p2_0 = 0, oldpmreg = 0; 638 BOOLEAN backlight = TRUE; 639 640 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 641 "XGIDisplayPowerManagementSet(%d)\n", PowerManagementMode); 642 643#if 1 644 PVB_DEVICE_INFO pVBInfo = pXGI->XGI_Pr; 645 PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt; 646 ULONG PowerState = 0xFFFFFFFF; 647 648 if((PowerManagementMode != 0) && (PowerManagementMode <= 3)) 649 PowerState = 0x00000001 << (PowerManagementMode + 7); 650 else 651 PowerState = 0x0; 652 653 XGISetDPMS(pScrn, pVBInfo, pHwDevInfo, PowerState); 654#else 655 if (IS_DUAL_HEAD(pXGI)) { 656 if (IS_SECOND_HEAD(pXGI)) 657 docrt2 = FALSE; 658 else 659 docrt1 = FALSE; 660 } 661 662#ifdef UNLOCK_ALWAYS 663 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); 664#endif 665 666 switch (PowerManagementMode) { 667 668 case DPMSModeOn: /* HSync: On, VSync: On */ 669 PDEBUG(ErrorF("!-DPMSMode-On...\n")); 670 671 if (docrt1) 672 pXGI->Blank = FALSE; 673 674 sr1 = 0x00; 675 cr17 = 0x80; 676 pmreg = 0x00; 677 cr63 = 0x00; 678 sr7 = 0x10; 679 sr11 = (pXGI->LCDon & 0x0C); 680 p2_0 = 0x20; 681 p1_13 = 0x00; 682 backlight = TRUE; 683 break; 684 685 case DPMSModeSuspend: /* HSync: On, VSync: Off */ 686 PDEBUG(ErrorF("!-DPMSMode-Suspend...\n")); 687 688 if (docrt1) 689 pXGI->Blank = TRUE; 690 691 sr1 = 0x20; 692 cr17 = 0x80; 693 pmreg = 0x80; 694 cr63 = 0x40; 695 sr7 = 0x00; 696 sr11 = 0x08; 697 p2_0 = 0x40; 698 p1_13 = 0x80; 699 backlight = FALSE; 700 break; 701 702 case DPMSModeStandby: /* HSync: Off, VSync: On */ 703 PDEBUG(ErrorF("!-DPMSMode-Standby...\n")); 704 705 if (docrt1) 706 pXGI->Blank = TRUE; 707 708 sr1 = 0x20; 709 cr17 = 0x80; 710 pmreg = 0x40; 711 cr63 = 0x40; 712 sr7 = 0x00; 713 sr11 = 0x08; 714 p2_0 = 0x80; 715 p1_13 = 0x40; 716 backlight = FALSE; 717 break; 718 719 case DPMSModeOff: /* HSync: Off, VSync: Off */ 720 PDEBUG(ErrorF("!-DPMSMode-Off...\n")); 721 722 if (docrt1) 723 pXGI->Blank = TRUE; 724 725 sr1 = 0x20; 726 cr17 = 0x00; 727 pmreg = 0xc0; 728 cr63 = 0x40; 729 sr7 = 0x00; 730 sr11 = 0x08; 731 p2_0 = 0xc0; 732 p1_13 = 0xc0; 733 backlight = FALSE; 734 break; 735 736 default: 737 return; 738 } 739 740 if (docrt1) { 741 /* Set/Clear "Display On" bit 742 */ 743 setXGIIDXREG(XGISR, 0x01, ~0x20, sr1); 744 745 if ((!(pXGI->VBFlags & CRT1_LCDA)) 746 || (pXGI->XGI_Pr->VBType & VB_XGI301C)) { 747 inXGIIDXREG(XGISR, 0x1f, oldpmreg); 748 if (!pXGI->CRT1off) { 749 setXGIIDXREG(XGISR, 0x1f, 0x3f, pmreg); 750 } 751 } 752 oldpmreg &= 0xc0; 753 } 754 755 if ((docrt1) && (pmreg != oldpmreg) 756 && ((!(pXGI->VBFlags & CRT1_LCDA)) 757 || (pXGI->XGI_Pr->VBType & VB_XGI301C))) { 758 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */ 759 usleep(10000); 760 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */ 761 } 762#endif 763} 764 765typedef struct 766{ 767 char name[10]; 768 unsigned int DCLK; 769 unsigned int HDisplay; 770 unsigned int HSyncStart; 771 unsigned int HSyncEnd; 772 unsigned int HTotal; 773 unsigned int VDisplay; 774 unsigned int VSyncStart; 775 unsigned int VSyncEnd; 776 unsigned int VTotal; 777} XGITimingInfo; 778 779XGITimingInfo ExtraAvailableModeTiming[]= 780{ 781 {"1440x900", 782 106470, 783 1440, 1520, 1672, 1904, 784 900, 901, 904, 932}, 785 {"1680x1050", 786 146250, 787 1680, 1784, 1960, 2240, 788 1050, 1053, 1059, 1089}, 789 {"0x0", 790 106470, 791 1440, 1520, 1672, 1904, 792 900, 901, 904, 932} 793}; 794 795int ExtraAvailableModeTimingCount = 1; 796 797void XGIAddAvailableModes(DisplayModePtr availModes) 798{ 799 DisplayModePtr p; 800 DisplayModePtr q; 801 DisplayModePtr last; 802 DisplayModePtr first; 803 int i; 804 805 /* Scan to last node */ 806 for (q = availModes; q != NULL; q = q->next){ 807 last = q; 808 } 809 810 /* first = availModes->next; */ 811 812 /* Add all modes of ExtraAvailableModeTiming[] */ 813 for(i=0; /* i < ExtraAvailableModeTimingCount */ xf86NameCmp(ExtraAvailableModeTiming[i].name, "0x0") != 0 ; i++) 814 { 815 p = xnfcalloc(1, sizeof(DisplayModeRec)); 816 817 p->prev = last; 818 p->next = NULL; 819 last->next = p; 820 821 /* 822 first->next->prev = p; 823 p->prev = first; 824 p->next = first->next; 825 first->next = p; 826 */ 827 828 p->name = xnfalloc(strlen(ExtraAvailableModeTiming[i].name) + 1); 829 p->name = ExtraAvailableModeTiming[i].name; 830 p->status = MODE_OK; 831 832 p->type = M_T_CLOCK_CRTC_C /* M_T_BUILTIN */ /* M_T_USERDEF */ ; 833 834 p->Clock = ExtraAvailableModeTiming[i].DCLK; 835 p->HDisplay = ExtraAvailableModeTiming[i].HDisplay; 836 p->HSyncStart = ExtraAvailableModeTiming[i].HSyncStart; 837 p->HSyncEnd = ExtraAvailableModeTiming[i].HSyncEnd; 838 p->HTotal = ExtraAvailableModeTiming[i].HTotal; 839 840 p->VDisplay = ExtraAvailableModeTiming[i].VDisplay; 841 p->VSyncStart = ExtraAvailableModeTiming[i].VSyncStart; 842 p->VSyncEnd = ExtraAvailableModeTiming[i].VSyncEnd; 843 p->VTotal = ExtraAvailableModeTiming[i].VTotal; 844 845 p->Flags = 5; 846 847 last = p; 848 } 849} 850 851/* Mandatory */ 852static void 853XGIIdentify(int flags) 854{ 855 xf86PrintChipsets(XGI_NAME, "driver for XGI chipsets", XGIChipsets); 856 PDEBUG(ErrorF(" --- XGIIdentify \n")); 857} 858 859static void 860XGIErrorLog(ScrnInfoPtr pScrn, const char *format, ...) 861{ 862 va_list ap; 863 static const char *str = 864 "**************************************************\n"; 865 866 va_start(ap, format); 867 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s", str); 868 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " ERROR:\n"); 869 xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap); 870 va_end(ap); 871 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 872 " END OF MESSAGE\n"); 873 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s", str); 874} 875 876#ifdef XSERVER_LIBPCIACCESS 877static Bool XGIPciProbe(DriverPtr drv, int entity_num, 878 struct pci_device *dev, intptr_t match_data) 879{ 880 ScrnInfoPtr pScrn; 881 882 883 pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, 884 NULL, NULL, NULL, NULL, NULL); 885 if (pScrn != NULL) { 886 XGIPtr pXGI; 887 888 /* Fill in what we can of the ScrnInfoRec */ 889 pScrn->driverVersion = XGI_CURRENT_VERSION; 890 pScrn->driverName = XGI_DRIVER_NAME; 891 pScrn->name = XGI_NAME; 892 pScrn->Probe = NULL; 893 pScrn->PreInit = XGIPreInit; 894 pScrn->ScreenInit = XGIScreenInit; 895 pScrn->SwitchMode = XGISwitchMode; 896 pScrn->AdjustFrame = XGIAdjustFrame; 897 pScrn->EnterVT = XGIEnterVT; 898 pScrn->LeaveVT = XGILeaveVT; 899 pScrn->FreeScreen = XGIFreeScreen; 900 pScrn->ValidMode = XGIValidMode; 901 902 903 pXGI = XGIGetRec(pScrn); 904 if (pXGI == NULL) { 905 return FALSE; 906 } 907 908 pXGI->PciInfo = dev; 909 } 910 911 return (pScrn != NULL); 912} 913 914#else 915 916/* Mandatory */ 917static Bool 918XGIProbe(DriverPtr drv, int flags) 919{ 920 int i; 921 GDevPtr *devSections; 922 int *usedChips; 923 int numDevSections; 924 int numUsed; 925 Bool foundScreen = FALSE; 926 927 /* 928 * The aim here is to find all cards that this driver can handle, 929 * and for the ones not already claimed by another driver, claim the 930 * slot, and allocate a ScrnInfoRec. 931 * 932 * This should be a minimal probe, and it should under no circumstances 933 * change the state of the hardware. Because a device is found, don't 934 * assume that it will be used. Don't do any initialisations other than 935 * the required ScrnInfoRec initialisations. Don't allocate any new 936 * data structures. 937 * 938 */ 939 940 /* 941 * Next we check, if there has been a chipset override in the config file. 942 * For this we must find out if there is an active device section which 943 * is relevant, i.e., which has no driver specified or has THIS driver 944 * specified. 945 */ 946 947 if ((numDevSections = 948 xf86MatchDevice(XGI_DRIVER_NAME, &devSections)) <= 0) { 949 /* 950 * There's no matching device section in the config file, so quit 951 * now. 952 */ 953 return FALSE; 954 } 955 956 PDEBUG(ErrorF(" --- XGIProbe \n")); 957 /* 958 * We need to probe the hardware first. We then need to see how this 959 * fits in with what is given in the config file, and allow the config 960 * file info to override any contradictions. 961 */ 962 963 /* 964 * All of the cards this driver supports are PCI, so the "probing" just 965 * amounts to checking the PCI data that the server has already collected. 966 */ 967 if (xf86GetPciVideoInfo() == NULL) { 968 /* 969 * We won't let anything in the config file override finding no 970 * PCI video cards at all. This seems reasonable now, but we'll see. 971 */ 972 return FALSE; 973 } 974 975 numUsed = xf86MatchPciInstances(XGI_NAME, PCI_VENDOR_XGI, 976 XGIChipsets, XGIPciChipsets, devSections, 977 numDevSections, drv, &usedChips); 978 979 /* Free it since we don't need that list after this */ 980 xfree(devSections); 981 if (numUsed <= 0) 982 return FALSE; 983 984 if (flags & PROBE_DETECT) { 985 foundScreen = TRUE; 986 } 987 else 988 for (i = 0; i < numUsed; i++) { 989 ScrnInfoPtr pScrn; 990#ifdef XGIDUALHEAD 991 EntityInfoPtr pEnt; 992#endif 993 994 /* Allocate a ScrnInfoRec and claim the slot */ 995 pScrn = NULL; 996 997 if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], 998 XGIPciChipsets, NULL, NULL, 999 NULL, NULL, NULL))) { 1000 /* Fill in what we can of the ScrnInfoRec */ 1001 pScrn->driverVersion = XGI_CURRENT_VERSION; 1002 pScrn->driverName = XGI_DRIVER_NAME; 1003 pScrn->name = XGI_NAME; 1004 pScrn->Probe = XGIProbe; 1005 pScrn->PreInit = XGIPreInit; 1006 pScrn->ScreenInit = XGIScreenInit; 1007 pScrn->SwitchMode = XGISwitchMode; 1008 pScrn->AdjustFrame = XGIAdjustFrame; 1009 pScrn->EnterVT = XGIEnterVT; 1010 pScrn->LeaveVT = XGILeaveVT; 1011 pScrn->FreeScreen = XGIFreeScreen; 1012 pScrn->ValidMode = XGIValidMode; 1013 foundScreen = TRUE; 1014 } 1015#ifdef XGIDUALHEAD 1016 pEnt = xf86GetEntityInfo(usedChips[i]); 1017 1018#endif 1019 } 1020 xfree(usedChips); 1021 1022 return foundScreen; 1023} 1024#endif 1025 1026 1027/* Some helper functions for MergedFB mode */ 1028 1029#ifdef XGIMERGED 1030 1031/* Copy and link two modes form mergedfb mode 1032 * (Code base taken from mga driver) 1033 * Copys mode i, links the result to dest, and returns it. 1034 * Links i and j in Private record. 1035 * If dest is NULL, return value is copy of i linked to itself. 1036 * For mergedfb auto-config, we only check the dimension 1037 * against virtualX/Y, if they were user-provided. 1038 */ 1039static DisplayModePtr 1040XGICopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest, 1041 DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel) 1042{ 1043 XGIPtr pXGI = XGIPTR(pScrn); 1044 DisplayModePtr mode; 1045 int dx = 0, dy = 0; 1046 1047 ErrorF("XGICopyModeNLink()...Use Virtual Size-1\n"); 1048 1049 if (!((mode = xalloc(sizeof(DisplayModeRec))))) 1050 return dest; 1051 memcpy(mode, i, sizeof(DisplayModeRec)); 1052 if (!((mode->Private = xalloc(sizeof(XGIMergedDisplayModeRec))))) { 1053 xfree(mode); 1054 return dest; 1055 } 1056 ((XGIMergedDisplayModePtr) mode->Private)->CRT1 = i; 1057 ((XGIMergedDisplayModePtr) mode->Private)->CRT2 = j; 1058 ((XGIMergedDisplayModePtr) mode->Private)->CRT2Position = srel; 1059 mode->PrivSize = 0; 1060 1061 switch (srel) { 1062 case xgiLeftOf: 1063 case xgiRightOf: 1064 if (!(pScrn->display->virtualX)) { 1065 dx = i->HDisplay + j->HDisplay; 1066 } 1067 else { 1068 dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay); 1069 } 1070 dx -= mode->HDisplay; 1071 if (!(pScrn->display->virtualY)) { 1072 dy = max(i->VDisplay, j->VDisplay); 1073 } 1074 else { 1075 dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay)); 1076 } 1077 dy -= mode->VDisplay; 1078 break; 1079 case xgiAbove: 1080 case xgiBelow: 1081 if (!(pScrn->display->virtualY)) { 1082 dy = i->VDisplay + j->VDisplay; 1083 } 1084 else { 1085 dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay); 1086 } 1087 dy -= mode->VDisplay; 1088 if (!(pScrn->display->virtualX)) { 1089 dx = max(i->HDisplay, j->HDisplay); 1090 } 1091 else { 1092 dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay)); 1093 } 1094 dx -= mode->HDisplay; 1095 break; 1096 case xgiClone: 1097 if (!(pScrn->display->virtualX)) { 1098 dx = max(i->HDisplay, j->HDisplay); 1099 } 1100 else { 1101 dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay)); 1102 } 1103 dx -= mode->HDisplay; 1104 if (!(pScrn->display->virtualY)) { 1105 dy = max(i->VDisplay, j->VDisplay); 1106 } 1107 else { 1108 dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay)); 1109 } 1110 dy -= mode->VDisplay; 1111 break; 1112 } 1113 mode->HDisplay += dx; 1114 mode->HSyncStart += dx; 1115 mode->HSyncEnd += dx; 1116 mode->HTotal += dx; 1117 mode->VDisplay += dy; 1118 mode->VSyncStart += dy; 1119 mode->VSyncEnd += dy; 1120 mode->VTotal += dy; 1121 mode->Clock = 0; 1122 1123 if (((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > 1124 pXGI->maxxfbmem) || (mode->HDisplay > 4088) 1125 || (mode->VDisplay > 4096)) { 1126 1127 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1128 "Skipped %dx%d, not enough video RAM or beyond hardware specs\n", 1129 mode->HDisplay, mode->VDisplay); 1130 xfree(mode->Private); 1131 xfree(mode); 1132 1133 return dest; 1134 } 1135 1136#ifdef XGIXINERAMA 1137 if (srel != xgiClone) { 1138 pXGI->AtLeastOneNonClone = TRUE; 1139 } 1140#endif 1141 1142 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1143 "Merged %dx%d and %dx%d to %dx%d%s\n", 1144 i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay, 1145 mode->HDisplay, mode->VDisplay, 1146 (srel == xgiClone) ? " (Clone)" : ""); 1147 1148 mode->next = mode; 1149 mode->prev = mode; 1150 1151 if (dest) { 1152 mode->next = dest->next; /* Insert node after "dest" */ 1153 dest->next->prev = mode; 1154 mode->prev = dest; 1155 dest->next = mode; 1156 } 1157 1158 return mode; 1159} 1160 1161/* Helper function to find a mode from a given name 1162 * (Code base taken from mga driver) 1163 */ 1164static DisplayModePtr 1165XGIGetModeFromName(char *str, DisplayModePtr i) 1166{ 1167 DisplayModePtr c = i; 1168 if (!i) 1169 return NULL; 1170 do { 1171 if (strcmp(str, c->name) == 0) 1172 return c; 1173 c = c->next; 1174 } while (c != i); 1175 return NULL; 1176} 1177 1178static DisplayModePtr 1179XGIFindWidestTallestMode(DisplayModePtr i, Bool tallest) 1180{ 1181 DisplayModePtr c = i, d = NULL; 1182 int max = 0; 1183 if (!i) 1184 return NULL; 1185 do { 1186 if (tallest) { 1187 if (c->VDisplay > max) { 1188 max = c->VDisplay; 1189 d = c; 1190 } 1191 } 1192 else { 1193 if (c->HDisplay > max) { 1194 max = c->HDisplay; 1195 d = c; 1196 } 1197 } 1198 c = c->next; 1199 } while (c != i); 1200 return d; 1201} 1202 1203static DisplayModePtr 1204XGIGenerateModeListFromLargestModes(ScrnInfoPtr pScrn, 1205 DisplayModePtr i, DisplayModePtr j, 1206 XGIScrn2Rel srel) 1207{ 1208#ifdef XGIXINERAMA 1209 XGIPtr pXGI = XGIPTR(pScrn); 1210#endif 1211 DisplayModePtr mode1 = NULL; 1212 DisplayModePtr mode2 = NULL; 1213 DisplayModePtr result = NULL; 1214 1215#ifdef XGIXINERAMA 1216 pXGI->AtLeastOneNonClone = FALSE; 1217#endif 1218 1219 switch (srel) { 1220 case xgiLeftOf: 1221 case xgiRightOf: 1222 mode1 = XGIFindWidestTallestMode(i, FALSE); 1223 mode2 = XGIFindWidestTallestMode(j, FALSE); 1224 break; 1225 case xgiAbove: 1226 case xgiBelow: 1227 mode1 = XGIFindWidestTallestMode(i, TRUE); 1228 mode2 = XGIFindWidestTallestMode(j, TRUE); 1229 break; 1230 case xgiClone: 1231 mode1 = i; 1232 mode2 = j; 1233 } 1234 1235 if (mode1 && mode2) { 1236 return (XGICopyModeNLink(pScrn, result, mode1, mode2, srel)); 1237 } 1238 else { 1239 return NULL; 1240 } 1241} 1242 1243/* Generate the merged-fb mode modelist from metamodes 1244 * (Code base taken from mga driver) 1245 */ 1246static DisplayModePtr 1247XGIGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char *str, 1248 DisplayModePtr i, DisplayModePtr j, 1249 XGIScrn2Rel srel) 1250{ 1251#ifdef XGIXINERAMA 1252 XGIPtr pXGI = XGIPTR(pScrn); 1253#endif 1254 char *strmode = str; 1255 char modename[256]; 1256 Bool gotdash = FALSE; 1257 XGIScrn2Rel sr; 1258 DisplayModePtr mode1 = NULL; 1259 DisplayModePtr mode2 = NULL; 1260 DisplayModePtr result = NULL; 1261 1262#ifdef XGIXINERAMA 1263 pXGI->AtLeastOneNonClone = FALSE; 1264#endif 1265 1266 do { 1267 switch (*str) { 1268 case 0: 1269 case '-': 1270 case ' ': 1271 if ((strmode != str)) { 1272 1273 strncpy(modename, strmode, str - strmode); 1274 modename[str - strmode] = 0; 1275 1276 if (gotdash) { 1277 if (mode1 == NULL) 1278 return NULL; 1279 mode2 = XGIGetModeFromName(modename, j); 1280 if (!mode2) { 1281 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1282 "Mode \"%s\" is not a supported mode for CRT2\n", 1283 modename); 1284 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1285 "Skipping metamode \"%s-%s\".\n", 1286 mode1->name, modename); 1287 mode1 = NULL; 1288 } 1289 } 1290 else { 1291 mode1 = XGIGetModeFromName(modename, i); 1292 if (!mode1) { 1293 char *tmps = str; 1294 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1295 "Mode \"%s\" is not a supported mode for CRT1\n", 1296 modename); 1297 gotdash = FALSE; 1298 while (*tmps == ' ') 1299 tmps++; 1300 if (*tmps == '-') { /* skip the next mode */ 1301 tmps++; 1302 while ((*tmps == ' ') && (*tmps != 0)) 1303 tmps++; /* skip spaces */ 1304 while ((*tmps != ' ') && (*tmps != '-') 1305 && (*tmps != 0)) 1306 tmps++; /* skip modename */ 1307 strncpy(modename, strmode, tmps - strmode); 1308 modename[tmps - strmode] = 0; 1309 str = tmps - 1; 1310 } 1311 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1312 "Skipping metamode \"%s\".\n", modename); 1313 mode1 = NULL; 1314 } 1315 } 1316 gotdash = FALSE; 1317 } 1318 strmode = str + 1; 1319 gotdash |= (*str == '-'); 1320 1321 if (*str != 0) 1322 break; 1323 /* Fall through otherwise */ 1324 1325 default: 1326 if (!gotdash && mode1) { 1327 sr = srel; 1328 if (!mode2) { 1329 mode2 = XGIGetModeFromName(mode1->name, j); 1330 sr = xgiClone; 1331 } 1332 if (!mode2) { 1333 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1334 "Mode: \"%s\" is not a supported mode for CRT2\n", 1335 mode1->name); 1336 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1337 "Skipping metamode \"%s\".\n", modename); 1338 mode1 = NULL; 1339 } 1340 else { 1341 result = 1342 XGICopyModeNLink(pScrn, result, mode1, mode2, sr); 1343 mode1 = NULL; 1344 mode2 = NULL; 1345 } 1346 } 1347 break; 1348 1349 } 1350 1351 } while (*(str++) != 0); 1352 1353 return result; 1354} 1355 1356static DisplayModePtr 1357XGIGenerateModeList(ScrnInfoPtr pScrn, char *str, 1358 DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel) 1359{ 1360 if (str != NULL) { 1361 return (XGIGenerateModeListFromMetaModes(pScrn, str, i, j, srel)); 1362 } 1363 else { 1364 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1365 "No MetaModes given, linking %s modes by default\n", 1366 (srel == xgiClone) ? "first" : 1367 (((srel == xgiLeftOf) 1368 || (srel == xgiRightOf)) ? "widest" : "tallest")); 1369 return (XGIGenerateModeListFromLargestModes(pScrn, i, j, srel)); 1370 } 1371} 1372 1373static void 1374XGIRecalcDefaultVirtualSize(ScrnInfoPtr pScrn) 1375{ 1376 DisplayModePtr mode, bmode; 1377 int max; 1378 static const char *str = "MergedFB: Virtual %s %d\n"; 1379 1380 ErrorF("XGIRecalcDefaultVirtualSize()...Update Virtual Size-1\n"); 1381 if (!(pScrn->display->virtualX)) { 1382 mode = bmode = pScrn->modes; 1383 max = 0; 1384 do { 1385 if (mode->HDisplay > max) 1386 max = mode->HDisplay; 1387 mode = mode->next; 1388 } while (mode != bmode); 1389 pScrn->virtualX = max; 1390 pScrn->displayWidth = max; 1391 ErrorF("XGIRecalcDefaultVirtualSize()...Update Virtual Size-2-pScrn->virtualX=%d\n", pScrn->virtualX); 1392 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max); 1393 } 1394 if (!(pScrn->display->virtualY)) { 1395 mode = bmode = pScrn->modes; 1396 max = 0; 1397 do { 1398 if (mode->VDisplay > max) 1399 max = mode->VDisplay; 1400 mode = mode->next; 1401 } while (mode != bmode); 1402 pScrn->virtualY = max; 1403 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max); 1404 } 1405} 1406 1407static void 1408XGIMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, XGIScrn2Rel srel) 1409{ 1410 XGIPtr pXGI = XGIPTR(pScrn1); 1411 MessageType from = X_DEFAULT; 1412 xf86MonPtr DDC1 = (xf86MonPtr) (pScrn1->monitor->DDC); 1413 xf86MonPtr DDC2 = (xf86MonPtr) (pScrn2->monitor->DDC); 1414 int ddcWidthmm = 0, ddcHeightmm = 0; 1415 const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n"; 1416 1417 ErrorF("XGIMergedFBSetDpi()...Use Virtual Size -1\n"); 1418 1419 /* This sets the DPI for MergedFB mode. The problem is that 1420 * this can never be exact, because the output devices may 1421 * have different dimensions. This function tries to compromise 1422 * through a few assumptions, and it just calculates an average DPI 1423 * value for both monitors. 1424 */ 1425 1426 /* Given DisplaySize should regard BOTH monitors */ 1427 pScrn1->widthmm = pScrn1->monitor->widthmm; 1428 pScrn1->heightmm = pScrn1->monitor->heightmm; 1429 1430 /* Get DDC display size; if only either CRT1 or CRT2 provided these, 1431 * assume equal dimensions for both, otherwise add dimensions 1432 */ 1433 if ((DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) && 1434 (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0))) { 1435 ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10; 1436 ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10; 1437 switch (srel) { 1438 case xgiLeftOf: 1439 case xgiRightOf: 1440 ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10; 1441 break; 1442 case xgiAbove: 1443 case xgiBelow: 1444 ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10; 1445 default: 1446 break; 1447 } 1448 } 1449 else if (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) { 1450 ddcWidthmm = DDC1->features.hsize * 10; 1451 ddcHeightmm = DDC1->features.vsize * 10; 1452 switch (srel) { 1453 case xgiLeftOf: 1454 case xgiRightOf: 1455 ddcWidthmm *= 2; 1456 break; 1457 case xgiAbove: 1458 case xgiBelow: 1459 ddcHeightmm *= 2; 1460 default: 1461 break; 1462 } 1463 } 1464 else if (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) { 1465 ddcWidthmm = DDC2->features.hsize * 10; 1466 ddcHeightmm = DDC2->features.vsize * 10; 1467 switch (srel) { 1468 case xgiLeftOf: 1469 case xgiRightOf: 1470 ddcWidthmm *= 2; 1471 break; 1472 case xgiAbove: 1473 case xgiBelow: 1474 ddcHeightmm *= 2; 1475 default: 1476 break; 1477 } 1478 } 1479 1480 if (monitorResolution > 0) { 1481 1482 /* Set command line given values (overrules given options) */ 1483 pScrn1->xDpi = monitorResolution; 1484 pScrn1->yDpi = monitorResolution; 1485 from = X_CMDLINE; 1486 1487 } 1488 else if (pXGI->MergedFBXDPI) { 1489 1490 /* Set option-wise given values (overrule DisplaySize) */ 1491 pScrn1->xDpi = pXGI->MergedFBXDPI; 1492 pScrn1->yDpi = pXGI->MergedFBYDPI; 1493 from = X_CONFIG; 1494 1495 } 1496 else if (pScrn1->widthmm > 0 || pScrn1->heightmm > 0) { 1497 1498 /* Set values calculated from given DisplaySize */ 1499 from = X_CONFIG; 1500 if (pScrn1->widthmm > 0) { 1501 pScrn1->xDpi = 1502 (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm); 1503 } 1504 if (pScrn1->heightmm > 0) { 1505 pScrn1->yDpi = 1506 (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm); 1507 } 1508 xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, 1509 pScrn1->heightmm); 1510 1511 } 1512 else if (ddcWidthmm && ddcHeightmm) { 1513 1514 /* Set values from DDC-provided display size */ 1515 from = X_PROBED; 1516 xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm); 1517 pScrn1->widthmm = ddcWidthmm; 1518 pScrn1->heightmm = ddcHeightmm; 1519 if (pScrn1->widthmm > 0) { 1520 pScrn1->xDpi = 1521 (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm); 1522 } 1523 if (pScrn1->heightmm > 0) { 1524 pScrn1->yDpi = 1525 (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm); 1526 } 1527 1528 } 1529 else { 1530 1531 pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI; 1532 1533 } 1534 1535 /* Sanity check */ 1536 if (pScrn1->xDpi > 0 && pScrn1->yDpi <= 0) 1537 pScrn1->yDpi = pScrn1->xDpi; 1538 if (pScrn1->yDpi > 0 && pScrn1->xDpi <= 0) 1539 pScrn1->xDpi = pScrn1->yDpi; 1540 1541 pScrn2->xDpi = pScrn1->xDpi; 1542 pScrn2->yDpi = pScrn1->yDpi; 1543 1544 xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n", 1545 pScrn1->xDpi, pScrn1->yDpi); 1546} 1547 1548static void 1549XGIFreeCRT2Structs(XGIPtr pXGI) 1550{ 1551 if (pXGI->CRT2pScrn) { 1552 if (pXGI->CRT2pScrn->modes) { 1553 while (pXGI->CRT2pScrn->modes) 1554 xf86DeleteMode(&pXGI->CRT2pScrn->modes, 1555 pXGI->CRT2pScrn->modes); 1556 } 1557 if (pXGI->CRT2pScrn->monitor) { 1558 if (pXGI->CRT2pScrn->monitor->Modes) { 1559 while (pXGI->CRT2pScrn->monitor->Modes) 1560 xf86DeleteMode(&pXGI->CRT2pScrn->monitor->Modes, 1561 pXGI->CRT2pScrn->monitor->Modes); 1562 } 1563 if (pXGI->CRT2pScrn->monitor->DDC) 1564 xfree(pXGI->CRT2pScrn->monitor->DDC); 1565 xfree(pXGI->CRT2pScrn->monitor); 1566 } 1567 xfree(pXGI->CRT2pScrn); 1568 pXGI->CRT2pScrn = NULL; 1569 } 1570} 1571 1572#endif /* End of MergedFB helpers */ 1573 1574static xf86MonPtr 1575XGIInternalDDC(ScrnInfoPtr pScrn, int crtno) 1576{ 1577 XGIPtr pXGI = XGIPTR(pScrn); 1578 unsigned char buffer[256]; 1579 1580 int RealOff; 1581 unsigned char *page; 1582 1583 xf86MonPtr pMonitor = NULL; 1584 xf86Int10InfoPtr pInt = NULL; /* Our int10 */ 1585 1586 /*yilin 03/10/2008: set the monitor default size to 310mm x 240mm to fix KDE font too small problem*/ 1587 pScrn->monitor->widthmm = 310; 1588 pScrn->monitor->heightmm = 240; 1589 1590 static char *crtno_means_str[] = { 1591 "CRT1", "DVI", "CRT2" 1592 }; 1593 1594 if (crtno > 2 || crtno < 0) { 1595 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1596 "XGIInternalDDC(): Can not get EDID for crtno = %d,abort.\n", 1597 crtno); 1598 } 1599 else { 1600 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1601 "XGIInternalDDC(): getting EDID for %s.\n", 1602 crtno_means_str[crtno]); 1603 } 1604 1605/* Jong 08/03/2009; get EDID with I2C function instead of VBIOS call */ 1606#if 1 1607 ErrorF("get EDID with I2C function instead of VBIOS call...\n"); 1608 1609 PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt; 1610 PUCHAR pjEDIDBuffer = buffer; 1611 ULONG ulBufferSize = 256; 1612 1613 pHwDevInfo->crtno = crtno; 1614 int bEDID = bGetEDID(pHwDevInfo, crtno, pjEDIDBuffer, ulBufferSize); 1615 1616#else 1617 ErrorF("get EDID with VBIOS call...\n"); 1618 if (xf86LoadSubModule(pScrn, "int10")) 1619 { 1620#if 0 1621 xf86LoaderReqSymLists(int10Symbols, NULL); 1622#endif 1623 pInt = xf86InitInt10(pXGI->pEnt->index); 1624 if (pInt == NULL) { 1625 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1626 "XGIInternalDDC(): Can not initialize pInt, abort.\n"); 1627 return NULL; 1628 } 1629 1630 page = xf86Int10AllocPages(pInt, 1, &RealOff); 1631 if (page == NULL) { 1632 xf86FreeInt10(pInt); 1633 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1634 "XGIInternalDDC(): Can not initialize real mode buffer, abort.\n"); 1635 return NULL; 1636 } 1637 } 1638 1639 if (pInt) 1640 { 1641 pInt->ax = 0x4f15; /* VESA DDC supporting */ 1642 pInt->bx = 1; /* get EDID */ 1643 pInt->cx = crtno; /* port 0 or 1 for CRT 1 or 2 */ 1644 pInt->es = SEG_ADDR(RealOff); 1645 pInt->di = SEG_OFF(RealOff); 1646 pInt->num = 0x10; 1647 xf86ExecX86int10(pInt); 1648 1649 PDEBUG3(ErrorF 1650 ("ax = %04X bx = %04X cx = %04X dx = %04X si = %04X di = %04X es = %04X\n", 1651 pInt->ax, pInt->bx, pInt->cx, pInt->dx, pInt->si, pInt->di, 1652 pInt->es)); 1653#endif 1654 1655#if 0 1656 if ((pInt->ax & 0xff00) == 0) 1657 { 1658 int i; 1659 1660 for (i = 0; i < 128; i++) { 1661 buffer[i] = page[i]; 1662 } 1663#else /* Jong 08/03/2009; get EDID with I2C function instead of VBIOS call */ 1664 if(bEDID == 1) 1665 { 1666 int i; 1667#endif 1668 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1669 "XGIInternalDDC(): VESA get DDC success for output channel %d.\n", 1670 crtno + 1); 1671 1672 for (i = 0; i < 128; i += 16) { 1673 unsigned j; 1674 ErrorF("EDID[%02X]", i); 1675 for (j = 0; j < 16; j++) { 1676 ErrorF(" %02X", buffer[i + j]); 1677 } 1678 ErrorF("\n"); 1679 } 1680 1681 g_DVI_I_SignalType = (buffer[20] & 0x80) >> 7; 1682 ErrorF("DVI-I : %s signal ...\n", (g_DVI_I_SignalType == 0x01) ? "DVI" : "CRT" ); 1683#if 0 1684 xf86LoaderReqSymLists(ddcSymbols, NULL); 1685#endif 1686 /* Jong 09/04/2007; Alan fixed abnormal EDID data */ 1687 /* pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer) ; */ 1688 if ( (buffer[0]==0) && (buffer[7]==0) ) 1689 { 1690 for (i=1;i<7;i++) 1691 { 1692 if (buffer[i]!=0xFF) 1693 break; 1694 } 1695 if (i==7) 1696 { 1697 pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer); 1698 } 1699 } 1700 1701 if (pMonitor == NULL) { 1702 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1703 "CRT%d DDC EDID corrupt\n", crtno + 1); 1704 return (NULL); 1705 } 1706 xf86UnloadSubModule("ddc"); 1707 } 1708 else { 1709 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1710 "XGIInternalDDC(): VESA get DDC fail for output channel %d.\n", 1711 crtno + 1); 1712 } 1713 1714/* Jong 08/03/2009; get EDID with I2C function instead of VBIOS call */ 1715#if 0 1716 xf86Int10FreePages(pInt, page, 1); 1717 xf86FreeInt10(pInt); 1718 } 1719#endif 1720 1721 return pMonitor; 1722} 1723 1724/* static xf86MonPtr 1725XGIDoPrivateDDC(ScrnInfoPtr pScrn, int *crtnum) 1726{ 1727 XGIPtr pXGI = XGIPTR(pScrn); 1728 1729 if(IS_DUAL_HEAD(pXGI)) 1730 { 1731 if(IS_SECOND_HEAD(pXGI)) 1732 { 1733 *crtnum = 1; 1734 return(XGIInternalDDC(pScrn, 0)); 1735 } 1736 else 1737 { 1738 *crtnum = 2; 1739 return(XGIInternalDDC(pScrn, 1)); 1740 } 1741 } 1742 else if(pXGI->CRT1off) 1743 { 1744 *crtnum = 2; 1745 return(XGIInternalDDC(pScrn, 1)); 1746 } 1747 else 1748 { 1749 *crtnum = 1; 1750 return(XGIInternalDDC(pScrn, 0)); 1751 } 1752} */ 1753 1754 1755#ifdef DEBUG5 1756static void 1757XGIDumpMonitorInfo(xf86MonPtr pMonitor) 1758{ 1759 struct detailed_timings *pd_timings; 1760 Uchar *pserial; 1761 Uchar *pascii_data; 1762 Uchar *pname; 1763 struct monitor_ranges *pranges; 1764 struct std_timings *pstd_t; 1765 struct whitePoints *pwp; 1766 int i, j; 1767 1768 if (pMonitor == NULL) { 1769 ErrorF("Monitor is NULL"); 1770 return; 1771 } 1772 1773 ErrorF("pMonitor->scrnIndex = %d\n", pMonitor->scrnIndex); 1774 ErrorF 1775 ("vendor = %c%c%c%c, prod_id = %x serial = %d week = %d year = %d\n", 1776 pMonitor->vendor.name[0], pMonitor->vendor.name[1], 1777 pMonitor->vendor.name[2], pMonitor->vendor.name[3], 1778 pMonitor->vendor.prod_id, pMonitor->vendor.serial, 1779 pMonitor->vendor.week, pMonitor->vendor.year); 1780 1781 ErrorF("ver = %d %d\n", pMonitor->ver.version, pMonitor->ver.revision); 1782 ErrorF("intput type = %d voltage = %d setup = %d sync = %d\n", 1783 pMonitor->features.input_type, 1784 pMonitor->features.input_voltage, 1785 pMonitor->features.input_setup, pMonitor->features.input_sync); 1786 ErrorF("hsize = %d vsize = %d gamma=%8.3f\n", 1787 pMonitor->features.hsize, 1788 pMonitor->features.vsize, pMonitor->features.gamma); 1789 1790 ErrorF("dpms = %d display_type = %d msc = %d\n", 1791 pMonitor->features.dpms, 1792 pMonitor->features.display_type, pMonitor->features.msc); 1793 ErrorF 1794 ("redx,redy,greenx,greeny,bluex,bluey,whitex,whitey = %8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f\n", 1795 pMonitor->features.redx, pMonitor->features.redy, 1796 pMonitor->features.greenx, pMonitor->features.greeny, 1797 pMonitor->features.bluex, pMonitor->features.bluey, 1798 pMonitor->features.whitex, pMonitor->features.whitey); 1799 1800 ErrorF("established_timings = (t1)%d%d%d%d%d%d%d%d", 1801 (pMonitor->timings1.t1 >> 7) & 1, 1802 (pMonitor->timings1.t1 >> 6) & 1, 1803 (pMonitor->timings1.t1 >> 5) & 1, 1804 (pMonitor->timings1.t1 >> 4) & 1, 1805 (pMonitor->timings1.t1 >> 3) & 1, 1806 (pMonitor->timings1.t1 >> 2) & 1, 1807 (pMonitor->timings1.t1 >> 1) & 1, 1808 (pMonitor->timings1.t1 >> 0) & 1); 1809 ErrorF("(t2) %d%d%d%d%d%d%d%d", 1810 (pMonitor->timings1.t1 >> 7) & 1, 1811 (pMonitor->timings1.t1 >> 6) & 1, 1812 (pMonitor->timings1.t1 >> 5) & 1, 1813 (pMonitor->timings1.t1 >> 4) & 1, 1814 (pMonitor->timings1.t1 >> 3) & 1, 1815 (pMonitor->timings1.t1 >> 2) & 1, 1816 (pMonitor->timings1.t1 >> 1) & 1, 1817 (pMonitor->timings1.t1 >> 0) & 1); 1818 ErrorF("(t_manu)%d%d%d%d%d%d%d%d\n", 1819 (pMonitor->timings1.t_manu >> 7) & 1, 1820 (pMonitor->timings1.t_manu >> 6) & 1, 1821 (pMonitor->timings1.t_manu >> 5) & 1, 1822 (pMonitor->timings1.t_manu >> 4) & 1, 1823 (pMonitor->timings1.t_manu >> 3) & 1, 1824 (pMonitor->timings1.t_manu >> 2) & 1, 1825 (pMonitor->timings1.t_manu >> 1) & 1, 1826 (pMonitor->timings1.t_manu >> 0) & 1); 1827 1828 for (i = 0; i < 7; i++) { 1829 ErrorF 1830 ("std timing %d: hsize = %d, vsize = %d, refresh = %d, id = %d\n", 1831 i, pMonitor->timings2[i].hsize, pMonitor->timings2[i].vsize, 1832 pMonitor->timings2[i].refresh, pMonitor->timings2[i].id); 1833 } 1834 1835 for (i = 0; i < 4; i++) { 1836 ErrorF("Detail timing section %d\n", i); 1837 ErrorF("type = %x\n", pMonitor->det_mon[i].type); 1838 switch (pMonitor->det_mon[i].type) { 1839 case DS_SERIAL: 1840 ErrorF("type = %x DS_SERIAL = %x\n", pMonitor->det_mon[i].type, 1841 DS_SERIAL); 1842 break; 1843 case DS_ASCII_STR: 1844 ErrorF("type = %x DS_ASCII_STR = %x\n", pMonitor->det_mon[i].type, 1845 DS_ASCII_STR); 1846 break; 1847 case DS_NAME: 1848 ErrorF("type = %x DS_NAME = %x\n", pMonitor->det_mon[i].type, 1849 DS_NAME); 1850 break; 1851 case DS_RANGES: 1852 ErrorF("type = %x DS_RANGES = %x\n", pMonitor->det_mon[i].type, 1853 DS_RANGES); 1854 break; 1855 case DS_WHITE_P: 1856 ErrorF("type = %x DS_WHITE_P = %x\n", pMonitor->det_mon[i].type, 1857 DS_WHITE_P); 1858 break; 1859 case DS_STD_TIMINGS: 1860 ErrorF("type = %x DS_STD_TIMINGS = %x\n", 1861 pMonitor->det_mon[i].type, DS_STD_TIMINGS); 1862 break; 1863 } 1864 switch (pMonitor->det_mon[i].type) { 1865 case DS_SERIAL: 1866 pserial = pMonitor->det_mon[i].section.serial; 1867 ErrorF("seial: "); 1868 for (j = 0; j < 13; j++) { 1869 ErrorF("%02X", pserial[j]); 1870 } 1871 ErrorF("\n"); 1872 break; 1873 case DS_ASCII_STR: 1874 pascii_data = pMonitor->det_mon[i].section.ascii_data; 1875 ErrorF("ascii: "); 1876 for (j = 0; j < 13; j++) { 1877 ErrorF("%c", pascii_data[j]); 1878 } 1879 ErrorF("\n"); 1880 break; 1881 case DS_NAME: 1882 pname = pMonitor->det_mon[i].section.name; 1883 ErrorF("name: "); 1884 for (j = 0; j < 13; j++) { 1885 ErrorF("%c", pname[j]); 1886 } 1887 ErrorF("\n"); 1888 break; 1889 case DS_RANGES: 1890 pranges = &(pMonitor->det_mon[i].section.ranges); 1891 ErrorF 1892 ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n", 1893 pranges->min_v, pranges->max_v, pranges->min_h, 1894 pranges->max_h, pranges->max_clock); 1895 break; 1896 case DS_WHITE_P: 1897 pwp = pMonitor->det_mon[i].section.wp; 1898 for (j = 0; j < 2; j++) { 1899 ErrorF 1900 ("wp[%d].index = %d white_x = %8.3f white_y = %8.3f white_gamma = %8.3f\n", 1901 j, pwp[j].index, pwp[j].white_x, pwp[j].white_y, 1902 pwp[j].white_gamma); 1903 } 1904 break; 1905 case DS_STD_TIMINGS: 1906 pstd_t = pMonitor->det_mon[i].section.std_t; 1907 for (j = 0; j < 5; j++) { 1908 ErrorF 1909 ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n", 1910 j, pstd_t[j].hsize, pstd_t[j].vsize, pstd_t[j].refresh, 1911 pstd_t[j].id); 1912 } 1913 break; 1914 case DT: 1915 1916 pd_timings = &pMonitor->det_mon[i].section.d_timings; 1917 ErrorF("Detail Timing Descriptor\n"); 1918 ErrorF("clock = %d\n", pd_timings->clock); 1919 ErrorF("h_active = %d\n", pd_timings->h_active); 1920 ErrorF("h_blanking = %d\n", pd_timings->h_blanking); 1921 ErrorF("v_active = %d\n", pd_timings->v_active); 1922 ErrorF("v_blanking = %d\n", pd_timings->v_blanking); 1923 ErrorF("h_sync_off = %d\n", pd_timings->h_sync_off); 1924 ErrorF("h_sync_width = %d\n", pd_timings->h_sync_width); 1925 ErrorF("v_sync_off = %d\n", pd_timings->v_sync_off); 1926 ErrorF("v_sync_width = %d\n", pd_timings->v_sync_width); 1927 ErrorF("h_size = %d\n", pd_timings->h_size); 1928 ErrorF("v_size = %d\n", pd_timings->v_size); 1929 ErrorF("h_border = %d\n", pd_timings->h_border); 1930 ErrorF("v_border = %d\n", pd_timings->v_border); 1931 ErrorF("interlaced = %d stereo = %x sync = %x misc = %x\n", 1932 pd_timings->interlaced, 1933 pd_timings->stereo, pd_timings->sync, pd_timings->misc); 1934 break; 1935 } 1936 } 1937 1938 for (i = 0; i < 128; i += 16) { 1939 ErrorF("rawData[%02X]:", i); 1940 for (j = 0; j < 16; j++) { 1941 ErrorF(" %02X", pMonitor->rawData[i + j]); 1942 } 1943 ErrorF("\n"); 1944 } 1945} 1946#endif 1947 1948static void 1949XGIGetMonitorRangeByDDC(MonitorRangePtr range, xf86MonPtr pMonitor) 1950{ 1951 int i, j; 1952 float VF, HF; 1953 struct detailed_timings *pd_timings; 1954 struct monitor_ranges *pranges; 1955 struct std_timings *pstd_t; 1956 1957 if ((range == NULL) || (pMonitor == NULL)) { 1958 return; /* ignore */ 1959 } 1960 1961 PDEBUG5(ErrorF 1962 ("establish timing t1 = %02x t2=%02x\n", pMonitor->timings1.t1, 1963 pMonitor->timings1.t2)); 1964 1965 for (i = 0, j = 0; i < 8; i++, j++) 1966 { 1967 if (establish_timing[j].width == -1) { 1968 continue; 1969 } 1970 1971 if (pMonitor->timings1.t1 & (1 << i)) 1972 { 1973 PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n", 1974 establish_timing[j].width, 1975 establish_timing[j].height, 1976 establish_timing[j].VRefresh, 1977 establish_timing[j].HSync)); 1978 1979 if (range->loH > establish_timing[j].HSync) { 1980 range->loH = establish_timing[j].HSync; 1981 } 1982 1983 if (range->hiH < establish_timing[j].HSync) { 1984 range->hiH = establish_timing[j].HSync; 1985 } 1986 1987 if (range->loV > establish_timing[j].VRefresh) { 1988 range->loV = establish_timing[j].VRefresh; 1989 } 1990 1991 if (range->hiV < establish_timing[j].VRefresh) { 1992 range->hiV = establish_timing[j].VRefresh; 1993 } 1994 } 1995 } 1996 1997 PDEBUG5(ErrorF 1998 ("check establish timing t1:range ( %8.3f %8.3f %8.3f %8.3f )\n", 1999 range->loH, range->loV, range->hiH, range->hiV)); 2000 2001 for (i = 0; i < 8; i++, j++) { 2002 if (establish_timing[j].width == -1) { 2003 continue; 2004 } 2005 2006 if (pMonitor->timings1.t2 & (1 << i)) { 2007 PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n", 2008 establish_timing[j].width, 2009 establish_timing[j].height, 2010 establish_timing[j].VRefresh, 2011 establish_timing[j].HSync)); 2012 2013 if (range->loH > establish_timing[j].HSync) { 2014 range->loH = establish_timing[j].HSync; 2015 } 2016 2017 if (range->hiH < establish_timing[j].HSync) { 2018 range->hiH = establish_timing[j].HSync; 2019 } 2020 2021 if (range->loV > establish_timing[j].VRefresh) { 2022 range->loV = establish_timing[j].VRefresh; 2023 } 2024 2025 if (range->hiV < establish_timing[j].VRefresh) { 2026 range->hiV = establish_timing[j].VRefresh; 2027 } 2028 } 2029 } 2030 PDEBUG5(ErrorF 2031 ("check establish timing t2:range ( %8.3f %8.3f %8.3f %8.3f )\n", 2032 range->loH, range->loV, range->hiH, range->hiV)); 2033 2034 for (i = 0; i < 8; i++) { 2035 for (j = 0; StdTiming[j].width != -1; j++) { 2036 if ((StdTiming[j].width == pMonitor->timings2[i].hsize) && 2037 (StdTiming[j].height == pMonitor->timings2[i].vsize) && 2038 (StdTiming[j].VRefresh == pMonitor->timings2[i].refresh)) { 2039 PDEBUG5(ErrorF("pMonitor->timings2[%d]= %d %d %d %d\n", 2040 i, 2041 pMonitor->timings2[i].hsize, 2042 pMonitor->timings2[i].vsize, 2043 pMonitor->timings2[i].refresh, 2044 pMonitor->timings2[i].id)); 2045 HF = StdTiming[j].HSync; 2046 VF = StdTiming[j].VRefresh; 2047 if (range->loH > HF) 2048 range->loH = HF; 2049 if (range->loV > VF) 2050 range->loV = VF; 2051 if (range->hiH < HF) 2052 range->hiH = HF; 2053 if (range->hiV < VF) 2054 range->hiV = VF; 2055 break; 2056 } 2057 } 2058 } 2059 PDEBUG5(ErrorF 2060 ("check standard timing :range ( %8.3f %8.3f %8.3f %8.3f )\n", 2061 range->loH, range->loV, range->hiH, range->hiV)); 2062 2063 for (i = 0; i < 4; i++) { 2064 switch (pMonitor->det_mon[i].type) { 2065 case DS_RANGES: 2066 pranges = &(pMonitor->det_mon[i].section.ranges); 2067 PDEBUG5(ErrorF 2068 ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n", 2069 pranges->min_v, pranges->max_v, pranges->min_h, 2070 pranges->max_h, pranges->max_clock)); 2071 2072 if (range->loH > pranges->min_h) 2073 range->loH = pranges->min_h; 2074 if (range->loV > pranges->min_v) 2075 range->loV = pranges->min_v; 2076 if (range->hiH < pranges->max_h) 2077 range->hiH = pranges->max_h; 2078 if (range->hiV < pranges->max_v) 2079 range->hiV = pranges->max_v; 2080 PDEBUG5(ErrorF 2081 ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, 2082 range->loV, range->hiH, range->hiV)); 2083 break; 2084 2085 case DS_STD_TIMINGS: 2086 pstd_t = pMonitor->det_mon[i].section.std_t; 2087 for (j = 0; j < 5; j++) { 2088 int k; 2089 PDEBUG5(ErrorF 2090 ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n", 2091 j, pstd_t[j].hsize, pstd_t[j].vsize, 2092 pstd_t[j].refresh, pstd_t[j].id)); 2093 for (k = 0; StdTiming[k].width != -1; k++) { 2094 if ((StdTiming[k].width == pstd_t[j].hsize) && 2095 (StdTiming[k].height == pstd_t[j].vsize) && 2096 (StdTiming[k].VRefresh == pstd_t[j].refresh)) { 2097 if (range->loH > StdTiming[k].HSync) 2098 range->loH = StdTiming[k].HSync; 2099 if (range->hiH < StdTiming[k].HSync) 2100 range->hiH = StdTiming[k].HSync; 2101 if (range->loV > StdTiming[k].VRefresh) 2102 range->loV = StdTiming[k].VRefresh; 2103 if (range->hiV < StdTiming[k].VRefresh) 2104 range->hiV = StdTiming[k].VRefresh; 2105 break; 2106 } 2107 2108 } 2109 } 2110 break; 2111 2112 case DT: 2113 2114 pd_timings = &pMonitor->det_mon[i].section.d_timings; 2115 2116 HF = pd_timings->clock / (pd_timings->h_active + 2117 pd_timings->h_blanking); 2118 VF = HF / (pd_timings->v_active + pd_timings->v_blanking); 2119 HF /= 1000; /* into KHz Domain */ 2120 if (range->loH > HF) 2121 range->loH = HF; 2122 if (range->hiH < HF) 2123 range->hiH = HF; 2124 if (range->loV > VF) 2125 range->loV = VF; 2126 if (range->hiV < VF) 2127 range->hiV = VF; 2128 PDEBUG(ErrorF 2129 ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n", 2130 HF, VF, range->loH, range->loV, range->hiH, range->hiV)); 2131 break; 2132 } 2133 } 2134 PDEBUG5(ErrorF 2135 ("Done range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, range->loV, 2136 range->hiH, range->hiV)); 2137 2138} 2139 2140static void 2141XGISyncDDCMonitorRange(MonPtr monitor, MonitorRangePtr range) 2142{ 2143 int i; 2144 if ((monitor == NULL) || (range == NULL)) { 2145 return; 2146 } 2147 2148 monitor->nHsync++; 2149 monitor->nVrefresh++; 2150 2151#if 1 2152 monitor->hsync[monitor->nHsync-1].lo = range->loH; 2153 monitor->hsync[monitor->nHsync-1].hi = range->hiH; 2154 monitor->vrefresh[monitor->nVrefresh-1].lo = range->loV; 2155 monitor->vrefresh[monitor->nVrefresh-1].hi = range->hiV; 2156#else 2157 for (i = 0; i < monitor->nHsync; i++) { 2158 monitor->hsync[i].lo = range->loH; 2159 monitor->hsync[i].hi = range->hiH; 2160 } 2161 2162 for (i = 0; i < monitor->nVrefresh; i++) { 2163 monitor->vrefresh[i].lo = range->loV; 2164 monitor->vrefresh[i].hi = range->hiV; 2165 } 2166#endif 2167} 2168 2169/* Jong@08212009; defined in vb_ext.c */ 2170extern void XGIPowerSaving(PVB_DEVICE_INFO pVBInfo, UCHAR PowerSavingStatus); 2171UCHAR g_PowerSavingStatus = 0x00; 2172 2173static void 2174XGIDDCPreInit(ScrnInfoPtr pScrn) 2175{ 2176 2177 XGIPtr pXGI = XGIPTR(pScrn); 2178 xf86MonPtr pMonitor = NULL; 2179 xf86MonPtr pMonitorCRT1 = NULL; 2180 xf86MonPtr pMonitorDVI = NULL; 2181 xf86MonPtr pMonitorCRT2 = NULL; 2182 Bool didddc2; 2183 2184 UCHAR PowerSavingStatus = 0xFF; /* 0x00; */ 2185 2186 if(pXGI->IgnoreDDC) 2187 { 2188 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2189 "Ignore DDC detection --> No EDID info...turn on all DAC and DVO\n"); 2190 XGIPowerSaving(pXGI->XGI_Pr, 0x00); 2191 return; 2192 } 2193 2194 static const char *ddcsstr = 2195 "CRT%d DDC monitor info: ************************************\n"; 2196 static const char *ddcestr = 2197 "End of CRT%d DDC monitor info ******************************\n"; 2198 2199 /* Now for something completely different: DDC. 2200 * For 300 and 315/330 series, we provide our 2201 * own functions (in order to probe CRT2 as well) 2202 * If these fail, use the VBE. 2203 * All other chipsets will use VBE. No need to re-invent 2204 * the wheel there. 2205 */ 2206 2207 pXGI->pVbe = NULL; 2208 didddc2 = FALSE; 2209 2210 /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */ 2211 if (IS_DUAL_HEAD(pXGI) && (!didddc2) && !IS_SECOND_HEAD(pXGI)) 2212 didddc2 = TRUE; 2213 2214 if (!didddc2) { 2215 /* If CRT1 is off or LCDA, skip DDC via VBE */ 2216 if ((pXGI->CRT1off) || (pXGI->VBFlags & CRT1_LCDA)) 2217 didddc2 = TRUE; 2218 } 2219 2220 /* Now (re-)load and initialize the DDC module */ 2221 if (!didddc2) { 2222 2223 if (xf86LoadSubModule(pScrn, "ddc")) 2224 { 2225#if 0 2226 xf86LoaderReqSymLists(ddcSymbols, NULL); 2227#endif 2228 if (pXGI->xgi_HwDevExt.jChipType == XG27) 2229 { 2230 ErrorF("Getting CRT EDID (DAC1-CRT1)...\n"); 2231 pMonitorCRT1 = XGIInternalDDC(pScrn, 0); 2232 2233 if (pMonitorCRT1 == NULL) 2234 { 2235 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2236 "Could not retrieve DDC data for CRT1\n"); 2237 /* PowerSavingStatus |= 0x01; */ /* device is not detected through DAC1 */ 2238 2239 ErrorF("Getting DVI EDID (DVO)...\n"); 2240 pMonitorDVI = XGIInternalDDC(pScrn, 1); 2241 2242 if (pMonitorDVI == NULL) { 2243 /* PowerSavingStatus |= 0x02; */ /* device is not detected through DVO */ 2244 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2245 "Could not retrieve DDC data for DVI\n"); 2246 } 2247 else 2248 { 2249 PowerSavingStatus &= ~0x02; /* device is detected through DVO */ 2250 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2251 "Succeed to retrieve DDC data for DVI\n"); 2252 } 2253 } 2254 else 2255 { 2256 if(g_DVI_I_SignalType == 0x00) /* analog CRT */ 2257 PowerSavingStatus &= ~0x01; /* CRT device is detected */ 2258 else /* DVI digital */ 2259 PowerSavingStatus &= ~0x02; /* DVI device is detected */ 2260 2261 2262 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2263 "Succeed to retrieve DDC data for %s\n", (g_DVI_I_SignalType == 0x01) ? "DVI" : "CRT"); 2264 } 2265 2266 ErrorF("Getting CRT EDID (CRT2)...\n"); 2267 pMonitorCRT2 = XGIInternalDDC(pScrn, 2); 2268 2269 if (pMonitorCRT2 == NULL) { 2270 /* PowerSavingStatus |= 0x04; */ /* device is not detected through DAC2 */ 2271 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2272 "Could not retrieve DDC data for CRT2\n"); 2273 } 2274 else /* Used for filtering of CRT1/DVI modes; g_pMonitorDVI is not a good naming; should be g_pMonitorFilter */ 2275 { 2276 PowerSavingStatus &= ~0x04; /* device is detected through DAC2 */ 2277 g_pMonitorDVI=pMonitorCRT2; 2278 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2279 "Succeed to retrieve DDC data for CRT2\n"); 2280 } 2281 2282 if (pMonitorCRT1 != NULL) 2283 pMonitor = pMonitorCRT1; 2284 else if(pMonitorDVI != NULL) 2285 pMonitor = pMonitorDVI; 2286 else if(pMonitorCRT2 != NULL) 2287 pMonitor = pMonitorCRT2; 2288 } 2289 else /* for XG20/21 */ 2290 { 2291 ErrorF("Getting CRT EDID (CRT1)...\n"); 2292 pMonitor = XGIInternalDDC(pScrn, 0); 2293 2294 if (pMonitor == NULL) { 2295 PowerSavingStatus |= 0x01; /* device is not detected through DAC1 */ 2296 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2297 "Could not retrieve DDC data\n"); 2298 } 2299 2300 if (pXGI->xgi_HwDevExt.jChipType == XG21) /* CRT1 -DVI */ 2301 { 2302 ErrorF("Getting XG21 DVI EDID (crt2)...\n"); 2303 pMonitorDVI = XGIInternalDDC(pScrn, 1); 2304 2305 if (pMonitorDVI == NULL) { 2306 PowerSavingStatus |= 0x02; /* device is not detected through DVO */ 2307 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2308 "Could not retrieve DVI DDC data\n"); 2309 } 2310 else /* Jong 12/04/2007; used for filtering of CRT1 modes */ 2311 { 2312 g_pMonitorDVI=pMonitorDVI; 2313 } 2314 2315 if ((pMonitor == NULL) && (pMonitorDVI != NULL)) { 2316 pMonitor = pMonitorDVI; 2317 } 2318 } 2319 } 2320 } 2321 } 2322 2323 ErrorF("PowerSavingStatus = 0x%x...\n", PowerSavingStatus); 2324 2325 if(PowerSavingStatus == 0xFF) 2326 PowerSavingStatus = 0x00; 2327 2328 2329/* if((pXGI->xgi_HwDevExt.jChipType == XG27) && (PowerSavingStatus == 0x07)) 2330 PowerSavingStatus = 0x00; 2331 2332 if((pXGI->xgi_HwDevExt.jChipType == XG21) && (PowerSavingStatus == 0x03)) 2333 PowerSavingStatus = 0x00; 2334*/ 2335 2336 XGIPowerSaving(pXGI->XGI_Pr, PowerSavingStatus); 2337 g_PowerSavingStatus = PowerSavingStatus; 2338 2339 /* initialize */ 2340 2341 if (pXGI->xgi_HwDevExt.jChipType == XG27) 2342 { 2343 if (pMonitorCRT1) { 2344 pXGI->CRT1Range.loH = 1000; 2345 pXGI->CRT1Range.loV = 1000; 2346 pXGI->CRT1Range.hiH = 0; 2347 pXGI->CRT1Range.hiV = 0; 2348 XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitorCRT1); 2349 2350 if (pMonitorDVI) { 2351 XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitorDVI); 2352 } 2353 } 2354 else { 2355 if (pMonitorDVI) { 2356 pXGI->CRT1Range.loV = 1000; 2357 pXGI->CRT1Range.loH = 1000; 2358 pXGI->CRT1Range.hiH = 0; 2359 pXGI->CRT1Range.hiV = 0; 2360 XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitorDVI); 2361 } 2362 else { 2363 pXGI->CRT1Range.loH = 0; 2364 pXGI->CRT1Range.loV = 0; 2365 pXGI->CRT1Range.hiH = 1000; 2366 pXGI->CRT1Range.hiV = 1000; 2367 } 2368 } 2369 2370 if (pMonitorCRT2) { 2371 pXGI->CRT2Range.loV = 1000; 2372 pXGI->CRT2Range.loH = 1000; 2373 pXGI->CRT2Range.hiH = 0; 2374 pXGI->CRT2Range.hiV = 0; 2375 XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorCRT2); 2376 } 2377 else { 2378 pXGI->CRT2Range.loH = 0; 2379 pXGI->CRT2Range.loV = 0; 2380 pXGI->CRT2Range.hiH = 1000; 2381 pXGI->CRT2Range.hiV = 1000; 2382 } 2383 } 2384 else /* XG20/21 */ 2385 { 2386 if (pMonitor) { 2387 pXGI->CRT1Range.loH = 1000; 2388 pXGI->CRT1Range.loV = 1000; 2389 pXGI->CRT1Range.hiH = 0; 2390 pXGI->CRT1Range.hiV = 0; 2391 XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitor); 2392 } 2393 else { 2394 pXGI->CRT1Range.loH = 0; 2395 pXGI->CRT1Range.loV = 0; 2396 pXGI->CRT1Range.hiH = 1000; 2397 pXGI->CRT1Range.hiV = 1000; 2398 } 2399 2400 if (pMonitorDVI) { 2401 pXGI->CRT2Range.loV = 1000; 2402 pXGI->CRT2Range.loH = 1000; 2403 pXGI->CRT2Range.hiH = 0; 2404 pXGI->CRT2Range.hiV = 0; 2405 XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorDVI); 2406 } 2407 else { 2408 pXGI->CRT2Range.loH = 0; 2409 pXGI->CRT2Range.loV = 0; 2410 pXGI->CRT2Range.hiH = 1000; 2411 pXGI->CRT2Range.hiV = 1000; 2412 } 2413 } 2414 2415 /* Jong@08132009 */ 2416 /* if (pXGI->xgi_HwDevExt.jChipType == XG21) { */ 2417 if ((pXGI->xgi_HwDevExt.jChipType == XG21) || (pXGI->xgi_HwDevExt.jChipType == XG27) ) { 2418 /* Mode range intersecting */ 2419 if (pXGI->CRT1Range.loH < pXGI->CRT2Range.loH) { 2420 pXGI->CRT1Range.loH = pXGI->CRT2Range.loH; 2421 } 2422 if (pXGI->CRT1Range.loV < pXGI->CRT2Range.loV) { 2423 pXGI->CRT1Range.loV = pXGI->CRT2Range.loV; 2424 } 2425 if (pXGI->CRT1Range.hiH > pXGI->CRT2Range.hiH) { 2426 pXGI->CRT1Range.hiH = pXGI->CRT2Range.hiH; 2427 } 2428 if (pXGI->CRT1Range.hiV > pXGI->CRT2Range.hiV) { 2429 pXGI->CRT1Range.hiV = pXGI->CRT2Range.hiV; 2430 } 2431 } 2432 2433 if (pMonitor) { 2434 XGISyncDDCMonitorRange(pScrn->monitor, &pXGI->CRT1Range); 2435 } 2436 2437 if (pScrn->monitor) { 2438 pScrn->monitor->DDC = pMonitor; 2439 } 2440 2441 return; 2442 2443#ifdef XGIMERGED 2444 if (pXGI->MergedFB) { 2445 pXGI->CRT2pScrn->monitor = xalloc(sizeof(MonRec)); 2446 if (pXGI->CRT2pScrn->monitor) { 2447 DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL; 2448 memcpy(pXGI->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec)); 2449 pXGI->CRT2pScrn->monitor->DDC = NULL; 2450 pXGI->CRT2pScrn->monitor->Modes = NULL; 2451 tempm = pScrn->monitor->Modes; 2452 while (tempm) { 2453 if (!(newm = xalloc(sizeof(DisplayModeRec)))) 2454 break; 2455 memcpy(newm, tempm, sizeof(DisplayModeRec)); 2456 if (!(newm->name = xalloc(strlen(tempm->name) + 1))) { 2457 xfree(newm); 2458 break; 2459 } 2460 strcpy(newm->name, tempm->name); 2461 if (!pXGI->CRT2pScrn->monitor->Modes) 2462 pXGI->CRT2pScrn->monitor->Modes = newm; 2463 if (currentm) { 2464 currentm->next = newm; 2465 newm->prev = currentm; 2466 } 2467 currentm = newm; 2468 tempm = tempm->next; 2469 } 2470 2471 if ((pMonitor = XGIInternalDDC(pXGI->CRT2pScrn, 1))) { 2472 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, 2); 2473 xf86PrintEDID(pMonitor); 2474 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, 2); 2475 xf86SetDDCproperties(pXGI->CRT2pScrn, pMonitor); 2476 2477 pXGI->CRT2pScrn->monitor->DDC = pMonitor; 2478 2479 /* use DDC data if no ranges in config file */ 2480 if (!pXGI->CRT2HSync) { 2481 pXGI->CRT2pScrn->monitor->nHsync = 0; 2482 } 2483 if (!pXGI->CRT2VRefresh) { 2484 pXGI->CRT2pScrn->monitor->nVrefresh = 0; 2485 } 2486 } 2487 else { 2488 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2489 "Failed to read DDC data for CRT2\n"); 2490 } 2491 } 2492 else { 2493 XGIErrorLog(pScrn, 2494 "Failed to allocate memory for CRT2 monitor, %s.\n", 2495 mergeddisstr); 2496 if (pXGI->CRT2pScrn) 2497 xfree(pXGI->CRT2pScrn); 2498 pXGI->CRT2pScrn = NULL; 2499 pXGI->MergedFB = FALSE; 2500 } 2501 } 2502#endif 2503 2504#ifdef XGIMERGED 2505 if (pXGI->MergedFB) { 2506 xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 1); 2507 } 2508#endif 2509 2510 /* end of DDC */ 2511} 2512 2513#ifdef DEBUG5 2514static void 2515XGIDumpModePtr(DisplayModePtr mode) 2516{ 2517 if (mode == NULL) 2518 return; 2519 2520 ErrorF("Dump DisplayModePtr mode\n"); 2521 ErrorF("name = %s\n", mode->name); 2522 /* ModeStatus status; */ 2523 ErrorF("type = %d\n", mode->type); 2524 ErrorF("Clock = %d\n", mode->Clock); 2525 ErrorF("HDisplay = %d\n", mode->HDisplay); 2526 ErrorF("HSyncStart = %d\n", mode->HSyncStart); 2527 ErrorF("HSyncEnd = %d\n", mode->HSyncEnd); 2528 ErrorF("HTotal = %d\n", mode->HTotal); 2529 ErrorF("HSkew = %d\n", mode->HSkew); 2530 ErrorF("VDisplay = %d\n", mode->VDisplay); 2531 ErrorF("VSyncStart = %d\n", mode->VSyncStart); 2532 ErrorF("VSyncEnd = %d\n", mode->VSyncEnd); 2533 ErrorF("VTotal = %d\n", mode->VTotal); 2534 ErrorF("VScan = %d\n", mode->VScan); 2535 ErrorF("Flags = %d\n", mode->Flags); 2536 2537 2538 ErrorF("ClockIndex = %d\n", mode->ClockIndex); 2539 ErrorF("SynthClock = %d\n", mode->SynthClock); 2540 ErrorF("CrtcHDisplay = %d\n", mode->CrtcHDisplay); 2541 ErrorF("CrtcHBlankStart = %d\n", mode->CrtcHBlankStart); 2542 ErrorF("CrtcHSyncStart = %d\n", mode->CrtcHSyncStart); 2543 ErrorF("CrtcHSyncEnd = %d\n", mode->CrtcHSyncEnd); 2544 ErrorF("CrtcHBlankEnd = %d\n", mode->CrtcHBlankEnd); 2545 ErrorF("CrtcHTotal = %d\n", mode->CrtcHTotal); 2546 ErrorF("CrtcHSkew = %d\n", mode->CrtcHSkew); 2547 ErrorF("CrtcVDisplay = %d\n", mode->CrtcVDisplay); 2548 ErrorF("CrtcVBlankStart = %d\n", mode->CrtcVBlankStart); 2549 ErrorF("CrtcVSyncStart = %d\n", mode->CrtcVSyncStart); 2550 ErrorF("CrtcVSyncEnd = %d\n", mode->CrtcVSyncEnd); 2551 ErrorF("CrtcVBlankEnd = %d\n", mode->CrtcVBlankEnd); 2552 ErrorF("CrtcVTotal = %d\n", mode->CrtcVTotal); 2553 ErrorF("CrtcHAdjusted = %s\n", (mode->CrtcHAdjusted) ? "TRUE" : "FALSE"); 2554 ErrorF("CrtcVAdjusted = %s\n", (mode->CrtcVAdjusted) ? "TRUE" : "FALSE"); 2555 ErrorF("PrivSize = %d\n", mode->PrivSize); 2556 /* INT32 * Private; */ 2557 ErrorF("PrivFlags = %d\n", mode->PrivFlags); 2558 ErrorF("HSync = %8.3f\n", mode->HSync); 2559 ErrorF("VRefresh = %8.3f\n", mode->VRefresh); 2560} 2561#endif 2562 2563static void 2564XGIDumpMonPtr(MonPtr pMonitor) 2565{ 2566#ifdef DEBUG5 2567 int i; 2568# if 0 2569 DisplayModePtr mode; 2570#endif 2571 2572 ErrorF("XGIDumpMonPtr() ... \n"); 2573 if (pMonitor == NULL) { 2574 ErrorF("pMonitor is NULL\n"); 2575 } 2576 2577 ErrorF("id = %s, vendor = %s model = %s\n", 2578 pMonitor->id, pMonitor->vendor, pMonitor->model); 2579 ErrorF("nHsync = %d\n", pMonitor->nHsync); 2580 ErrorF("nVrefresh = %d\n", pMonitor->nVrefresh); 2581 2582 for (i = 0; i < MAX_HSYNC; i++) { 2583 ErrorF("hsync[%d] = (%8.3f,%8.3f)\n", i, pMonitor->hsync[i].lo, 2584 pMonitor->hsync[i].hi); 2585 } 2586 2587 for (i = 0; i < MAX_VREFRESH; i++) { 2588 ErrorF("vrefresh[%d] = (%8.3f,%8.3f)\n", i, pMonitor->vrefresh[i].lo, 2589 pMonitor->vrefresh[i].hi); 2590 } 2591 2592 ErrorF("widthmm = %d, heightmm = %d\n", 2593 pMonitor->widthmm, pMonitor->heightmm); 2594 ErrorF("options = %p, DDC = %p\n", pMonitor->options, pMonitor->DDC); 2595# if 0 2596 mode = pMonitor->Modes; 2597 while (1) { 2598 XGIDumpModePtr(mode); 2599 if (mode == pMonitor->Last) { 2600 break; 2601 } 2602 mode = mode->next; 2603 } 2604# endif 2605#endif /* DEBUG5 */ 2606} 2607 2608/* Jong 09/19/2007; support modeline of custom modes */ 2609int ModifyTypeOfSupportMode(DisplayModePtr availModes) 2610{ 2611 int CountOfModifiedModes=0; 2612 DisplayModePtr p=availModes; 2613 2614 while(p) 2615 { 2616 /* if( (p->HDisplay == 1440) && (p->VDisplay == 900)) */ 2617 if( p->type == 0) /* externel support modeline */ 2618 { 2619 p->type = M_T_USERDEF; 2620 CountOfModifiedModes++; 2621 } 2622 2623 p=p->next; 2624 } 2625 2626 return(CountOfModifiedModes); 2627} 2628 2629 2630/* Mandatory */ 2631static Bool 2632XGIPreInit(ScrnInfoPtr pScrn, int flags) 2633{ 2634 XGIPtr pXGI; 2635 MessageType from; 2636 unsigned long int i; 2637 int temp; 2638 ClockRangePtr clockRanges; 2639 int pix24flags; 2640 int fd; 2641 struct fb_fix_screeninfo fix; 2642 XGIEntPtr pXGIEnt = NULL; 2643 size_t memreq; 2644 2645#if defined(XGIMERGED) || defined(XGIDUALHEAD) 2646 DisplayModePtr first, p, n; 2647#endif 2648 unsigned char srlockReg, crlockReg; 2649 vbeInfoPtr pVbe; 2650 2651 /****************** Code Start ***********************/ 2652 2653 ErrorF("XGIPreInit\n"); 2654 2655 if (flags & PROBE_DETECT) { 2656 if (xf86LoadSubModule(pScrn, "vbe")) { 2657 int index = xf86GetEntityInfo(pScrn->entityList[0])->index; 2658 2659 if ((pVbe = VBEExtendedInit(NULL, index, 0))) { 2660 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 2661 vbeFree(pVbe); 2662 } 2663 } 2664 return TRUE; 2665 } 2666 2667 /* 2668 * Note: This function is only called once at server startup, and 2669 * not at the start of each server generation. This means that 2670 * only things that are persistent across server generations can 2671 * be initialised here. xf86Screens[] is the array of all screens, 2672 * (pScrn is a pointer to one of these). Privates allocated using 2673 * xf86AllocateScrnInfoPrivateIndex() are too, and should be used 2674 * for data that must persist across server generations. 2675 * 2676 * Per-generation data should be allocated with 2677 * AllocateScreenPrivateIndex() from the ScreenInit() function. 2678 */ 2679 2680 /* Check the number of entities, and fail if it isn't one. */ 2681 if (pScrn->numEntities != 1) { 2682 XGIErrorLog(pScrn, "Number of entities is not 1\n"); 2683 return FALSE; 2684 } 2685 2686 /* The vgahw module should be loaded here when needed */ 2687 if (!xf86LoadSubModule(pScrn, "vgahw")) { 2688 XGIErrorLog(pScrn, "Could not load vgahw module\n"); 2689 return FALSE; 2690 } 2691#if 0 2692 xf86LoaderReqSymLists(vgahwSymbols, NULL); 2693#endif 2694 /* Due to the liberal license terms this is needed for 2695 * keeping the copyright notice readable and intact in 2696 * binary distributions. Removing this is a copyright 2697 * infringement. Please read the license terms above. 2698 */ 2699 2700 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2701 "XGI driver (%s)\n", "01/21/2009" /*XGI_RELEASE_DATE*/); 2702 2703 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2704 "Copyright (C) 2001-2004 Thomas Winischhofer <thomas@winischhofer.net> and others\n"); 2705 2706 /* Allocate a vgaHWRec */ 2707 if (!vgaHWGetHWRec(pScrn)) { 2708 XGIErrorLog(pScrn, "Could not allocate VGA private\n"); 2709 return FALSE; 2710 } 2711 2712 /* Allocate the XGIRec driverPrivate */ 2713 pXGI = XGIGetRec(pScrn); 2714 if (pXGI == NULL) { 2715 XGIErrorLog(pScrn, "Could not allocate memory for pXGI private\n"); 2716 return FALSE; 2717 } 2718 2719 pXGI->IODBase = pScrn->domainIOBase; 2720 2721 2722 /* Get the entity, and make sure it is PCI. */ 2723 pXGI->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 2724 if (pXGI->pEnt->location.type != BUS_PCI) { 2725 XGIErrorLog(pScrn, "Entity's bus type is not PCI\n"); 2726 XGIFreeRec(pScrn); 2727 return FALSE; 2728 } 2729 2730#ifdef XGIDUALHEAD 2731 /* Allocate an entity private if necessary */ 2732 if (xf86IsEntityShared(pScrn->entityList[0])) { 2733 pXGIEnt = xf86GetEntityPrivate(pScrn->entityList[0], 2734 XGIEntityIndex)->ptr; 2735 pXGI->entityPrivate = pXGIEnt; 2736 2737 /* If something went wrong, quit here */ 2738 if ((pXGIEnt->DisableDual) || (pXGIEnt->ErrorAfterFirst)) { 2739 XGIErrorLog(pScrn, 2740 "First head encountered fatal error, can't continue\n"); 2741 XGIFreeRec(pScrn); 2742 return FALSE; 2743 } 2744 } 2745#endif 2746 2747 /* Find the PCI info for this screen */ 2748#ifndef XSERVER_LIBPCIACCESS 2749 pXGI->PciInfo = xf86GetPciInfoForEntity(pXGI->pEnt->index); 2750 pXGI->PciTag = pciTag(pXGI->PciInfo->bus, pXGI->PciInfo->device, 2751 pXGI->PciInfo->func); 2752#endif 2753 2754 pXGI->Primary = xf86IsPrimaryPci(pXGI->PciInfo); 2755 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2756 "This adapter is %s display adapter\n", 2757 (pXGI->Primary ? "primary" : "secondary")); 2758 2759 if (pXGI->Primary) { 2760#if defined(__arm__) 2761 VGAHWPTR(pScrn)->MapPhys = pXGI->PciInfo->ioBase[2] + 0xf2000000; 2762#endif 2763 2764 VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */ 2765 if (!vgaHWMapMem(pScrn)) { 2766 XGIErrorLog(pScrn, "Could not map VGA memory\n"); 2767 XGIFreeRec(pScrn); 2768 return FALSE; 2769 } else { 2770#if defined(__arm__) 2771 vgaHWSetMmioFuncs(VGAHWPTR(pScrn), VGAHWPTR(pScrn)->Base, 0); 2772#endif 2773 2774 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 2775 "VGA memory map from %p to %p \n", 2776#ifdef XSERVER_LIBPCIACCESS 2777 (void *)(intptr_t)pXGI->PciInfo->regions[2].base_addr, VGAHWPTR(pScrn)->Base); 2778#else 2779 (void *)(intptr_t)pXGI->PciInfo->ioBase[2], VGAHWPTR(pScrn)->Base); 2780#endif 2781 } 2782 } 2783 vgaHWGetIOBase(VGAHWPTR(pScrn)); 2784 2785 /* Jong@08262009; why not to modify ??? */ 2786 /* We "patch" the PIOOffset inside vgaHW in order to force 2787 * the vgaHW module to use our relocated i/o ports. 2788 */ 2789 VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 + 2790#ifdef XSERVER_LIBPCIACCESS 2791 (pXGI->PciInfo->regions[2].base_addr & 0xFFFC) 2792#else 2793 (pXGI->PciInfo->ioBase[2] & 0xFFFC) 2794#endif 2795 ; 2796 2797 pXGI->pInt = NULL; 2798 if (!pXGI->Primary) { 2799#if !defined(__alpha__) 2800#if !defined(__powerpc__) 2801 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2802 "Initializing display adapter through int10\n"); 2803 2804 if (xf86LoadSubModule(pScrn, "int10")) { 2805#if 0 2806 xf86LoaderReqSymLists(int10Symbols, NULL); 2807#endif 2808 pXGI->pInt = xf86InitInt10(pXGI->pEnt->index); 2809 } 2810 else { 2811 XGIErrorLog(pScrn, "Could not load int10 module\n"); 2812 } 2813#endif /* !defined(__powerpc__) */ 2814#endif /* !defined(__alpha__) */ 2815 } 2816 2817#ifndef XSERVER_LIBPCIACCESS 2818 xf86SetOperatingState(resVgaMem, pXGI->pEnt->index, ResUnusedOpr); 2819 2820 /* Operations for which memory access is required */ 2821 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 2822 /* Operations for which I/O access is required */ 2823 pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 2824#endif 2825 2826 /* The ramdac module should be loaded here when needed */ 2827 if (!xf86LoadSubModule(pScrn, "ramdac")) { 2828 XGIErrorLog(pScrn, "Could not load ramdac module\n"); 2829 2830 if (pXGIEnt) 2831 pXGIEnt->ErrorAfterFirst = TRUE; 2832 2833 if (pXGI->pInt) 2834 xf86FreeInt10(pXGI->pInt); 2835 XGIFreeRec(pScrn); 2836 return FALSE; 2837 } 2838#if 0 2839 xf86LoaderReqSymLists(ramdacSymbols, NULL); 2840#endif 2841 /* Set pScrn->monitor */ 2842 pScrn->monitor = pScrn->confScreen->monitor; 2843 2844 /* Jong 09/19/2007; modify type of support modes to M_T_USERDEF */ 2845 g_CountOfUserDefinedModes=ModifyTypeOfSupportMode(pScrn->monitor->Modes); 2846 2847 /* 2848 * Set the Chipset and ChipRev, allowing config file entries to 2849 * override. DANGEROUS! 2850 */ 2851 if (pXGI->pEnt->device->chipset && *pXGI->pEnt->device->chipset) { 2852 PDEBUG(ErrorF(" --- Chipset 1 \n")); 2853 pScrn->chipset = pXGI->pEnt->device->chipset; 2854 pXGI->Chipset = xf86StringToToken(XGIChipsets, pScrn->chipset); 2855 from = X_CONFIG; 2856 } 2857 else if (pXGI->pEnt->device->chipID >= 0) { 2858 PDEBUG(ErrorF(" --- Chipset 2 \n")); 2859 pXGI->Chipset = pXGI->pEnt->device->chipID; 2860 pScrn->chipset = 2861 (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset); 2862 2863 from = X_CONFIG; 2864 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 2865 pXGI->Chipset); 2866 } 2867 else { 2868 PDEBUG(ErrorF(" --- Chipset 3 \n")); 2869 from = X_PROBED; 2870 pXGI->Chipset = DEVICE_ID(pXGI->PciInfo); 2871 pScrn->chipset = 2872 (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset); 2873 } 2874 if (pXGI->pEnt->device->chipRev >= 0) { 2875 pXGI->ChipRev = pXGI->pEnt->device->chipRev; 2876 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 2877 pXGI->ChipRev); 2878 } 2879 else { 2880 pXGI->ChipRev = CHIP_REVISION(pXGI->PciInfo); 2881 } 2882 pXGI->xgi_HwDevExt.jChipRevision = pXGI->ChipRev; 2883 2884 PDEBUG(ErrorF(" --- Chipset : %s \n", pScrn->chipset)); 2885 2886 2887 /* 2888 * This shouldn't happen because such problems should be caught in 2889 * XGIProbe(), but check it just in case. 2890 */ 2891 if (pScrn->chipset == NULL) { 2892 XGIErrorLog(pScrn, "ChipID 0x%04X is not recognised\n", 2893 pXGI->Chipset); 2894 2895 if (pXGIEnt) 2896 pXGIEnt->ErrorAfterFirst = TRUE; 2897 2898 if (pXGI->pInt) 2899 xf86FreeInt10(pXGI->pInt); 2900 XGIFreeRec(pScrn); 2901 return FALSE; 2902 } 2903 2904 if (pXGI->Chipset < 0) { 2905 XGIErrorLog(pScrn, "Chipset \"%s\" is not recognised\n", 2906 pScrn->chipset); 2907 2908 if (pXGIEnt) 2909 pXGIEnt->ErrorAfterFirst = TRUE; 2910 2911 if (pXGI->pInt) 2912 xf86FreeInt10(pXGI->pInt); 2913 XGIFreeRec(pScrn); 2914 return FALSE; 2915 } 2916 2917 /* Determine chipset and VGA engine type */ 2918 pXGI->ChipFlags = 0; 2919 pXGI->XGI_SD_Flags = 0; 2920 2921 switch (pXGI->Chipset) { 2922 case PCI_CHIP_XGIXG40: 2923 case PCI_CHIP_XGIXG20: 2924 case PCI_CHIP_XGIXG21: 2925 pXGI->xgi_HwDevExt.jChipType = XG40; 2926 pXGI->myCR63 = 0x63; 2927 pXGI->mmioSize = 64; 2928 break; 2929 2930 case PCI_CHIP_XGIXG27: 2931 pXGI->xgi_HwDevExt.jChipType = XG27; 2932 pXGI->myCR63 = 0x63; 2933 pXGI->mmioSize = 64; 2934 break; 2935 2936 default: 2937 /* This driver currently only supports V3XE, V3XT, V5, V8 (all of 2938 * which are XG40 chips) and Z7 (which is XG20). 2939 */ 2940 if (pXGI->pInt) { 2941 xf86FreeInt10(pXGI->pInt); 2942 } 2943 XGIFreeRec(pScrn); 2944 return FALSE; 2945 } 2946 2947/* load frame_buffer */ 2948 2949 FbDevExist = FALSE; 2950 if((pXGI->Chipset != PCI_CHIP_XGIXG20)&&(pXGI->Chipset != PCI_CHIP_XGIXG21)&&( pXGI->Chipset != PCI_CHIP_XGIXG27 )) 2951 { 2952 if ((fd = open("/dev/fb", 'r')) != -1) { 2953 PDEBUG(ErrorF("--- open /dev/fb.... \n")); 2954 ioctl(fd, FBIOGET_FSCREENINFO, &fix); 2955 if (fix.accel == FB_ACCEL_XGI_GLAMOUR) { 2956 PDEBUG(ErrorF("--- fix.accel.... \n")); 2957 FbDevExist = TRUE; 2958 } 2959 else 2960 PDEBUG(ErrorF("--- no fix.accel.... 0x%08lx \n", fix.accel)); 2961 close(fd); 2962 } 2963 } 2964 2965 2966 /* 2967 * The first thing we should figure out is the depth, bpp, etc. 2968 * Additionally, determine the size of the HWCursor memory area. 2969 */ 2970 pXGI->CursorSize = 4096; 2971 pix24flags = Support32bppFb; 2972 2973#ifdef XGIDUALHEAD 2974 /* In case of Dual Head, we need to determine if we are the "master" head or 2975 * the "slave" head. In order to do that, we set PrimInit to DONE in the 2976 * shared entity at the end of the first initialization. The second 2977 * initialization then knows that some things have already been done. THIS 2978 * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER! 2979 */ 2980 2981 if (xf86IsEntityShared(pScrn->entityList[0])) { 2982 if (pXGIEnt->lastInstance > 0) { 2983 if (!xf86IsPrimInitDone(pScrn->entityList[0])) { 2984 /* First Head (always CRT2) */ 2985 pXGI->SecondHead = FALSE; 2986 pXGIEnt->pScrn_1 = pScrn; 2987 pXGIEnt->CRT2ModeNo = -1; 2988 pXGIEnt->CRT2ModeSet = FALSE; 2989 pXGI->DualHeadMode = TRUE; 2990 pXGIEnt->DisableDual = FALSE; 2991 pXGIEnt->BIOS = NULL; 2992 pXGIEnt->XGI_Pr = NULL; 2993 pXGIEnt->RenderAccelArray = NULL; 2994 } 2995 else { 2996 /* Second Head (always CRT1) */ 2997 pXGI->SecondHead = TRUE; 2998 pXGIEnt->pScrn_2 = pScrn; 2999 pXGI->DualHeadMode = TRUE; 3000 } 3001 } 3002 else { 3003 /* Only one screen in config file - disable dual head mode */ 3004 pXGI->SecondHead = FALSE; 3005 pXGI->DualHeadMode = FALSE; 3006 pXGIEnt->DisableDual = TRUE; 3007 } 3008 } 3009 else { 3010 /* Entity is not shared - disable dual head mode */ 3011 pXGI->SecondHead = FALSE; 3012 pXGI->DualHeadMode = FALSE; 3013 } 3014#endif 3015 3016 /* Allocate VB_DEVICE_INFO (for mode switching code) and initialize it */ 3017 pXGI->XGI_Pr = NULL; 3018 if (pXGIEnt && pXGIEnt->XGI_Pr) { 3019 pXGI->XGI_Pr = pXGIEnt->XGI_Pr; 3020 } 3021 3022 if (!pXGI->XGI_Pr) { 3023 if (!(pXGI->XGI_Pr = xnfcalloc(sizeof(VB_DEVICE_INFO), 1))) { 3024 XGIErrorLog(pScrn, 3025 "Could not allocate memory for XGI_Pr private\n"); 3026 3027 if (pXGIEnt) 3028 pXGIEnt->ErrorAfterFirst = TRUE; 3029 if (pXGI->pInt) 3030 xf86FreeInt10(pXGI->pInt); 3031 XGIFreeRec(pScrn); 3032 return FALSE; 3033 } 3034 3035 if (pXGIEnt) 3036 pXGIEnt->XGI_Pr = pXGI->XGI_Pr; 3037 3038 memset(pXGI->XGI_Pr, 0, sizeof(VB_DEVICE_INFO)); 3039 } 3040 3041 /* Get our relocated IO registers */ 3042#if defined(__arm__) 3043 pXGI->RelIO = (XGIIOADDRESS)(((IOADDRESS)VGAHWPTR(pScrn)->Base & 0xFFFFFFFC) + pXGI->IODBase); 3044 3045#else 3046 pXGI->RelIO = (XGIIOADDRESS) (pXGI->IODBase | 3047#ifdef XSERVER_LIBPCIACCESS 3048 (pXGI->PciInfo->regions[2].base_addr & 0xFFFC) 3049#else 3050 (pXGI->PciInfo->ioBase[2] & 0xFFFC) 3051#endif 3052 ); 3053#endif 3054 3055 pXGI->xgi_HwDevExt.pjIOAddress = (XGIIOADDRESS) (pXGI->RelIO + 0x30); 3056 xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n", 3057 (unsigned long) pXGI->RelIO); 3058 ErrorF("xgi_driver.c-pXGI->xgi_HwDevExt.pjIOAddress=0x%lx...\n", pXGI->xgi_HwDevExt.pjIOAddress); 3059 3060 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) { 3061 XGIErrorLog(pScrn, "xf86SetDepthBpp() error\n"); 3062 3063 if (pXGIEnt) 3064 pXGIEnt->ErrorAfterFirst = TRUE; 3065 3066 if (pXGI->pInt) 3067 xf86FreeInt10(pXGI->pInt); 3068 XGIFreeRec(pScrn); 3069 return FALSE; 3070 } 3071 3072 /* Check that the returned depth is one we support */ 3073 temp = 0; 3074 switch (pScrn->depth) { 3075 case 8: 3076 case 16: 3077 case 24: 3078#if !defined(__powerpc__) 3079 case 15: 3080#endif 3081 break; 3082 default: 3083 temp = 1; 3084 } 3085 3086 if (temp) { 3087 XGIErrorLog(pScrn, 3088 "Given color depth (%d) is not supported by this driver/chipset\n", 3089 pScrn->depth); 3090 if (pXGI->pInt) 3091 xf86FreeInt10(pXGI->pInt); 3092 XGIFreeRec(pScrn); 3093 return FALSE; 3094 } 3095 3096 xf86PrintDepthBpp(pScrn); 3097 3098 /* Get the depth24 pixmap format */ 3099 if (pScrn->depth == 24 && pix24bpp == 0) { 3100 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 3101 } 3102 3103 /* 3104 * This must happen after pScrn->display has been set because 3105 * xf86SetWeight references it. 3106 */ 3107 if (pScrn->depth > 8) { 3108 /* The defaults are OK for us */ 3109 rgb zeros = { 0, 0, 0 }; 3110 3111 if (!xf86SetWeight(pScrn, zeros, zeros)) { 3112 XGIErrorLog(pScrn, "xf86SetWeight() error\n"); 3113 3114 if (pXGIEnt) 3115 pXGIEnt->ErrorAfterFirst = TRUE; 3116 3117 if (pXGI->pInt) 3118 xf86FreeInt10(pXGI->pInt); 3119 XGIFreeRec(pScrn); 3120 return FALSE; 3121 } 3122 else { 3123 Bool ret = FALSE; 3124 switch (pScrn->depth) { 3125 case 15: 3126 if ((pScrn->weight.red != 5) || 3127 (pScrn->weight.green != 5) || (pScrn->weight.blue != 5)) 3128 ret = TRUE; 3129 break; 3130 case 16: 3131 if ((pScrn->weight.red != 5) || 3132 (pScrn->weight.green != 6) || (pScrn->weight.blue != 5)) 3133 ret = TRUE; 3134 break; 3135 case 24: 3136 if ((pScrn->weight.red != 8) || 3137 (pScrn->weight.green != 8) || (pScrn->weight.blue != 8)) 3138 ret = TRUE; 3139 break; 3140 } 3141 if (ret) { 3142 XGIErrorLog(pScrn, 3143 "RGB weight %d%d%d at depth %d not supported by hardware\n", 3144 (int) pScrn->weight.red, 3145 (int) pScrn->weight.green, 3146 (int) pScrn->weight.blue, pScrn->depth); 3147 3148 if (pXGIEnt) 3149 pXGIEnt->ErrorAfterFirst = TRUE; 3150 3151 if (pXGI->pInt) 3152 xf86FreeInt10(pXGI->pInt); 3153 XGIFreeRec(pScrn); 3154 return FALSE; 3155 } 3156 } 3157 } 3158 3159 /* Set the current layout parameters */ 3160 pXGI->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; 3161 pXGI->CurrentLayout.depth = pScrn->depth; 3162 /* (Inside this function, we can use pScrn's contents anyway) */ 3163 3164 if (!xf86SetDefaultVisual(pScrn, -1)) { 3165 XGIErrorLog(pScrn, "xf86SetDefaultVisual() error\n"); 3166 3167 if (pXGIEnt) 3168 pXGIEnt->ErrorAfterFirst = TRUE; 3169 3170 if (pXGI->pInt) 3171 xf86FreeInt10(pXGI->pInt); 3172 XGIFreeRec(pScrn); 3173 return FALSE; 3174 } 3175 else { 3176 /* We don't support DirectColor at > 8bpp */ 3177 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 3178 XGIErrorLog(pScrn, 3179 "Given default visual (%s) is not supported at depth %d\n", 3180 xf86GetVisualName(pScrn->defaultVisual), 3181 pScrn->depth); 3182 3183 if (pXGIEnt) 3184 pXGIEnt->ErrorAfterFirst = TRUE; 3185 3186 if (pXGI->pInt) 3187 xf86FreeInt10(pXGI->pInt); 3188 XGIFreeRec(pScrn); 3189 return FALSE; 3190 } 3191 } 3192 3193 /* Due to palette & timing problems we don't support 8bpp in DHM */ 3194 if ((IS_DUAL_HEAD(pXGI)) && (pScrn->bitsPerPixel == 8)) { 3195 XGIErrorLog(pScrn, 3196 "Color depth 8 not supported in Dual Head mode.\n"); 3197 if (pXGIEnt) 3198 pXGIEnt->ErrorAfterFirst = TRUE; 3199 if (pXGI->pInt) 3200 xf86FreeInt10(pXGI->pInt); 3201 XGIFreeRec(pScrn); 3202 return FALSE; 3203 } 3204 3205 /* 3206 * The cmap layer needs this to be initialised. 3207 */ 3208 { 3209 Gamma zeros = { 0.0, 0.0, 0.0 }; 3210 /* Gamma zeros = { 0.5, 0.5, 0.5 }; */ 3211 3212 if (!xf86SetGamma(pScrn, zeros)) { 3213 XGIErrorLog(pScrn, "xf86SetGamma() error\n"); 3214 3215 if (pXGIEnt) 3216 pXGIEnt->ErrorAfterFirst = TRUE; 3217 3218 if (pXGI->pInt) 3219 xf86FreeInt10(pXGI->pInt); 3220 XGIFreeRec(pScrn); 3221 return FALSE; 3222 } 3223 } 3224 3225 /* We use a programamble clock */ 3226 pScrn->progClock = TRUE; 3227 3228 /* Set the bits per RGB for 8bpp mode */ 3229 if (pScrn->depth == 8) { 3230 pScrn->rgbBits = 6; 3231 } 3232 3233 from = X_DEFAULT; 3234 3235 /* Unlock registers */ 3236 xgiSaveUnlockExtRegisterLock(pXGI, &srlockReg, &crlockReg); 3237 3238 /* Read BIOS for 300 and 315/330 series customization */ 3239 pXGI->xgi_HwDevExt.pjVirtualRomBase = NULL; 3240 pXGI->BIOS = NULL; 3241 pXGI->xgi_HwDevExt.UseROM = FALSE; 3242 3243 /* Evaluate options */ 3244 xgiOptions(pScrn); 3245 3246#ifdef XGIMERGED 3247 /* Due to palette & timing problems we don't support 8bpp in MFBM */ 3248 if ((pXGI->MergedFB) && (pScrn->bitsPerPixel == 8)) { 3249 XGIErrorLog(pScrn, "MergedFB: Color depth 8 not supported, %s\n", 3250 mergeddisstr); 3251 pXGI->MergedFB = pXGI->MergedFBAuto = FALSE; 3252 } 3253#endif 3254 3255 /* Do basic configuration */ 3256 3257 XGISetup(pScrn); 3258 3259 from = X_PROBED; 3260#ifdef XSERVER_LIBPCIACCESS 3261 pXGI->FbAddress = pXGI->PciInfo->regions[0].base_addr & 0xFFFFFFF0; 3262#else 3263 if (pXGI->pEnt->device->MemBase != 0) { 3264 /* 3265 * XXX Should check that the config file value matches one of the 3266 * PCI base address values. 3267 */ 3268 pXGI->FbAddress = pXGI->pEnt->device->MemBase; 3269 from = X_CONFIG; 3270 } 3271 else { 3272 pXGI->FbAddress = pXGI->PciInfo->memBase[0] & 0xFFFFFFF0; 3273 } 3274#endif 3275 3276 pXGI->realFbAddress = pXGI->FbAddress; 3277 3278 xf86DrvMsg(pScrn->scrnIndex, from, 3279 "%sinear framebuffer at 0x%lX\n", 3280 IS_DUAL_HEAD(pXGI) ? "Global l" : "L", 3281 (unsigned long) pXGI->FbAddress); 3282 3283#ifdef XSERVER_LIBPCIACCESS 3284 pXGI->IOAddress = pXGI->PciInfo->regions[1].base_addr & 0xFFFFFFF0; 3285#else 3286 if (pXGI->pEnt->device->IOBase != 0) { 3287 /* 3288 * XXX Should check that the config file value matches one of the 3289 * PCI base address values. 3290 */ 3291 pXGI->IOAddress = pXGI->pEnt->device->IOBase; 3292 from = X_CONFIG; 3293 } 3294 else { 3295 pXGI->IOAddress = pXGI->PciInfo->memBase[1] & 0xFFFFFFF0; 3296 } 3297#endif 3298 3299 xf86DrvMsg(pScrn->scrnIndex, from, 3300 "MMIO registers at 0x%lX (size %ldK)\n", 3301 (unsigned long) pXGI->IOAddress, pXGI->mmioSize); 3302 pXGI->xgi_HwDevExt.bIntegratedMMEnabled = TRUE; 3303 3304#ifndef XSERVER_LIBPCIACCESS 3305 /* Register the PCI-assigned resources. */ 3306 if (xf86RegisterResources(pXGI->pEnt->index, NULL, ResExclusive)) { 3307 XGIErrorLog(pScrn, 3308 "xf86RegisterResources() found resource conflicts\n"); 3309 3310 if (pXGIEnt) 3311 pXGIEnt->ErrorAfterFirst = TRUE; 3312 3313 if (pXGI->pInt) 3314 xf86FreeInt10(pXGI->pInt); 3315 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 3316 XGIFreeRec(pScrn); 3317 return FALSE; 3318 } 3319#endif 3320 3321 from = X_PROBED; 3322 if (pXGI->pEnt->device->videoRam != 0) { 3323 3324 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3325 "Option \"VideoRAM\" ignored\n"); 3326 } 3327 3328 xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n", pScrn->videoRam); 3329 3330 pXGI->FbMapSize = pXGI->availMem = pScrn->videoRam * 1024; 3331 pXGI->xgi_HwDevExt.ulVideoMemorySize = pScrn->videoRam * 1024; 3332 pXGI->xgi_HwDevExt.bSkipDramSizing = TRUE; 3333 3334 /* Calculate real availMem according to Accel/TurboQueue and 3335 * HWCursur setting. 3336 * 3337 * TQ is max 64KiB. Reduce the available memory by 64KiB, and locate the 3338 * TQ at the beginning of this last 64KiB block. This is done even when 3339 * using the HWCursor, because the cursor only takes 2KiB and the queue 3340 * does not seem to last that far anyway. 3341 * 3342 * The TQ must be located at 32KB boundaries. 3343 */ 3344 if (pScrn->videoRam < 3072) { 3345 if (pXGI->TurboQueue) { 3346 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3347 "Not enough video RAM for TurboQueue. TurboQueue disabled\n"); 3348 pXGI->TurboQueue = FALSE; 3349 } 3350 } 3351 3352 pXGI->availMem -= (pXGI->TurboQueue) ? (64 * 1024) : pXGI->CursorSize; 3353 3354 3355 /* In dual head mode, we share availMem equally - so align it 3356 * to 8KB; this way, the address of the FB of the second 3357 * head is aligned to 4KB for mapping. 3358 * 3359 * Check MaxXFBMem setting. Since DRI is not supported in dual head 3360 * mode, we don't need the MaxXFBMem setting. 3361 */ 3362 if (IS_DUAL_HEAD(pXGI)) { 3363 if (pXGI->maxxfbmem) { 3364 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3365 "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n"); 3366 } 3367 3368 pXGI->availMem &= 0xFFFFE000; 3369 pXGI->maxxfbmem = pXGI->availMem; 3370 } 3371 else if (pXGI->maxxfbmem) { 3372 if (pXGI->maxxfbmem > pXGI->availMem) { 3373 if (pXGI->xgifbMem) { 3374 pXGI->maxxfbmem = pXGI->xgifbMem * 1024; 3375 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3376 "Invalid MaxXFBMem setting. Using xgifb heap start information\n"); 3377 } 3378 else { 3379 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3380 "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n"); 3381 pXGI->maxxfbmem = pXGI->availMem; 3382 } 3383 } 3384 else if (pXGI->xgifbMem) { 3385 if (pXGI->maxxfbmem > pXGI->xgifbMem * 1024) { 3386 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3387 "MaxXFBMem beyond xgifb heap start. Using xgifb heap start\n"); 3388 pXGI->maxxfbmem = pXGI->xgifbMem * 1024; 3389 } 3390 } 3391 } 3392 else if (pXGI->xgifbMem) { 3393 pXGI->maxxfbmem = pXGI->xgifbMem * 1024; 3394 } 3395 else 3396 pXGI->maxxfbmem = pXGI->availMem; 3397 3398 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n", 3399 pXGI->maxxfbmem / 1024); 3400 3401 pXGI->CRT1off = -1; 3402 3403 /* Detect video bridge and sense TV/VGA2 */ 3404 XGIVGAPreInit(pScrn); 3405 3406 /* Detect CRT1 (via DDC1 and DDC2, hence via VGA port; regardless of LCDA) */ 3407 XGICRT1PreInit(pScrn); 3408 3409 /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */ 3410 XGILCDPreInit(pScrn); 3411 3412 /* LCDA only supported under these conditions: */ 3413 if (pXGI->ForceCRT1Type == CRT1_LCDA) { 3414 if (! 3415 (pXGI->XGI_Pr-> 3416 VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV | 3417 VB_XGI302LV))) { 3418 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3419 "Chipset/Video bridge does not support LCD-via-CRT1\n"); 3420 pXGI->ForceCRT1Type = CRT1_VGA; 3421 } 3422 else if (!(pXGI->VBFlags & CRT2_LCD)) { 3423 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3424 "No digitally connected LCD panel found, LCD-via-CRT1 " 3425 "disabled\n"); 3426 pXGI->ForceCRT1Type = CRT1_VGA; 3427 } 3428 } 3429 3430 /* Setup SD flags */ 3431 pXGI->XGI_SD_Flags |= XGI_SD_ADDLSUPFLAG; 3432 3433 if (pXGI->XGI_Pr->VBType & VB_XGIVB) { 3434 pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTV; 3435 } 3436 3437#ifdef ENABLE_YPBPR 3438 if (pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B)) { 3439 pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTHIVISION; 3440 } 3441#endif 3442 3443#ifdef TWDEBUG /* @@@ TEST @@@ */ 3444 pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTYPBPRAR; 3445 xf86DrvMsg(0, X_INFO, "TEST: Support Aspect Ratio\n"); 3446#endif 3447 3448 /* Detect CRT2-TV and PAL/NTSC mode */ 3449 XGITVPreInit(pScrn); 3450 3451 /* Detect CRT2-VGA */ 3452 XGICRT2PreInit(pScrn); 3453 PDEBUG(ErrorF("3496 pXGI->VBFlags =%x\n", pXGI->VBFlags)); 3454 3455 if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR)) { 3456 if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_YPBPR)) { 3457 pXGI->ForceTVType = -1; 3458 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3459 "YPbPr TV output not supported\n"); 3460 } 3461 } 3462 3463 if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTHIVISION)) { 3464 if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_HIVISION)) { 3465 pXGI->ForceTVType = -1; 3466 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3467 "HiVision TV output not supported\n"); 3468 } 3469 } 3470 3471 if (pXGI->XGI_Pr->VBType & VB_XGIVB) { 3472 pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ); 3473 } 3474 if (pXGI->XGI_Pr->VBType & VB_XGIVB) { 3475 pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTVPOS; 3476 } 3477 if (pXGI->XGI_Pr-> 3478 VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)) { 3479 pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTSCART | XGI_SD_SUPPORTVGA2); 3480 } 3481 3482 if ((pXGI->XGI_Pr-> 3483 VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV | VB_XGI302LV)) 3484 && (pXGI->VBFlags & CRT2_LCD)) { 3485 pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTLCDA; 3486 } 3487 3488 pXGI->VBFlags |= pXGI->ForceCRT1Type; 3489 3490#ifdef TWDEBUG 3491 xf86DrvMsg(0, X_INFO, "SDFlags %lx\n", pXGI->XGI_SD_Flags); 3492#endif 3493 3494 3495 if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI)) { 3496 xf86DrvMsg(pScrn->scrnIndex, pXGI->CRT1gammaGiven ? X_CONFIG : X_INFO, 3497 "CRT1 gamma correction is %s\n", 3498 pXGI->CRT1gamma ? "enabled" : "disabled"); 3499 } 3500 3501 /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART, HIVISION, YPBPR) */ 3502 if (pXGI->XGI_Pr->VBType & VB_XGIVB) { 3503 if (pXGI->ForceTVType != -1) { 3504 pXGI->VBFlags &= ~(TV_INTERFACE); 3505 pXGI->VBFlags |= pXGI->ForceTVType; 3506 if (pXGI->VBFlags & TV_YPBPR) { 3507 pXGI->VBFlags &= ~(TV_STANDARD); 3508 pXGI->VBFlags &= ~(TV_YPBPRAR); 3509 pXGI->VBFlags |= pXGI->ForceYPbPrType; 3510 pXGI->VBFlags |= pXGI->ForceYPbPrAR; 3511 } 3512 } 3513 } 3514 3515 /* Check if CRT1 used or needed. There are three cases where this can 3516 * happen: 3517 * - No video bridge. 3518 * - No CRT2 output. 3519 * - Depth = 8 and bridge=LVDS|301B-DH 3520 * - LCDA 3521 */ 3522 if (((pXGI->XGI_Pr->VBType & VB_XGIVB) == 0) 3523 || ((pXGI->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)) == 0) 3524 || ((pScrn->bitsPerPixel == 8) 3525 && (pXGI->XGI_Pr->VBType & VB_XGI301LV302LV)) 3526 || (pXGI->VBFlags & CRT1_LCDA)) { 3527 pXGI->CRT1off = 0; 3528 } 3529 3530 3531 /* Handle TVStandard option */ 3532 if ((pXGI->NonDefaultPAL != -1) || (pXGI->NonDefaultNTSC != -1)) { 3533 if (!(pXGI->XGI_Pr->VBType & VB_XGIVB)) { 3534 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3535 "PALM, PALN and NTSCJ not supported on this hardware\n"); 3536 pXGI->NonDefaultPAL = pXGI->NonDefaultNTSC = -1; 3537 pXGI->VBFlags &= ~(TV_PALN | TV_PALM | TV_NTSCJ); 3538 pXGI->XGI_SD_Flags &= 3539 ~(XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ); 3540 } 3541 } 3542 3543#ifdef XGI_CP 3544 XGI_CP_DRIVER_RECONFIGOPT 3545#endif 3546 /* Do some MergedFB mode initialisation */ 3547#ifdef XGIMERGED 3548 if (pXGI->MergedFB) { 3549 pXGI->CRT2pScrn = xalloc(sizeof(ScrnInfoRec)); 3550 if (!pXGI->CRT2pScrn) { 3551 XGIErrorLog(pScrn, 3552 "Failed to allocate memory for 2nd pScrn, %s\n", 3553 mergeddisstr); 3554 pXGI->MergedFB = FALSE; 3555 } 3556 else { 3557 memcpy(pXGI->CRT2pScrn, pScrn, sizeof(ScrnInfoRec)); 3558 } 3559 } 3560#endif 3561 PDEBUG(ErrorF("3674 pXGI->VBFlags =%x\n", pXGI->VBFlags)); 3562 3563 /* Determine CRT1<>CRT2 mode 3564 * Note: When using VESA or if the bridge is in slavemode, display 3565 * is ALWAYS in MIRROR_MODE! 3566 * This requires extra checks in functions using this flag! 3567 * (see xgi_video.c for example) 3568 */ 3569 if (pXGI->VBFlags & DISPTYPE_DISP2) { 3570 if (pXGI->CRT1off) { /* CRT2 only ------------------------------- */ 3571 if (IS_DUAL_HEAD(pXGI)) { 3572 XGIErrorLog(pScrn, 3573 "CRT1 not detected or forced off. Dual Head mode can't initialize.\n"); 3574 if (pXGIEnt) 3575 pXGIEnt->DisableDual = TRUE; 3576 if (pXGIEnt) 3577 pXGIEnt->ErrorAfterFirst = TRUE; 3578 if (pXGI->pInt) 3579 xf86FreeInt10(pXGI->pInt); 3580 pXGI->pInt = NULL; 3581 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 3582 XGIFreeRec(pScrn); 3583 return FALSE; 3584 } 3585#ifdef XGIMERGED 3586 if (pXGI->MergedFB) { 3587 if (pXGI->MergedFBAuto) { 3588 xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt1, 3589 mergeddisstr); 3590 } 3591 else { 3592 XGIErrorLog(pScrn, mergednocrt1, mergeddisstr); 3593 } 3594 if (pXGI->CRT2pScrn) 3595 xfree(pXGI->CRT2pScrn); 3596 pXGI->CRT2pScrn = NULL; 3597 pXGI->MergedFB = FALSE; 3598 } 3599#endif 3600 pXGI->VBFlags |= VB_DISPMODE_SINGLE; 3601 } 3602 /* CRT1 and CRT2 - mirror or dual head ----- */ 3603 else if (IS_DUAL_HEAD(pXGI)) { 3604 pXGI->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1); 3605 if (pXGIEnt) 3606 pXGIEnt->DisableDual = FALSE; 3607 } 3608 else 3609 pXGI->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1); 3610 } 3611 else { /* CRT1 only ------------------------------- */ 3612 if (IS_DUAL_HEAD(pXGI)) { 3613 XGIErrorLog(pScrn, 3614 "No CRT2 output selected or no bridge detected. " 3615 "Dual Head mode can't initialize.\n"); 3616 if (pXGIEnt) 3617 pXGIEnt->ErrorAfterFirst = TRUE; 3618 if (pXGI->pInt) 3619 xf86FreeInt10(pXGI->pInt); 3620 pXGI->pInt = NULL; 3621 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 3622 XGIFreeRec(pScrn); 3623 return FALSE; 3624 } 3625 3626#ifdef XGIMERGED 3627 if (pXGI->MergedFB) { 3628 if (pXGI->MergedFBAuto) { 3629 xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt2, 3630 mergeddisstr); 3631 } 3632 else { 3633 XGIErrorLog(pScrn, mergednocrt2, mergeddisstr); 3634 } 3635 if (pXGI->CRT2pScrn) 3636 xfree(pXGI->CRT2pScrn); 3637 pXGI->CRT2pScrn = NULL; 3638 pXGI->MergedFB = FALSE; 3639 } 3640#endif 3641 PDEBUG(ErrorF("3782 pXGI->VBFlags =%x\n", pXGI->VBFlags)); 3642 pXGI->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1); 3643 } 3644 3645 /* Init Ptrs for Save/Restore functions and calc MaxClock */ 3646 XGIDACPreInit(pScrn); 3647 3648 /* ********** end of VBFlags setup ********** */ 3649 3650 /* VBFlags are initialized now. Back them up for SlaveMode modes. */ 3651 pXGI->VBFlags_backup = pXGI->VBFlags; 3652 3653 /* Find out about paneldelaycompensation and evaluate option */ 3654 if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) { 3655 3656 } 3657 3658 /* In dual head mode, both heads (currently) share the maxxfbmem equally. 3659 * If memory sharing is done differently, the following has to be changed; 3660 * the other modules (eg. accel and Xv) use dhmOffset for hardware 3661 * pointer settings relative to VideoRAM start and won't need to be changed. 3662 */ 3663 if (IS_DUAL_HEAD(pXGI)) { 3664 if (!IS_SECOND_HEAD(pXGI)) { 3665 /* ===== First head (always CRT2) ===== */ 3666 /* We use only half of the memory available */ 3667 pXGI->maxxfbmem /= 2; 3668 /* Initialize dhmOffset */ 3669 pXGI->dhmOffset = 0; 3670 /* Copy framebuffer addresses & sizes to entity */ 3671 pXGIEnt->masterFbAddress = pXGI->FbAddress; 3672 pXGIEnt->masterFbSize = pXGI->maxxfbmem; 3673 pXGIEnt->slaveFbAddress = pXGI->FbAddress + pXGI->maxxfbmem; 3674 pXGIEnt->slaveFbSize = pXGI->maxxfbmem; 3675 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3676 "%ldKB video RAM at 0x%lx available for master head (CRT2)\n", 3677 pXGI->maxxfbmem / 1024, pXGI->FbAddress); 3678 } 3679 else { 3680 /* ===== Second head (always CRT1) ===== */ 3681 /* We use only half of the memory available */ 3682 pXGI->maxxfbmem /= 2; 3683 /* Adapt FBAddress */ 3684 pXGI->FbAddress += pXGI->maxxfbmem; 3685 /* Initialize dhmOffset */ 3686 pXGI->dhmOffset = pXGI->availMem - pXGI->maxxfbmem; 3687 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3688 "%ldKB video RAM at 0x%lx available for slave head (CRT1)\n", 3689 pXGI->maxxfbmem / 1024, pXGI->FbAddress); 3690 } 3691 } 3692 else 3693 pXGI->dhmOffset = 0; 3694 3695 /* Note: Do not use availMem for anything from now. Use 3696 * maxxfbmem instead. (availMem does not take dual head 3697 * mode into account.) 3698 */ 3699 3700#if !defined(__arm__) 3701#if !defined(__powerpc__) 3702 /* Now load and initialize VBE module. */ 3703 if (xf86LoadSubModule(pScrn, "vbe")) { 3704#if 0 3705 xf86LoaderReqSymLists(vbeSymbols, NULL); 3706#endif 3707 pXGI->pVbe = VBEExtendedInit(pXGI->pInt, pXGI->pEnt->index, 3708 SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); 3709 if (!pXGI->pVbe) { 3710 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3711 "Could not initialize VBE module for DDC\n"); 3712 } 3713 } 3714 else { 3715 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3716 "Could not load VBE module\n"); 3717 } 3718 3719#endif 3720#endif 3721 3722 3723 XGIDDCPreInit(pScrn); 3724 3725 /* Jong 07/29/2009; Proposal : use wide range for HorizSync and strict range for VertRefresh; And set 1024x768 in Modes of Screen section */ 3726 /* Jong 07/17/2009; fix issue of only one mode (800x600) */ 3727 /* if (no Horizsync or VertRefresh is spefified in Monitor section) and (no DDC detection) */ 3728 /* then apply followings as default Hsync and VRefresh (1024x768x60HZ) */ 3729 /* XGIDDCPreInit() should be called first to get EDID but need I2C programming instead of VBIOS call */ 3730 if(pScrn->monitor->DDC == NULL) 3731 { 3732 ErrorF("Non-DDC minitor or NO EDID information...\n"); 3733 3734 if(pScrn->monitor->nHsync == 0) 3735 { 3736 pScrn->monitor->nHsync = 1; 3737 pScrn->monitor->hsync[0].lo=30; 3738 pScrn->monitor->hsync[0].hi=50; 3739 ErrorF("No HorizSync information set in Monitor section and use default (%g, %g)...\n", 3740 pScrn->monitor->hsync[0].lo, pScrn->monitor->hsync[0].hi); 3741 } 3742 3743 if(pScrn->monitor->nVrefresh == 0) 3744 { 3745 pScrn->monitor->nVrefresh = 1; 3746 pScrn->monitor->vrefresh[0].lo=40; 3747 pScrn->monitor->vrefresh[0].hi=60; 3748 ErrorF("No VertRefresh information set in Monitor section and use default (%g, %g)...\n", 3749 pScrn->monitor->vrefresh[0].lo, pScrn->monitor->vrefresh[0].hi); 3750 } 3751 } 3752 3753 /* From here, we mainly deal with clocks and modes */ 3754 3755 /* Set the min pixel clock */ 3756 pXGI->MinClock = 5000; 3757 3758 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", 3759 pXGI->MinClock / 1000); 3760 3761 from = X_PROBED; 3762 /* 3763 * If the user has specified ramdac speed in the XF86Config 3764 * file, we respect that setting. 3765 */ 3766 if (pXGI->pEnt->device->dacSpeeds[0]) { 3767 int speed = 0; 3768 switch (pScrn->bitsPerPixel) { 3769 case 8: 3770 speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP8]; 3771 break; 3772 case 16: 3773 speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP16]; 3774 break; 3775 case 24: 3776 speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP24]; 3777 break; 3778 case 32: 3779 speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP32]; 3780 break; 3781 } 3782 if (speed == 0) 3783 pXGI->MaxClock = pXGI->pEnt->device->dacSpeeds[0]; 3784 else 3785 pXGI->MaxClock = speed; 3786 from = X_CONFIG; 3787 } 3788 xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", 3789 pXGI->MaxClock / 1000); 3790 3791 /* 3792 * Setup the ClockRanges, which describe what clock ranges are available, 3793 * and what sort of modes they can be used for. 3794 */ 3795 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 3796 clockRanges->next = NULL; 3797 clockRanges->minClock = pXGI->MinClock; 3798 clockRanges->maxClock = pXGI->MaxClock; 3799 clockRanges->clockIndex = -1; /* programmable */ 3800 clockRanges->interlaceAllowed = TRUE; 3801 clockRanges->doubleScanAllowed = TRUE; 3802 3803 /* 3804 * xf86ValidateModes will check that the mode HTotal and VTotal values 3805 * don't exceed the chipset's limit if pScrn->maxHValue and 3806 * pScrn->maxVValue are set. Since our XGIValidMode() already takes 3807 * care of this, we don't worry about setting them here. 3808 */ 3809 3810 /* Select valid modes from those available */ 3811#ifdef XGIMERGED 3812 pXGI->CheckForCRT2 = FALSE; 3813#endif 3814 XGIDumpMonPtr(pScrn->monitor); 3815 3816 3817 XGIAddAvailableModes(pScrn->monitor->Modes); 3818 3819 /* XGIFilterModeByDDC(pScrn->monitor->Modes, g_pMonitorDVI); */ /* Do it in XGIValidMode() */ 3820 3821 ErrorF("Call xf86ValidateModes()...Use Virtual Size-1-Virtual Size=%d\n", pScrn->display->virtualX); 3822 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, 2048, /* min / max pitch */ 3823 pScrn->bitsPerPixel * 8, 128, 2048, /* min / max height */ 3824 pScrn->display->virtualX, 3825 pScrn->display->virtualY, 3826 pXGI->maxxfbmem, LOOKUP_BEST_REFRESH); 3827 3828 if (i == -1) { 3829 XGIErrorLog(pScrn, "xf86ValidateModes() error\n"); 3830 3831 if (pXGIEnt) 3832 pXGIEnt->ErrorAfterFirst = TRUE; 3833 3834 if (pXGI->pInt) 3835 xf86FreeInt10(pXGI->pInt); 3836 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 3837 XGIFreeRec(pScrn); 3838 return FALSE; 3839 } 3840 3841 /* Check the virtual screen against the available memory */ 3842 3843 memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8)) 3844 * pScrn->virtualY; 3845 3846 if (memreq > pXGI->maxxfbmem) { 3847 XGIErrorLog(pScrn, 3848 "Virtual screen too big for memory; %ldK needed, %ldK available\n", 3849 memreq / 1024, pXGI->maxxfbmem / 1024); 3850 3851 if (pXGIEnt) 3852 pXGIEnt->ErrorAfterFirst = TRUE; 3853 3854 if (pXGI->pInt) 3855 xf86FreeInt10(pXGI->pInt); 3856 pXGI->pInt = NULL; 3857 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 3858 XGIFreeRec(pScrn); 3859 return FALSE; 3860 } 3861 else if (pXGI->loadDRI && !IS_DUAL_HEAD(pXGI)) 3862 { 3863 pXGI->maxxfbmem = memreq; 3864 pXGI->DRIheapstart = pXGI->DRIheapend = 0; 3865 3866 if (pXGI->maxxfbmem == pXGI->availMem) { 3867 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3868 "All video memory used for framebuffer. DRI will be disabled.\n"); 3869 pXGI->loadDRI = FALSE; 3870 } 3871 else { 3872 pXGI->DRIheapstart = pXGI->maxxfbmem; 3873 pXGI->DRIheapend = pXGI->availMem; 3874 } 3875 } 3876 3877 3878 /* Dual Head: 3879 * -) Go through mode list and mark all those modes as bad, 3880 * which are unsuitable for dual head mode. 3881 * -) Find the highest used pixelclock on the master head. 3882 */ 3883 if (IS_DUAL_HEAD(pXGI) && !IS_SECOND_HEAD(pXGI)) 3884 { 3885 pXGIEnt->maxUsedClock = 0; 3886 3887 if ((p = first = pScrn->modes)) 3888 { 3889 do { 3890 n = p->next; 3891 3892 /* Modes that require the bridge to operate in SlaveMode 3893 * are not suitable for Dual Head mode. 3894 */ 3895 3896 /* Search for the highest clock on first head in order to calculate 3897 * max clock for second head (CRT1) 3898 */ 3899 if ((p->status == MODE_OK) 3900 && (p->Clock > pXGIEnt->maxUsedClock)) { 3901 pXGIEnt->maxUsedClock = p->Clock; 3902 } 3903 3904 p = n; 3905 3906 } while (p != NULL && p != first); 3907 } 3908 } 3909 3910 /* Prune the modes marked as invalid */ 3911 xf86PruneDriverModes(pScrn); 3912 3913 if (i == 0 || pScrn->modes == NULL) { 3914 XGIErrorLog(pScrn, "No valid modes found\n"); 3915 3916 if (pXGIEnt) 3917 pXGIEnt->ErrorAfterFirst = TRUE; 3918 3919 if (pXGI->pInt) 3920 xf86FreeInt10(pXGI->pInt); 3921 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 3922 XGIFreeRec(pScrn); 3923 return FALSE; 3924 } 3925 3926 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 3927 3928 /* Set the current mode to the first in the list */ 3929 pScrn->currentMode = pScrn->modes; 3930 3931 /* Copy to CurrentLayout */ 3932 pXGI->CurrentLayout.mode = pScrn->currentMode; 3933 pXGI->CurrentLayout.displayWidth = pScrn->displayWidth; 3934 3935#ifdef XGIMERGED 3936 if (pXGI->MergedFB) { 3937 xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 1); 3938 } 3939#endif 3940 3941 /* Print the list of modes being used ; call xf86Mode.c-xf86PrintModeline() to print */ 3942 ErrorF("Call xf86PrintModes(pScrn) to list all valid modes...\n"); 3943 xf86PrintModes(pScrn); 3944 3945#ifdef XGIMERGED 3946 if (pXGI->MergedFB) { 3947 BOOLEAN acceptcustommodes = TRUE; 3948 BOOLEAN includelcdmodes = TRUE; 3949 BOOLEAN isfordvi = FALSE; 3950 3951 xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 2); 3952 3953 clockRanges->next = NULL; 3954 clockRanges->minClock = pXGI->MinClock; 3955 clockRanges->clockIndex = -1; 3956 clockRanges->interlaceAllowed = FALSE; 3957 clockRanges->doubleScanAllowed = FALSE; 3958 3959 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, 3960 "Min pixel clock for CRT2 is %d MHz\n", 3961 clockRanges->minClock / 1000); 3962 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, 3963 "Max pixel clock for CRT2 is %d MHz\n", 3964 clockRanges->maxClock / 1000); 3965 3966 if ((pXGI->XGI_Pr-> 3967 VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B))) 3968 { 3969 if (!(pXGI->VBFlags & (CRT2_LCD | CRT2_VGA))) 3970 includelcdmodes = FALSE; 3971 if (pXGI->VBFlags & CRT2_LCD) 3972 isfordvi = TRUE; 3973 if (pXGI->VBFlags & CRT2_TV) 3974 acceptcustommodes = FALSE; 3975 } 3976 else { 3977 includelcdmodes = FALSE; 3978 acceptcustommodes = FALSE; 3979 } 3980 } 3981 3982 if (pXGI->MergedFB) { 3983 3984 pXGI->CheckForCRT2 = TRUE; 3985 i = xf86ValidateModes(pXGI->CRT2pScrn, 3986 pXGI->CRT2pScrn->monitor->Modes, 3987 pXGI->CRT2pScrn->display->modes, clockRanges, 3988 NULL, 256, 4088, 3989 pXGI->CRT2pScrn->bitsPerPixel * 8, 128, 4096, 3990 pScrn->display->virtualX ? pScrn->virtualX : 0, 3991 pScrn->display->virtualY ? pScrn->virtualY : 0, 3992 pXGI->maxxfbmem, LOOKUP_BEST_REFRESH); 3993 pXGI->CheckForCRT2 = FALSE; 3994 3995 if (i == -1) { 3996 XGIErrorLog(pScrn, "xf86ValidateModes() error, %s.\n", 3997 mergeddisstr); 3998 XGIFreeCRT2Structs(pXGI); 3999 pXGI->MergedFB = FALSE; 4000 } 4001 4002 } 4003 4004 if (pXGI->MergedFB) { 4005 4006 if ((p = first = pXGI->CRT2pScrn->modes)) { 4007 do { 4008 n = p->next; 4009 p = n; 4010 } while (p != NULL && p != first); 4011 } 4012 4013 xf86PruneDriverModes(pXGI->CRT2pScrn); 4014 4015 if (i == 0 || pXGI->CRT2pScrn->modes == NULL) { 4016 XGIErrorLog(pScrn, "No valid modes found for CRT2; %s\n", 4017 mergeddisstr); 4018 XGIFreeCRT2Structs(pXGI); 4019 pXGI->MergedFB = FALSE; 4020 } 4021 4022 } 4023 4024 if (pXGI->MergedFB) { 4025 4026 xf86SetCrtcForModes(pXGI->CRT2pScrn, INTERLACE_HALVE_V); 4027 4028 xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 2); 4029 4030 xf86PrintModes(pXGI->CRT2pScrn); 4031 4032 pXGI->CRT1Modes = pScrn->modes; 4033 pXGI->CRT1CurrentMode = pScrn->currentMode; 4034 4035 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4036 "Generating MergedFB mode list\n"); 4037 4038 pScrn->modes = XGIGenerateModeList(pScrn, pXGI->MetaModes, 4039 pXGI->CRT1Modes, 4040 pXGI->CRT2pScrn->modes, 4041 pXGI->CRT2Position); 4042 4043 if (!pScrn->modes) { 4044 4045 XGIErrorLog(pScrn, 4046 "Failed to parse MetaModes or no modes found. %s.\n", 4047 mergeddisstr); 4048 XGIFreeCRT2Structs(pXGI); 4049 pScrn->modes = pXGI->CRT1Modes; 4050 pXGI->CRT1Modes = NULL; 4051 pXGI->MergedFB = FALSE; 4052 4053 } 4054 4055 } 4056 4057 if (pXGI->MergedFB) { 4058 4059 /* If no virtual dimension was given by the user, 4060 * calculate a sane one now. Adapts pScrn->virtualX, 4061 * pScrn->virtualY and pScrn->displayWidth. 4062 */ 4063 XGIRecalcDefaultVirtualSize(pScrn); 4064 4065 pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */ 4066 pScrn->currentMode = pScrn->modes; 4067 4068 /* Update CurrentLayout */ 4069 pXGI->CurrentLayout.mode = pScrn->currentMode; 4070 pXGI->CurrentLayout.displayWidth = pScrn->displayWidth; 4071 4072 } 4073#endif 4074 4075 /* Set display resolution */ 4076#ifdef XGIMERGED 4077 if (pXGI->MergedFB) { 4078 XGIMergedFBSetDpi(pScrn, pXGI->CRT2pScrn, pXGI->CRT2Position); 4079 } 4080 else 4081#endif 4082 4083 4084 /* Jong 07/30/2009; might cause small font size */ 4085 xf86SetDpi(pScrn, 0, 0); 4086 4087#if 0 4088 /*yilin@20080407 fix the font too small problem at low resolution*/ 4089 if((pScrn->xDpi < 65)||(pScrn->yDpi < 65)) 4090 { 4091 pScrn->xDpi = 75; 4092 pScrn->yDpi = 75; 4093 } 4094#endif 4095 4096 /* Load fb module */ 4097 switch (pScrn->bitsPerPixel) { 4098 case 8: 4099 case 16: 4100 case 24: 4101 case 32: 4102 if (!xf86LoadSubModule(pScrn, "fb")) { 4103 XGIErrorLog(pScrn, "Failed to load fb module"); 4104 4105 if (pXGIEnt) 4106 pXGIEnt->ErrorAfterFirst = TRUE; 4107 4108 if (pXGI->pInt) 4109 xf86FreeInt10(pXGI->pInt); 4110 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 4111 XGIFreeRec(pScrn); 4112 return FALSE; 4113 } 4114 break; 4115 default: 4116 XGIErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n", 4117 pScrn->bitsPerPixel); 4118 4119 if (pXGIEnt) 4120 pXGIEnt->ErrorAfterFirst = TRUE; 4121 4122 if (pXGI->pInt) 4123 xf86FreeInt10(pXGI->pInt); 4124 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 4125 XGIFreeRec(pScrn); 4126 return FALSE; 4127 } 4128#if 0 4129 xf86LoaderReqSymLists(fbSymbols, NULL); 4130#endif 4131 /* Load XAA if needed */ 4132 if (!pXGI->NoAccel) 4133 { 4134 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n"); 4135 4136#ifdef XGI_USE_XAA 4137 if(!(pXGI->useEXA)) 4138 { 4139 if (!xf86LoadSubModule(pScrn, "xaa")) { 4140 XGIErrorLog(pScrn, "Could not load xaa module\n"); 4141 4142 if (pXGIEnt) 4143 pXGIEnt->ErrorAfterFirst = TRUE; 4144 4145 if (pXGI->pInt) 4146 xf86FreeInt10(pXGI->pInt); 4147 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 4148 XGIFreeRec(pScrn); 4149 return FALSE; 4150 } 4151#if 0 4152 xf86LoaderReqSymLists(xaaSymbols, NULL); 4153#endif 4154 } 4155#endif 4156 4157#ifdef XGI_USE_EXA 4158 if(pXGI->useEXA) 4159 { 4160 if(!xf86LoadSubModule(pScrn, "exa")) { 4161 XGIErrorLog(pScrn, "Could not load exa module\n"); 4162 return FALSE; 4163 } 4164#if 0 4165 xf86LoaderReqSymLists(exaSymbols, NULL); 4166#endif 4167 } 4168#endif 4169 } 4170 4171 /* Load shadowfb if needed */ 4172 if (pXGI->ShadowFB) { 4173 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 4174 XGIErrorLog(pScrn, "Could not load shadowfb module\n"); 4175 4176 if (pXGIEnt) 4177 pXGIEnt->ErrorAfterFirst = TRUE; 4178 4179 if (pXGI->pInt) 4180 xf86FreeInt10(pXGI->pInt); 4181 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 4182 XGIFreeRec(pScrn); 4183 return FALSE; 4184 } 4185#if 0 4186 xf86LoaderReqSymLists(shadowSymbols, NULL); 4187#endif 4188 } 4189 4190 /* Load the dri module if requested. */ 4191#ifdef XF86DRI 4192 if(pXGI->loadDRI) { 4193 if (xf86LoadSubModule(pScrn, "dri")) { 4194#if 0 4195 xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL); 4196#endif 4197 } 4198 else { 4199 if (!IS_DUAL_HEAD(pXGI)) 4200 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4201 "Remove >Load \"dri\"< from the Module section of your XF86Config file\n"); 4202 } 4203 } 4204#endif 4205 4206 4207 /* Now load and initialize VBE module for VESA and mode restoring. */ 4208 if (pXGI->pVbe) { 4209 vbeFree(pXGI->pVbe); 4210 pXGI->pVbe = NULL; 4211 } 4212 4213#ifdef XGIDUALHEAD 4214 xf86SetPrimInitDone(pScrn->entityList[0]); 4215#endif 4216 4217 xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg); 4218 4219 if (pXGI->pInt) 4220 xf86FreeInt10(pXGI->pInt); 4221 pXGI->pInt = NULL; 4222 4223 if (IS_DUAL_HEAD(pXGI)) { 4224 pXGI->XGI_SD_Flags |= XGI_SD_ISDUALHEAD; 4225 if (IS_SECOND_HEAD(pXGI)) 4226 pXGI->XGI_SD_Flags |= XGI_SD_ISDHSECONDHEAD; 4227 else 4228 pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1); 4229#ifdef PANORAMIX 4230 if (!noPanoramiXExtension) { 4231 pXGI->XGI_SD_Flags |= XGI_SD_ISDHXINERAMA; 4232 pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1); 4233 } 4234#endif 4235 } 4236 4237#ifdef XGIMERGED 4238 if (pXGI->MergedFB) 4239 pXGI->XGI_SD_Flags |= XGI_SD_ISMERGEDFB; 4240#endif 4241 4242 if (pXGI->enablexgictrl) 4243 pXGI->XGI_SD_Flags |= XGI_SD_ENABLED; 4244 4245 return TRUE; 4246} 4247 4248 4249/* 4250 * Map the framebuffer and MMIO memory. 4251 */ 4252 4253static Bool 4254XGIMapMem(ScrnInfoPtr pScrn) 4255{ 4256 XGIPtr pXGI = XGIPTR(pScrn);; 4257 4258#ifdef XSERVER_LIBPCIACCESS 4259 unsigned i; 4260 4261 for (i = 0; i < 2; i++) { 4262 int err; 4263 4264 err = pci_device_map_region(pXGI->PciInfo, i, TRUE); 4265 if (err) { 4266 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4267 "Internal error: cound not map PCI region %u\n", i); 4268 return FALSE; 4269 } 4270 } 4271 4272 pXGI->FbBase = pXGI->PciInfo->regions[0].memory; 4273 pXGI->IOBase = pXGI->PciInfo->regions[1].memory; 4274#else 4275 int mmioFlags; 4276 4277 /* 4278 * Map IO registers to virtual address space 4279 */ 4280#if !defined(__alpha__) 4281 mmioFlags = VIDMEM_MMIO; 4282#else 4283 /* 4284 * For Alpha, we need to map SPARSE memory, since we need 4285 * byte/short access. 4286 */ 4287 mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE; 4288#endif 4289 pXGI->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, 4290 pXGI->PciTag, pXGI->IOAddress, 0x10000); 4291 if (pXGI->IOBase == NULL) 4292 return FALSE; 4293 4294#ifdef __alpha__ 4295 /* 4296 * for Alpha, we need to map DENSE memory as well, for 4297 * setting CPUToScreenColorExpandBase. 4298 */ 4299 pXGI->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, 4300 pXGI->PciTag, pXGI->IOAddress, 0x10000); 4301 4302 if (pXGI->IOBaseDense == NULL) 4303 return FALSE; 4304#endif /* __alpha__ */ 4305 4306 pXGI->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 4307 pXGI->PciTag, 4308 (unsigned long) pXGI->FbAddress, 4309 pXGI->FbMapSize); 4310 4311 PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n", (ULONG) (pXGI->FbBase))); 4312 4313 if (pXGI->FbBase == NULL) 4314 return FALSE; 4315#endif 4316 4317 return TRUE; 4318} 4319 4320 4321/* 4322 * Unmap the framebuffer and MMIO memory. 4323 */ 4324 4325static Bool 4326XGIUnmapMem(ScrnInfoPtr pScrn) 4327{ 4328 XGIPtr pXGI = XGIPTR(pScrn); 4329 XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI); 4330 4331 4332 /* In dual head mode, we must not unmap if the other head still 4333 * assumes memory as mapped 4334 */ 4335 if (IS_DUAL_HEAD(pXGI)) { 4336 if (pXGIEnt->MapCountIOBase) { 4337 pXGIEnt->MapCountIOBase--; 4338 if ((pXGIEnt->MapCountIOBase == 0) || (pXGIEnt->forceUnmapIOBase)) { 4339#ifdef XSERVER_LIBPCIACCESS 4340 pci_device_unmap_region(pXGI->PciInfo, 1); 4341#else 4342 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->IOBase, 4343 (pXGI->mmioSize * 1024)); 4344#endif 4345 pXGIEnt->IOBase = NULL; 4346 pXGIEnt->MapCountIOBase = 0; 4347 pXGIEnt->forceUnmapIOBase = FALSE; 4348 } 4349 pXGI->IOBase = NULL; 4350 } 4351#ifdef __alpha__ 4352#ifdef XSERVER_LIBPCIACCESS 4353#error "How to do dense mapping on Alpha?" 4354#else 4355 if (pXGIEnt->MapCountIOBaseDense) { 4356 pXGIEnt->MapCountIOBaseDense--; 4357 if ((pXGIEnt->MapCountIOBaseDense == 0) 4358 || (pXGIEnt->forceUnmapIOBaseDense)) { 4359 xf86UnMapVidMem(pScrn->scrnIndex, 4360 (pointer) pXGIEnt->IOBaseDense, 4361 (pXGI->mmioSize * 1024)); 4362 pXGIEnt->IOBaseDense = NULL; 4363 pXGIEnt->MapCountIOBaseDense = 0; 4364 pXGIEnt->forceUnmapIOBaseDense = FALSE; 4365 } 4366 pXGI->IOBaseDense = NULL; 4367 } 4368#endif 4369#endif /* __alpha__ */ 4370 if (pXGIEnt->MapCountFbBase) { 4371 pXGIEnt->MapCountFbBase--; 4372 if ((pXGIEnt->MapCountFbBase == 0) || (pXGIEnt->forceUnmapFbBase)) { 4373#ifdef XSERVER_LIBPCIACCESS 4374 pci_device_unmap_region(pXGI->PciInfo, 0); 4375#else 4376 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->FbBase, 4377 pXGI->FbMapSize); 4378#endif 4379 pXGIEnt->FbBase = NULL; 4380 pXGIEnt->MapCountFbBase = 0; 4381 pXGIEnt->forceUnmapFbBase = FALSE; 4382 4383 } 4384 pXGI->FbBase = NULL; 4385 } 4386 } 4387 else { 4388#ifdef XSERVER_LIBPCIACCESS 4389 pci_device_unmap_region(pXGI->PciInfo, 0); 4390 pci_device_unmap_region(pXGI->PciInfo, 1); 4391#else 4392 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBase, 4393 (pXGI->mmioSize * 1024)); 4394 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->FbBase, 4395 pXGI->FbMapSize); 4396#endif 4397 pXGI->IOBase = NULL; 4398 pXGI->FbBase = NULL; 4399 4400#ifdef __alpha__ 4401#ifdef XSERVER_LIBPCIACCESS 4402#error "How to do dense mapping on Alpha?" 4403#else 4404 xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBaseDense, 4405 (pXGI->mmioSize * 1024)); 4406 pXGI->IOBaseDense = NULL; 4407#endif 4408#endif 4409 } 4410 4411 return TRUE; 4412} 4413 4414/* 4415 * This function saves the video state. 4416 */ 4417static void 4418XGISave(ScrnInfoPtr pScrn) 4419{ 4420 XGIPtr pXGI; 4421 vgaRegPtr vgaReg; 4422 XGIRegPtr xgiReg; 4423 4424 PDEBUG(ErrorF("XGISave()\n")); 4425 4426 pXGI = XGIPTR(pScrn); 4427 4428 /* We always save master & slave */ 4429 if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI)) 4430 return; 4431 4432 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 4433 xgiReg = &pXGI->SavedReg; 4434 4435 vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); 4436 4437 xgiSaveUnlockExtRegisterLock(pXGI, &xgiReg->xgiRegs3C4[0x05], 4438 &xgiReg->xgiRegs3D4[0x80]); 4439 4440 (*pXGI->XGISave) (pScrn, xgiReg); 4441 4442 /* "Save" these again as they may have been changed prior to XGISave() call */ 4443} 4444 4445 4446/* 4447 * Initialise a new mode. This is currently done using the 4448 * "initialise struct, restore/write struct to HW" model for 4449 * the old chipsets (5597/530/6326). For newer chipsets, 4450 * we use our own mode switching code (or VESA). 4451 */ 4452 4453static Bool 4454XGIModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 4455{ 4456 vgaHWPtr hwp = VGAHWPTR(pScrn); 4457 vgaRegPtr vgaReg; 4458 XGIPtr pXGI = XGIPTR(pScrn); 4459 XGIRegPtr xgiReg; 4460#ifdef __powerpc__ 4461 unsigned char tmpval; 4462#endif 4463 4464 PDEBUG(ErrorF("XGIModeInit\n")); 4465 PDEBUG(ErrorF("mode->HDisplay = %d\n", mode->HDisplay)); 4466 PDEBUG(ErrorF("mode->VDisplay = %d\n", mode->VDisplay)); 4467 4468 PDEBUG(ErrorF("Before update...\n")); 4469 PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX)); 4470 PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY)); 4471 PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth)); 4472 PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0)); 4473 PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0)); 4474 PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1)); 4475 PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1)); 4476 4477 /* pScrn->displayWidth=mode->HDisplay; */ 4478 4479 if(pXGI->TargetRefreshRate) 4480 mode->VRefresh = pXGI->TargetRefreshRate; 4481 4482 if((pScrn->monitor->DDC == NULL) && (pXGI->Non_DDC_DefaultMode)) 4483 { 4484 mode->HDisplay = pXGI->Non_DDC_DefaultResolutionX; 4485 mode->VDisplay = pXGI->Non_DDC_DefaultResolutionY; 4486 mode->VRefresh = pXGI->Non_DDC_DefaultRefreshRate; 4487 } 4488 4489 /* PDEBUG(ErrorF("XGIModeInit(). \n")); */ 4490 PDEBUG(ErrorF 4491 ("XGIModeInit Resolution (%d, %d) \n", mode->HDisplay, 4492 mode->VDisplay)); 4493 PDEBUG(ErrorF("XGIModeInit VVRefresh (%8.3f) \n", mode->VRefresh)); 4494 PDEBUG(ErrorF("XGIModeInit Color Depth (%d) \n", pScrn->depth)); 4495 4496 /* Jong Lin 08-26-2005; save current mode */ 4497 Volari_SetDefaultIdleWait(pXGI, mode->HDisplay, pScrn->depth); 4498 4499 andXGIIDXREG(XGICR, 0x11, 0x7f); /* Unlock CRTC registers */ 4500 4501 XGIModifyModeInfo(mode); /* Quick check of the mode parameters */ 4502 4503 4504 if (IS_DUAL_HEAD(pXGI)) 4505 { 4506 XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI); 4507 4508 if (!(*pXGI->ModeInit) (pScrn, mode)) { 4509 XGIErrorLog(pScrn, "ModeInit() failed\n"); 4510 return FALSE; 4511 } 4512 4513 pScrn->vtSema = TRUE; 4514 4515 /* Head 2 (slave) is always CRT1 */ 4516 XGIPreSetMode(pScrn, mode, XGI_MODE_CRT1); 4517 if (!XGIBIOSSetModeCRT1(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn, 4518 mode)) 4519 { 4520 XGIErrorLog(pScrn, "XGIBIOSSetModeCRT1() failed\n"); 4521 return FALSE; 4522 } 4523 4524 XGIPostSetMode(pScrn, &pXGI->ModeReg); 4525 XGIAdjustFrame(pXGIEnt->pScrn_1->scrnIndex, pXGIEnt->pScrn_1->frameX0, 4526 pXGIEnt->pScrn_1->frameY0, 0); 4527 } 4528 else 4529 { 4530 /* For other chipsets, use the old method */ 4531 4532 /* Initialise the ModeReg values */ 4533 if (!vgaHWInit(pScrn, mode)) { 4534 XGIErrorLog(pScrn, "vgaHWInit() failed\n"); 4535 return FALSE; 4536 } 4537 4538 /* Reset our PIOOffset as vgaHWInit might have reset it */ 4539 VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 + 4540#ifdef XSERVER_LIBPCIACCESS 4541 (pXGI->PciInfo->regions[2].base_addr & 0xFFFC) 4542#else 4543 (pXGI->PciInfo->ioBase[2] & 0xFFFC) 4544#endif 4545 ; 4546 4547 /* Prepare the register contents */ 4548 if (!(*pXGI->ModeInit) (pScrn, mode)) { 4549 XGIErrorLog(pScrn, "ModeInit() failed\n"); 4550 return FALSE; 4551 } 4552 4553 pScrn->vtSema = TRUE; 4554 4555 /* Program the registers */ 4556 vgaHWProtect(pScrn, TRUE); 4557 vgaReg = &hwp->ModeReg; 4558 xgiReg = &pXGI->ModeReg; 4559 4560 vgaReg->Attribute[0x10] = 0x01; 4561 if (pScrn->bitsPerPixel > 8) { 4562 vgaReg->Graphics[0x05] = 0x00; 4563 } 4564 4565 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 4566 4567 (*pXGI->XGIRestore) (pScrn, xgiReg); 4568 4569#ifdef TWDEBUG 4570 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4571 "REAL REGISTER CONTENTS AFTER SETMODE:\n"); 4572 (*pXGI->ModeInit) (pScrn, mode); 4573#endif 4574 4575 vgaHWProtect(pScrn, FALSE); 4576 } 4577 4578 4579 if((pXGI->Chipset == PCI_CHIP_XGIXG40)||(pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27)) 4580 { 4581 /* PDEBUG(XGIDumpRegs(pScrn)) ; */ 4582 PDEBUG(ErrorF(" *** PreSetMode(). \n")); 4583 XGIPreSetMode(pScrn, mode, XGI_MODE_SIMU); 4584 /* PDEBUG(XGIDumpRegs(pScrn)) ; */ 4585 PDEBUG(ErrorF(" *** Start SetMode() \n")); 4586 4587 if (!XGIBIOSSetMode(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn, mode)) { 4588 XGIErrorLog(pScrn, "XGIBIOSSetModeCRT() failed\n"); 4589 return FALSE; 4590 } 4591 Volari_EnableAccelerator(pScrn); 4592 /* XGIPostSetMode(pScrn, &pXGI->ModeReg); */ 4593 /* outXGIIDXREG(XGISR, 0x20, 0xA1) ; */ 4594 /* PDEBUG(XGIDumpRegs(pScrn)) ; */ 4595 } 4596 4597 /* Update Currentlayout */ 4598 pXGI->CurrentLayout.mode = mode; 4599 4600#ifdef __powerpc__ 4601 inXGIIDXREG(XGICR, 0x4D, tmpval); 4602 if (pScrn->depth == 16) 4603 tmpval = (tmpval & 0xE0) | 0x0B; //word swap 4604 else if (pScrn->depth == 24) 4605 tmpval = (tmpval & 0xE0) | 0x15; //dword swap 4606 else 4607 tmpval = tmpval & 0xE0; // no swap 4608 4609 outXGIIDXREG(XGICR, 0x4D, tmpval); 4610#endif 4611 4612 XGISetDPMS(pScrn, pXGI->XGI_Pr, &pXGI->xgi_HwDevExt , 0x00000000 ); 4613 4614 return TRUE; 4615} 4616 4617 4618/* 4619 * Restore the initial mode. To be used internally only! 4620 */ 4621static void 4622XGIRestore(ScrnInfoPtr pScrn) 4623{ 4624 XGIPtr pXGI = XGIPTR(pScrn); 4625 XGIRegPtr xgiReg = &pXGI->SavedReg; 4626 vgaHWPtr hwp = VGAHWPTR(pScrn); 4627 vgaRegPtr vgaReg = &hwp->SavedReg; 4628 4629 4630 PDEBUG(ErrorF("XGIRestore():\n")); 4631 4632 /* Wait for the accelerators */ 4633#ifdef XGI_USE_XAA 4634 if (!(pXGI->useEXA) && pXGI->AccelInfoPtr) { 4635 (*pXGI->AccelInfoPtr->Sync) (pScrn); 4636 } 4637#endif 4638 4639 vgaHWProtect(pScrn, TRUE); 4640 4641#ifdef UNLOCK_ALWAYS 4642 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); 4643#endif 4644 4645 /* Volari_DisableCmdQueue(pScrn) ; */ 4646 4647 /* Volari_Restore() */ 4648 (*pXGI->XGIRestore) (pScrn, xgiReg); 4649 4650 pXGI->xgi_HwDevExt.SpecifyTiming = FALSE; 4651 4652 /* Jong 11/14/2007; resolve no display of DVI after leaving VT */ 4653 /* But there's no int10 for PPC... */ 4654 /* XGIRestorePrevMode(pScrn) ; */ 4655 /* works but mode is not exactly right because there're more than one mode 0x03 in table XGI330_SModeIDTable[] */ 4656 XGISetModeNew( &pXGI->xgi_HwDevExt, pXGI->XGI_Pr, 0x03); 4657 4658 vgaHWProtect(pScrn, TRUE); 4659 if (pXGI->Primary) { 4660 vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); 4661 } 4662 4663 xgiRestoreExtRegisterLock(pXGI, xgiReg->xgiRegs3C4[5], 4664 xgiReg->xgiRegs3D4[0x80]); 4665 vgaHWProtect(pScrn, FALSE); 4666} 4667 4668 4669/* Our generic BlockHandler for Xv */ 4670static void 4671XGIBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) 4672{ 4673 ScreenPtr pScreen = screenInfo.screens[i]; 4674 ScrnInfoPtr pScrn = xf86Screens[i]; 4675 XGIPtr pXGI = XGIPTR(pScrn); 4676 4677 pScreen->BlockHandler = pXGI->BlockHandler; 4678 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 4679 pScreen->BlockHandler = XGIBlockHandler; 4680 4681 if (pXGI->VideoTimerCallback) { 4682 (*pXGI->VideoTimerCallback) (pScrn, currentTime.milliseconds); 4683 } 4684 4685 if (pXGI->RenderCallback) { 4686 (*pXGI->RenderCallback) (pScrn); 4687 } 4688} 4689 4690/* Jong@08122009 */ 4691int g_virtualX; 4692int g_virtualY; 4693int g_frameX0; 4694int g_frameY0; 4695int g_frameX1; 4696int g_frameY1; 4697 4698void xgiRestoreVirtual(ScrnInfoPtr pScrn) 4699{ 4700 pScrn->virtualX = g_virtualX; 4701 pScrn->virtualY = g_virtualY; 4702 pScrn->frameX0 = g_frameX0; 4703 pScrn->frameY0 = g_frameY0; 4704 pScrn->frameX1 = g_frameX1; 4705 pScrn->frameY1 = g_frameY1; 4706} 4707 4708/* Mandatory 4709 * This gets called at the start of each server generation 4710 * 4711 * We use pScrn and not CurrentLayout here, because the 4712 * properties we use have not changed (displayWidth, 4713 * depth, bitsPerPixel) 4714 * 4715 * pScrn->displayWidth : memory pitch 4716 */ 4717static Bool 4718XGIScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 4719{ 4720 ScrnInfoPtr pScrn; 4721 vgaHWPtr hwp; 4722 XGIPtr pXGI; 4723 int ret; 4724 VisualPtr visual; 4725 unsigned long OnScreenSize; 4726 int height, width, displayWidth; 4727 unsigned char *FBStart; 4728 XGIEntPtr pXGIEnt = NULL; 4729 4730 ErrorF("XGIScreenInit\n"); 4731 pScrn = xf86Screens[pScreen->myNum]; 4732 4733 PDEBUG(ErrorF("pScrn->currentMode->HDisplay = %d\n", pScrn->currentMode->HDisplay)); 4734 PDEBUG(ErrorF("pScrn->currentMode->VDisplay = %d\n", pScrn->currentMode->VDisplay)); 4735 4736 PDEBUG(ErrorF("Before update...\n")); 4737 PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX)); 4738 PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY)); 4739 PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth)); 4740 PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0)); 4741 PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0)); 4742 PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1)); 4743 PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1)); 4744 4745/* Jong 07/29/2009; fix bug of switch mode */ 4746#if 1 4747 /* Jong 08/30/2007; no virtual screen for all cases */ 4748 /* Jong 08/22/2007; support modeline */ 4749 /* if(g_CountOfUserDefinedModes > 0) */ 4750 { 4751 /* Jong@08122009 */ 4752 g_virtualX = pScrn->virtualX; 4753 g_virtualY = pScrn->virtualY; 4754 g_frameX0 = pScrn->frameX0; 4755 g_frameY0 = pScrn->frameY0; 4756 g_frameX1 = pScrn->frameX1; 4757 g_frameY1 = pScrn->frameY1; 4758 4759 /* 4760 pScrn->virtualX=pScrn->currentMode->HDisplay; 4761 pScrn->virtualY=pScrn->currentMode->VDisplay; 4762 */ 4763 4764 //pScrn->displayWidth=pScrn->currentMode->HDisplay; 4765 4766 /* 4767 pScrn->frameX0=0; 4768 pScrn->frameY0=0; 4769 pScrn->frameX1=pScrn->currentMode->HDisplay-1; 4770 pScrn->frameY1=pScrn->currentMode->VDisplay-1; */ 4771 } 4772#endif 4773 4774 PDEBUG(ErrorF("After update...\n")); 4775 PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX)); 4776 PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY)); 4777 PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth)); 4778 PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0)); 4779 PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0)); 4780 PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1)); 4781 PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1)); 4782 4783 hwp = VGAHWPTR(pScrn); 4784 4785 pXGI = XGIPTR(pScrn); 4786 4787#if !defined(__arm__) 4788#if !defined(__powerpc__) 4789 if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) { 4790 if (xf86LoadSubModule(pScrn, "vbe")) { 4791#if 0 4792 xf86LoaderReqSymLists(vbeSymbols, NULL); 4793#endif 4794 pXGI->pVbe = VBEExtendedInit(NULL, pXGI->pEnt->index, 4795 SET_BIOS_SCRATCH | 4796 RESTORE_BIOS_SCRATCH); 4797 } 4798 else { 4799 XGIErrorLog(pScrn, "Failed to load VBE submodule\n"); 4800 } 4801 } 4802#endif /* if !defined(__powerpc__) */ 4803#endif 4804 4805 if (IS_DUAL_HEAD(pXGI)) { 4806 pXGIEnt = ENTITY_PRIVATE(pXGI); 4807 pXGIEnt->refCount++; 4808 } 4809 4810 /* Map the VGA memory and get the VGA IO base */ 4811 if (pXGI->Primary) { 4812 hwp->MapSize = 0x10000; /* Standard 64k VGA window */ 4813 if (!vgaHWMapMem(pScrn)) { 4814 XGIErrorLog(pScrn, "Could not map VGA memory window\n"); 4815 return FALSE; 4816 } 4817 } 4818 vgaHWGetIOBase(hwp); 4819 4820 /* Patch the PIOOffset inside vgaHW to use 4821 * our relocated IO ports. 4822 */ 4823 VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 + 4824#ifdef XSERVER_LIBPCIACCESS 4825 (pXGI->PciInfo->regions[2].base_addr & 0xFFFC) 4826#else 4827 (pXGI->PciInfo->ioBase[2] & 0xFFFC) 4828#endif 4829 ; 4830 4831 /* Map the XGI memory and MMIO areas */ 4832 if (!XGIMapMem(pScrn)) { 4833 XGIErrorLog(pScrn, "XGIMapMem() failed\n"); 4834 return FALSE; 4835 } 4836 4837#ifdef UNLOCK_ALWAYS 4838 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); 4839#endif 4840 4841 /* Save the current state */ 4842 XGISave(pScrn); 4843 4844 4845 PDEBUG(ErrorF("--- ScreenInit --- \n")); 4846 PDEBUG(XGIDumpRegs(pScrn)); 4847 4848 /* Initialise the first mode */ 4849 if (!XGIModeInit(pScrn, pScrn->currentMode)) { 4850 XGIErrorLog(pScrn, "XGIModeInit() failed\n"); 4851 return FALSE; 4852 } 4853 4854 /* Jong@08122009; still at virtual */ 4855 /* xgiRestoreVirtual(); */ 4856 4857 PDEBUG(ErrorF("--- XGIModeInit --- \n")); 4858 PDEBUG(XGIDumpRegs(pScrn)); 4859 4860 /* Darken the screen for aesthetic reasons */ 4861 /* Not using Dual Head variant on purpose; we darken 4862 * the screen for both displays, and un-darken 4863 * it when the second head is finished 4864 */ 4865 XGISaveScreen(pScreen, SCREEN_SAVER_ON); 4866 4867 /* Set the viewport */ 4868 XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 4869 /* XGIAdjustFrame(scrnIndex, 0, 0, 0); */ 4870 4871 /* xgiRestoreVirtual(pScrn); */ 4872 4873 /* 4874 * The next step is to setup the screen's visuals, and initialise the 4875 * framebuffer code. In cases where the framebuffer's default 4876 * choices for things like visual layouts and bits per RGB are OK, 4877 * this may be as simple as calling the framebuffer's ScreenInit() 4878 * function. If not, the visuals will need to be setup before calling 4879 * a fb ScreenInit() function and fixed up after. 4880 * 4881 * For most PC hardware at depths >= 8, the defaults that cfb uses 4882 * are not appropriate. In this driver, we fixup the visuals after. 4883 */ 4884 4885 /* 4886 * Reset visual list. 4887 */ 4888 miClearVisualTypes(); 4889 4890 /* Setup the visuals we support. */ 4891 4892 /* 4893 * For bpp > 8, the default visuals are not acceptable because we only 4894 * support TrueColor and not DirectColor. 4895 */ 4896 if (!miSetVisualTypes(pScrn->depth, 4897 (pScrn->bitsPerPixel > 8) ? 4898 TrueColorMask : miGetDefaultVisualMask(pScrn-> 4899 depth), 4900 pScrn->rgbBits, pScrn->defaultVisual)) { 4901 XGISaveScreen(pScreen, SCREEN_SAVER_OFF); 4902 XGIErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n", 4903 pScrn->bitsPerPixel); 4904 return FALSE; 4905 } 4906 4907 /*xgiRestoreVirtual(pScrn); */ 4908 4909#if 0 4910 ErrorF("Use Virtual Size - *1\n"); 4911 width = pScrn->virtualX; 4912 height = pScrn->virtualY; 4913 displayWidth = pScrn->displayWidth; 4914#endif 4915 4916 if (pXGI->Rotate) { 4917 height = pScrn->virtualX; 4918 width = pScrn->virtualY; 4919 } 4920 4921 if (pXGI->ShadowFB) { 4922 pXGI->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 4923 pXGI->ShadowPtr = xalloc(pXGI->ShadowPitch * height); 4924 displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3); 4925 FBStart = pXGI->ShadowPtr; 4926 } 4927 else { 4928 pXGI->ShadowPtr = NULL; 4929 FBStart = pXGI->FbBase; 4930 } 4931 4932 if (!miSetPixmapDepths()) { 4933 XGISaveScreen(pScreen, SCREEN_SAVER_OFF); 4934 XGIErrorLog(pScrn, "miSetPixmapDepths() failed\n"); 4935 return FALSE; 4936 } 4937 4938 /* Point cmdQueuePtr to pXGIEnt for shared usage 4939 * (same technique is then eventually used in DRIScreeninit). 4940 */ 4941 if (IS_SECOND_HEAD(pXGI)) 4942 pXGI->cmdQueueLenPtr = &(XGIPTR(pXGIEnt->pScrn_1)->cmdQueueLen); 4943 else 4944 pXGI->cmdQueueLenPtr = &(pXGI->cmdQueueLen); 4945 4946 pXGI->cmdQueueLen = 0; /* Force an EngineIdle() at start */ 4947 4948#ifdef XF86DRI 4949 if(pXGI->loadDRI) { 4950 /* No DRI in dual head mode */ 4951 if (IS_DUAL_HEAD(pXGI)) { 4952 pXGI->directRenderingEnabled = FALSE; 4953 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4954 "DRI not supported in Dual Head mode\n"); 4955 } 4956 else if ((pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27)) { 4957 PDEBUG(ErrorF("--- DRI not supported \n")); 4958 xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED, 4959 "DRI not supported on this chipset\n"); 4960 pXGI->directRenderingEnabled = FALSE; 4961 } 4962 else { 4963 pXGI->directRenderingEnabled = XGIDRIScreenInit(pScreen); 4964 PDEBUG(ErrorF("--- DRI supported \n")); 4965 } 4966 } 4967#endif 4968 4969 /* xgiRestoreVirtual(pScrn); */ 4970 4971 /* 4972 * Call the framebuffer layer's ScreenInit function, and fill in other 4973 * pScreen fields. 4974 */ 4975 switch (pScrn->bitsPerPixel) { 4976 case 24: 4977 case 8: 4978 case 16: 4979 case 32: 4980 4981/* Jong 07/30/2009; fix bug of small font */ 4982#if 1 4983 PDEBUG(ErrorF("Use Virtual Size - *1\n")); 4984 width = /* pScrn->virtualX; */ pScrn->currentMode->HDisplay; 4985 height = /* pScrn->virtualY;*/ pScrn->currentMode->VDisplay; 4986 4987 /* Jong@10022009 */ 4988 displayWidth = pScrn->displayWidth; /* important to set pitch correctly */ 4989#endif 4990 PDEBUG(ErrorF("Call fbScreenInit()...\n")); 4991 PDEBUG(ErrorF("width=%d, height=%d, pScrn->xDpi=%d, pScrn->yDpi=%d, displayWidth=%d, pScrn->bitsPerPixel=%d...\n", 4992 width, height, pScrn->xDpi, pScrn->yDpi,displayWidth, pScrn->bitsPerPixel)); 4993 4994 /* in fbscreen.c */ 4995 /* (xsize, ysize) : virtual size (1600, 1200) 4996 (dpix, dpiy) : (75, 75) 4997 (542) pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10); 4998 (406) pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10); */ 4999 5000 /* ret = fbScreenInit(pScreen, FBStart, width, */ 5001 ret = fbScreenInit(pScreen, FBStart , width, 5002 height, pScrn->xDpi, pScrn->yDpi, 5003 displayWidth, pScrn->bitsPerPixel); 5004 5005 /* Jong 07/30/2009; bug fixing for small font size */ 5006 pScreen->mmWidth = (pScrn->currentMode->HDisplay * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10); 5007 pScreen->mmHeight = (pScrn->currentMode->VDisplay * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10); 5008 5009 PDEBUG(ErrorF("pScrn->xDpi = %d\n", pScrn->xDpi)); 5010 PDEBUG(ErrorF("pScrn->yDpi = %d\n", pScrn->yDpi)); 5011 PDEBUG(ErrorF("pScreen->mmWidth = %d\n", pScreen->mmWidth)); 5012 PDEBUG(ErrorF("pScreen->mmHeight = %d\n", pScreen->mmHeight)); 5013 5014 break; 5015 default: 5016 ret = FALSE; 5017 break; 5018 } 5019 5020 xgiRestoreVirtual(pScrn); 5021 5022 if (!ret) { 5023 XGIErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n", 5024 pScrn->bitsPerPixel); 5025 XGISaveScreen(pScreen, SCREEN_SAVER_OFF); 5026 return FALSE; 5027 } 5028 5029 if (pScrn->bitsPerPixel > 8) { 5030 /* Fixup RGB ordering */ 5031 visual = pScreen->visuals + pScreen->numVisuals; 5032 while (--visual >= pScreen->visuals) { 5033 if ((visual->class | DynamicClass) == DirectColor) { 5034 visual->offsetRed = pScrn->offset.red; 5035 visual->offsetGreen = pScrn->offset.green; 5036 visual->offsetBlue = pScrn->offset.blue; 5037 visual->redMask = pScrn->mask.red; 5038 visual->greenMask = pScrn->mask.green; 5039 visual->blueMask = pScrn->mask.blue; 5040 } 5041 } 5042 } 5043 5044 /* xgiRestoreVirtual(pScrn); */ 5045 5046 /* Initialize RENDER ext; must be after RGB ordering fixed */ 5047 fbPictureInit(pScreen, 0, 0); 5048 5049 /* xgiRestoreVirtual(pScrn); */ 5050 5051 /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */ 5052 if (!pXGI->ShadowFB) 5053 XGIDGAInit(pScreen); 5054 5055 xf86SetBlackWhitePixels(pScreen); 5056 5057 if (!pXGI->NoAccel) { 5058 /* Volari_EnableAccelerator(pScrn); */ 5059 PDEBUG(ErrorF("---Volari Accel.. \n")); 5060 Volari_AccelInit(pScreen); 5061 } 5062 5063 PDEBUG(ErrorF("--- AccelInit --- \n")); 5064 PDEBUG(XGIDumpRegs(pScrn)); 5065 5066 xf86SetBackingStore(pScreen); 5067 xf86SetSilkenMouse(pScreen); 5068 5069 /* Initialise cursor functions */ 5070 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 5071 5072 if (pXGI->HWCursor) { 5073 XGIHWCursorInit(pScreen); 5074 } 5075 5076 /* Initialise default colourmap */ 5077 if (!miCreateDefColormap(pScreen)) { 5078 XGISaveScreen(pScreen, SCREEN_SAVER_OFF); 5079 XGIErrorLog(pScrn, "miCreateDefColormap() failed\n"); 5080 return FALSE; 5081 } 5082 if (!xf86HandleColormaps 5083 (pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, 5084 XGILoadPalette, NULL, 5085 CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { 5086 PDEBUG(ErrorF("XGILoadPalette() check-return. \n")); 5087 XGISaveScreen(pScreen, SCREEN_SAVER_OFF); 5088 XGIErrorLog(pScrn, "xf86HandleColormaps() failed\n"); 5089 return FALSE; 5090 } 5091 5092/* 5093 if (!xf86HandleColormaps(pScreen, 256, 8, XGILoadPalette, NULL, 5094 CMAP_RELOAD_ON_MODE_SWITCH)) 5095 { 5096 return FALSE; 5097 } 5098*/ 5099 xf86DPMSInit(pScreen, (DPMSSetProcPtr) XGIDisplayPowerManagementSet, 0); 5100 5101 /* Init memPhysBase and fbOffset in pScrn */ 5102 pScrn->memPhysBase = pXGI->FbAddress; 5103 pScrn->fbOffset = 0; 5104 5105 pXGI->ResetXv = pXGI->ResetXvGamma = NULL; 5106 5107#if defined(XvExtension) 5108 if (!pXGI->NoXvideo) { 5109 XGIInitVideo(pScreen); 5110 } 5111#endif 5112 5113#ifdef XF86DRI 5114 if (pXGI->directRenderingEnabled) { 5115 /* Now that mi, drm and others have done their thing, 5116 * complete the DRI setup. 5117 */ 5118 pXGI->directRenderingEnabled = XGIDRIFinishScreenInit(pScreen); 5119 } 5120 5121 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering %sabled\n", 5122 (pXGI->directRenderingEnabled) ? "en" : "dis"); 5123 if (pXGI->directRenderingEnabled) { 5124 /* TODO */ 5125 /* XGISetLFBConfig(pXGI); */ 5126 } 5127#endif 5128 5129 /* Wrap some funcs and setup remaining SD flags */ 5130 5131 pXGI->XGI_SD_Flags &= ~(XGI_SD_PSEUDOXINERAMA); 5132 5133 pXGI->CloseScreen = pScreen->CloseScreen; 5134 pScreen->CloseScreen = XGICloseScreen; 5135 if (IS_DUAL_HEAD(pXGI)) 5136 pScreen->SaveScreen = XGISaveScreenDH; 5137 else 5138 pScreen->SaveScreen = XGISaveScreen; 5139 5140 /* Install BlockHandler */ 5141 pXGI->BlockHandler = pScreen->BlockHandler; 5142 pScreen->BlockHandler = XGIBlockHandler; 5143 5144 /* Report any unused options (only for the first generation) */ 5145 if (serverGeneration == 1) { 5146 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 5147 } 5148 5149 /* Clear frame buffer */ 5150 /* For CRT2, we don't do that at this point in dual head 5151 * mode since the mode isn't switched at this time (it will 5152 * be reset when setting the CRT1 mode). Hence, we just 5153 * save the necessary data and clear the screen when 5154 * going through this for CRT1. 5155 */ 5156 5157 OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay 5158 * (pScrn->bitsPerPixel >> 3); 5159 5160 /* Turn on the screen now */ 5161 /* We do this in dual head mode after second head is finished */ 5162 if (IS_DUAL_HEAD(pXGI)) { 5163 if (IS_SECOND_HEAD(pXGI)) { 5164 bzero(pXGI->FbBase, OnScreenSize); 5165 bzero(pXGIEnt->FbBase1, pXGIEnt->OnScreenSize1); 5166 XGISaveScreen(pScreen, SCREEN_SAVER_OFF); 5167 } 5168 else { 5169 pXGIEnt->FbBase1 = pXGI->FbBase; 5170 pXGIEnt->OnScreenSize1 = OnScreenSize; 5171 } 5172 } 5173 else { 5174 XGISaveScreen(pScreen, SCREEN_SAVER_OFF); 5175 bzero(pXGI->FbBase, OnScreenSize); 5176 } 5177 5178 pXGI->XGI_SD_Flags &= ~XGI_SD_ISDEPTH8; 5179 if (pXGI->CurrentLayout.bitsPerPixel == 8) { 5180 pXGI->XGI_SD_Flags |= XGI_SD_ISDEPTH8; 5181 pXGI->XGI_SD_Flags &= ~XGI_SD_SUPPORTXVGAMMA1; 5182 } 5183 5184 PDEBUG(ErrorF("XGIScreenInit() End. \n")); 5185 PDEBUG(XGIDumpPalette(pScrn)); 5186 PDEBUG(XGIDumpRegs(pScrn)); 5187 5188 /* xgiRestoreVirtual(); */ 5189 XGIAdjustFrame(scrnIndex, 0, 0, 0); 5190 pScrn->frameX0 = 0; 5191 pScrn->frameY0 = 0; 5192 pScrn->frameX1 = pScrn->currentMode->HDisplay - 1 ; 5193 pScrn->frameY1 = pScrn->currentMode->VDisplay - 1; 5194 5195 return TRUE; 5196} 5197 5198/* Usually mandatory */ 5199Bool 5200XGISwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 5201{ 5202 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 5203 XGIPtr pXGI = XGIPTR(pScrn); 5204 5205 if(pXGI->TargetRefreshRate) 5206 mode->VRefresh = pXGI->TargetRefreshRate; 5207 5208 PDEBUG(ErrorF("XGISwitchMode\n")); 5209 PDEBUG(ErrorF("mode->HDisplay = %d\n", mode->HDisplay)); 5210 PDEBUG(ErrorF("mode->VDisplay = %d\n", mode->VDisplay)); 5211 5212 PDEBUG(ErrorF("Before update...\n")); 5213 PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX)); 5214 PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY)); 5215 PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth)); 5216 PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0)); 5217 PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0)); 5218 PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1)); 5219 PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1)); 5220 5221 PDEBUG(ErrorF("pScrn->xDpi = %d\n", pScrn->xDpi)); 5222 PDEBUG(ErrorF("pScrn->yDpi = %d\n", pScrn->yDpi)); 5223 PDEBUG(ErrorF("pScreen->mmWidth = %d\n", pScrn->pScreen->mmWidth)); 5224 PDEBUG(ErrorF("pScreen->mmHeight = %d\n", pScrn->pScreen->mmHeight)); 5225 5226 /* Jong@08122009 */ 5227 //pScrn->frameX0 = 0; 5228 //pScrn->frameY0 = 0; 5229 //pScrn->frameX1 = mode->HDisplay; 5230 //pScrn->frameY1 = mode->VDisplay; 5231 5232 if (!pXGI->NoAccel) { 5233#ifdef XGI_USE_XAA 5234 if (!(pXGI->useEXA) && pXGI->AccelInfoPtr) { 5235 (*pXGI->AccelInfoPtr->Sync) (pScrn); 5236 PDEBUG(ErrorF("XGISwitchMode Accel Enabled. \n")); 5237 } 5238#endif 5239 } 5240 5241 PDEBUG(ErrorF 5242 ("XGISwitchMode (%d, %d) \n", mode->HDisplay, mode->VDisplay)); 5243 5244#if 1 5245 /* Jong 07/29/2009; Set the viewport; still not working */ 5246 XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 5247#endif 5248 5249 if (!(XGIModeInit(xf86Screens[scrnIndex], mode))) 5250 return FALSE; 5251 5252 5253#if 0 5254 int height, width, displayWidth; 5255 unsigned char *FBStart; 5256 int ret; 5257 5258 if (pXGI->ShadowFB) { 5259 displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3); 5260 FBStart = pXGI->ShadowPtr; 5261 } 5262 else { 5263 pXGI->ShadowPtr = NULL; 5264 FBStart = pXGI->FbBase; 5265 } 5266 5267 width = pScrn->virtualX; /* 1024; */ /* pScrn->currentMode->HDisplay; */ 5268 height = pScrn->virtualY; /* 768; */ /* pScrn->currentMode->VDisplay; */ 5269 displayWidth = pScrn->displayWidth; /* important to set pitch correctly */ 5270 5271 ErrorF("Call fbScreenInit()...\n"); 5272 ErrorF("width=%d, height=%d, pScrn->xDpi=%d, pScrn->yDpi=%d, displayWidth=%d, pScrn->bitsPerPixel=%d...\n", 5273 width, height, pScrn->xDpi, pScrn->yDpi,displayWidth, pScrn->bitsPerPixel); 5274 5275 /* in fbscreen.c */ 5276 /* (xsize, ysize) : virtual size (1600, 1200) 5277 (dpix, dpiy) : (75, 75) 5278 (542) pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10); 5279 (406) pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10); */ 5280 5281 ret = fbScreenInit(pScrn->pScreen, FBStart, width, 5282 height, pScrn->xDpi, pScrn->yDpi, 5283 displayWidth, pScrn->bitsPerPixel); 5284#endif 5285 5286 /* Jong 07/30/2009; bug fixing for small font size */ 5287 pScrn->pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10); 5288 pScrn->pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10); 5289 5290#if 0 5291 /* Jong 08/30/2007; no virtual screen for all cases */ 5292 /* Jong 08/22/2007; support modeline */ 5293 /* if(g_CountOfUserDefinedModes > 0) */ 5294 { 5295 5296 pScrn->virtualX=mode->HDisplay; 5297 pScrn->virtualY=mode->VDisplay; 5298 5299 pScrn->displayWidth=mode->HDisplay; 5300 pScrn->frameX0=0; 5301 pScrn->frameY0=0; 5302 pScrn->frameX1=mode->HDisplay-1; 5303 pScrn->frameY1=mode->VDisplay-1; 5304 } 5305#endif 5306 5307 PDEBUG(ErrorF("After update...\n")); 5308 PDEBUG(ErrorF("pScrn->virtualX = %d\n", pScrn->virtualX)); 5309 PDEBUG(ErrorF("pScrn->virtualY = %d\n", pScrn->virtualY)); 5310 PDEBUG(ErrorF("pScrn->displayWidth = %d\n", pScrn->displayWidth)); 5311 PDEBUG(ErrorF("pScrn->frameX0 = %d\n", pScrn->frameX0)); 5312 PDEBUG(ErrorF("pScrn->frameY0 = %d\n", pScrn->frameY0)); 5313 PDEBUG(ErrorF("pScrn->frameX1 = %d\n", pScrn->frameX1)); 5314 PDEBUG(ErrorF("pScrn->frameY1 = %d\n", pScrn->frameY1)); 5315 5316 PDEBUG(ErrorF("pScrn->xDpi = %d\n", pScrn->xDpi)); 5317 PDEBUG(ErrorF("pScrn->yDpi = %d\n", pScrn->yDpi)); 5318 PDEBUG(ErrorF("pScreen->mmWidth = %d\n", pScrn->pScreen->mmWidth)); 5319 PDEBUG(ErrorF("pScreen->mmHeight = %d\n", pScrn->pScreen->mmHeight)); 5320 5321 /* Since RandR (indirectly) uses SwitchMode(), we need to 5322 * update our Xinerama info here, too, in case of resizing 5323 */ 5324 5325 /* sleep(3); */ /* Jong 07/30/2009; wait to be ready for drawing */; 5326 5327 return TRUE; 5328} 5329 5330/* static void 5331XGISetStartAddressCRT1(XGIPtr pXGI, unsigned long base) 5332{ 5333 unsigned char cr11backup; 5334 5335 inXGIIDXREG(XGICR, 0x11, cr11backup); 5336 andXGIIDXREG(XGICR, 0x11, 0x7F); 5337 outXGIIDXREG(XGICR, 0x0D, base & 0xFF); 5338 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF); 5339 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF); 5340 5341 5342 setXGIIDXREG(XGICR, 0x11, 0x7F,(cr11backup & 0x80)); 5343} */ 5344 5345#ifdef XGIMERGED 5346/* static Bool 5347InRegion(int x, int y, region r) 5348{ 5349 return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1); 5350} */ 5351 5352/* static void 5353XGIAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y) 5354{ 5355 XGIPtr pXGI = XGIPTR(pScrn); 5356 unsigned long base; 5357 5358 base = y * pXGI->CurrentLayout.displayWidth + x; 5359 switch(pXGI->CurrentLayout.bitsPerPixel) 5360 { 5361 case 16: base >>= 1; break; 5362 case 32: break; 5363 default: base >>= 2; 5364 } 5365 XGISetStartAddressCRT1(pXGI, base); 5366} */ 5367 5368/* static void 5369XGIMergePointerMoved(int scrnIndex, int x, int y) 5370{ 5371 ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; 5372 XGIPtr pXGI = XGIPTR(pScrn1); 5373 ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn; 5374 region out, in1, in2, f2, f1; 5375 int deltax, deltay; 5376 5377 f1.x0 = pXGI->CRT1frameX0; 5378 f1.x1 = pXGI->CRT1frameX1; 5379 f1.y0 = pXGI->CRT1frameY0; 5380 f1.y1 = pXGI->CRT1frameY1; 5381 f2.x0 = pScrn2->frameX0; 5382 f2.x1 = pScrn2->frameX1; 5383 f2.y0 = pScrn2->frameY0; 5384 f2.y1 = pScrn2->frameY1; 5385 5386 out.x0 = pScrn1->frameX0; 5387 out.x1 = pScrn1->frameX1; 5388 out.y0 = pScrn1->frameY0; 5389 out.y1 = pScrn1->frameY1; 5390 5391 in1 = out; 5392 in2 = out; 5393 switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position) 5394 { 5395 case xgiLeftOf: 5396 in1.x0 = f1.x0; 5397 in2.x1 = f2.x1; 5398 break; 5399 case xgiRightOf: 5400 in1.x1 = f1.x1; 5401 in2.x0 = f2.x0; 5402 break; 5403 case xgiBelow: 5404 in1.y1 = f1.y1; 5405 in2.y0 = f2.y0; 5406 break; 5407 case xgiAbove: 5408 in1.y0 = f1.y0; 5409 in2.y1 = f2.y1; 5410 break; 5411 case xgiClone: 5412 break; 5413 } 5414 5415 deltay = 0; 5416 deltax = 0; 5417 5418 if(InRegion(x, y, out)) 5419 { 5420 5421 if(InRegion(x, y, in1) && !InRegion(x, y, f1)) 5422 { 5423 REBOUND(f1.x0, f1.x1, x); 5424 REBOUND(f1.y0, f1.y1, y); 5425 deltax = 1; 5426 } 5427 if(InRegion(x, y, in2) && !InRegion(x, y, f2)) 5428 { 5429 REBOUND(f2.x0, f2.x1, x); 5430 REBOUND(f2.y0, f2.y1, y); 5431 deltax = 1; 5432 } 5433 5434 } 5435 else 5436 { 5437 5438 if(out.x0 > x) 5439 { 5440 deltax = x - out.x0; 5441 } 5442 if(out.x1 < x) 5443 { 5444 deltax = x - out.x1; 5445 } 5446 if(deltax) 5447 { 5448 pScrn1->frameX0 += deltax; 5449 pScrn1->frameX1 += deltax; 5450 f1.x0 += deltax; 5451 f1.x1 += deltax; 5452 f2.x0 += deltax; 5453 f2.x1 += deltax; 5454 } 5455 5456 if(out.y0 > y) 5457 { 5458 deltay = y - out.y0; 5459 } 5460 if(out.y1 < y) 5461 { 5462 deltay = y - out.y1; 5463 } 5464 if(deltay) 5465 { 5466 pScrn1->frameY0 += deltay; 5467 pScrn1->frameY1 += deltay; 5468 f1.y0 += deltay; 5469 f1.y1 += deltay; 5470 f2.y0 += deltay; 5471 f2.y1 += deltay; 5472 } 5473 5474 switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position) 5475 { 5476 case xgiLeftOf: 5477 if(x >= f1.x0) 5478 { REBOUND(f1.y0, f1.y1, y); } 5479 if(x <= f2.x1) 5480 { REBOUND(f2.y0, f2.y1, y); } 5481 break; 5482 case xgiRightOf: 5483 if(x <= f1.x1) 5484 { REBOUND(f1.y0, f1.y1, y); } 5485 if(x >= f2.x0) 5486 { REBOUND(f2.y0, f2.y1, y); } 5487 break; 5488 case xgiBelow: 5489 if(y <= f1.y1) 5490 { REBOUND(f1.x0, f1.x1, x); } 5491 if(y >= f2.y0) 5492 { REBOUND(f2.x0, f2.x1, x); } 5493 break; 5494 case xgiAbove: 5495 if(y >= f1.y0) 5496 { REBOUND(f1.x0, f1.x1, x); } 5497 if(y <= f2.y1) 5498 { REBOUND(f2.x0, f2.x1, x); } 5499 break; 5500 case xgiClone: 5501 break; 5502 } 5503 5504 } 5505 5506 if(deltax || deltay) 5507 { 5508 pXGI->CRT1frameX0 = f1.x0; 5509 pXGI->CRT1frameY0 = f1.y0; 5510 pScrn2->frameX0 = f2.x0; 5511 pScrn2->frameY0 = f2.y0; 5512 5513 pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1; 5514 pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1; 5515 pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1; 5516 pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1; 5517 pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1; 5518 pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1; 5519 5520 XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0); 5521 } 5522} */ 5523 5524 5525/* static void 5526XGIAdjustFrameMerged(int scrnIndex, int x, int y, int flags) 5527{ 5528 ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex]; 5529 XGIPtr pXGI = XGIPTR(pScrn1); 5530 ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn; 5531 int VTotal = pXGI->CurrentLayout.mode->VDisplay; 5532 int HTotal = pXGI->CurrentLayout.mode->HDisplay; 5533 int VMax = VTotal; 5534 int HMax = HTotal; 5535 5536 BOUND(x, 0, pScrn1->virtualX - HTotal); 5537 BOUND(y, 0, pScrn1->virtualY - VTotal); 5538 5539 switch(SDMPTR(pScrn1)->CRT2Position) 5540 { 5541 case xgiLeftOf: 5542 pScrn2->frameX0 = x; 5543 BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); 5544 pXGI->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay; 5545 BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); 5546 break; 5547 case xgiRightOf: 5548 pXGI->CRT1frameX0 = x; 5549 BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); 5550 pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay; 5551 BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); 5552 break; 5553 case xgiAbove: 5554 BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); 5555 pScrn2->frameY0 = y; 5556 BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); 5557 pXGI->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay; 5558 break; 5559 case xgiBelow: 5560 BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); 5561 pXGI->CRT1frameY0 = y; 5562 BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); 5563 pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay; 5564 break; 5565 case xgiClone: 5566 BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay); 5567 BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay); 5568 BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay); 5569 BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay); 5570 break; 5571 } 5572 5573 BOUND(pXGI->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay); 5574 BOUND(pXGI->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay); 5575 BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay); 5576 BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay); 5577 5578 pScrn1->frameX0 = x; 5579 pScrn1->frameY0 = y; 5580 5581 pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1; 5582 pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1; 5583 pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1; 5584 pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1; 5585 pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1; 5586 pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1; 5587 5588 XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0); 5589} */ 5590#endif 5591 5592/* 5593 * This function is used to initialize the Start Address - the first 5594 * displayed location in the video memory. 5595 * 5596 * Usually mandatory 5597 */ 5598void 5599XGIAdjustFrame(int scrnIndex, int x, int y, int flags) 5600{ 5601 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 5602 XGIPtr pXGI = XGIPTR(pScrn); 5603 unsigned long base; 5604 unsigned char ucSR5Stat, ucTemp; 5605 5606 ErrorF("AdjustFrame %d\n", scrnIndex); 5607 inXGIIDXREG(XGISR, 0x05, ucSR5Stat); 5608 if (ucSR5Stat == 0xA1) 5609 ucSR5Stat = 0x86; 5610 outXGIIDXREG(XGISR, 0x05, 0x86); 5611 5612 base = (pScrn->bitsPerPixel + 7) / 8; 5613 base *= x; 5614 base += pXGI->scrnOffset * y; 5615 base >>= 2; 5616 5617 switch (pXGI->Chipset) { 5618 case PCI_CHIP_XGIXG40: 5619 case PCI_CHIP_XGIXG20: 5620 case PCI_CHIP_XGIXG21: 5621 case PCI_CHIP_XGIXG27: 5622 default: 5623 5624 ucTemp = base & 0xFF; 5625 outXGIIDXREG(XGICR, 0x0D, ucTemp); 5626 ucTemp = (base >> 8) & 0xFF; 5627 outXGIIDXREG(XGICR, 0x0C, ucTemp); 5628 ucTemp = (base >> 16) & 0xFF; 5629 outXGIIDXREG(XGISR, 0x0D, ucTemp); 5630 ucTemp = (base >> 24) & 0x01; 5631 setXGIIDXREG(XGISR, 0x37, 0xFE, ucTemp); 5632 5633/* if (pXGI->VBFlags) { 5634 XGI_UnLockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo); 5635 ucTemp = base & 0xFF ; outXGIIDXREG( XGIPART1, 6 , ucTemp ) ; 5636 ucTemp = (base>>8) & 0xFF ; outXGIIDXREG( XGIPART1, 5 , ucTemp ) ; 5637 ucTemp = (base>>16) & 0xFF ; outXGIIDXREG( XGIPART1, 4 , ucTemp ) ; 5638 ucTemp = (base>>24) & 0x01 ; ucTemp <<= 7 ; 5639 setXGIIDXREG( XGIPART1, 0x2, 0x7F, ucTemp ) ; 5640 5641 XGI_LockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo); 5642 } 5643 */ 5644 break; 5645 5646 } 5647 5648 outXGIIDXREG(XGISR, 0x05, ucSR5Stat); 5649 5650} 5651 5652/* 5653 * This is called when VT switching back to the X server. Its job is 5654 * to reinitialise the video mode. 5655 * Mandatory! 5656 */ 5657static Bool 5658XGIEnterVT(int scrnIndex, int flags) 5659{ 5660 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 5661 XGIPtr pXGI = XGIPTR(pScrn); 5662 5663 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); 5664 5665 if (!XGIModeInit(pScrn, pScrn->currentMode)) { 5666 XGIErrorLog(pScrn, "XGIEnterVT: XGIModeInit() failed\n"); 5667 return FALSE; 5668 } 5669 5670 XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 5671 5672#ifdef XF86DRI 5673 if (pXGI->directRenderingEnabled) { 5674 DRIUnlock(screenInfo.screens[scrnIndex]); 5675 } 5676#endif 5677 5678 if ((!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) && (pXGI->ResetXv)) { 5679 (pXGI->ResetXv) (pScrn); 5680 } 5681 5682 return TRUE; 5683} 5684 5685/* 5686 * This is called when VT switching away from the X server. Its job is 5687 * to restore the previous (text) mode. 5688 * Mandatory! 5689 */ 5690static void 5691XGILeaveVT(int scrnIndex, int flags) 5692{ 5693 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 5694 vgaHWPtr hwp = VGAHWPTR(pScrn); 5695 XGIPtr pXGI = XGIPTR(pScrn); 5696#ifdef XF86DRI 5697 ScreenPtr pScreen; 5698 5699 PDEBUG(ErrorF("XGILeaveVT()\n")); 5700 if (pXGI->directRenderingEnabled) { 5701 pScreen = screenInfo.screens[scrnIndex]; 5702 DRILock(pScreen, 0); 5703 } 5704#endif 5705 5706 if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI)) 5707 return; 5708 5709 if (pXGI->CursorInfoPtr) { 5710 /* Because of the test and return above, we know that this is not 5711 * the second head. 5712 */ 5713 pXGI->CursorInfoPtr->HideCursor(pScrn); 5714 XGI_WaitBeginRetrace(pXGI->RelIO); 5715 } 5716 5717 XGIRestore(pScrn); 5718 5719 5720 /* We use (otherwise unused) bit 7 to indicate that we are running to keep 5721 * xgifb to change the displaymode (this would result in lethal display 5722 * corruption upon quitting X or changing to a VT until a reboot). 5723 */ 5724 vgaHWLock(hwp); 5725} 5726 5727 5728/* 5729 * This is called at the end of each server generation. It restores the 5730 * original (text) mode. It should really also unmap the video memory too. 5731 * Mandatory! 5732 */ 5733static Bool 5734XGICloseScreen(int scrnIndex, ScreenPtr pScreen) 5735{ 5736 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 5737 vgaHWPtr hwp = VGAHWPTR(pScrn); 5738 XGIPtr pXGI = XGIPTR(pScrn); 5739 5740 5741#ifdef XF86DRI 5742 if (pXGI->directRenderingEnabled) { 5743 XGIDRICloseScreen(pScreen); 5744 pXGI->directRenderingEnabled = FALSE; 5745 } 5746#endif 5747 5748 if (pScrn->vtSema) { 5749 if (pXGI->CursorInfoPtr 5750 && (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI))) { 5751 pXGI->CursorInfoPtr->HideCursor(pScrn); 5752 XGI_WaitBeginRetrace(pXGI->RelIO); 5753 } 5754 5755 5756 XGIRestore(pScrn); 5757 vgaHWLock(hwp); 5758 } 5759 5760 /* We should restore the mode number in case vtsema = false as well, 5761 * but since we haven't register access then we can't do it. I think 5762 * I need to rework the save/restore stuff, like saving the video 5763 * status when returning to the X server and by that save me the 5764 * trouble if xgifb was started from a textmode VT while X was on. 5765 */ 5766 5767 XGIUnmapMem(pScrn); 5768 vgaHWUnmapMem(pScrn); 5769 5770 if (IS_DUAL_HEAD(pXGI)) { 5771 XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI); 5772 pXGIEnt->refCount--; 5773 } 5774 5775 if (pXGI->pInt) { 5776 xf86FreeInt10(pXGI->pInt); 5777 pXGI->pInt = NULL; 5778 } 5779 5780#ifdef XGI_USE_XAA 5781 if (pXGI->AccelLinearScratch) { 5782 xf86FreeOffscreenLinear(pXGI->AccelLinearScratch); 5783 pXGI->AccelLinearScratch = NULL; 5784 } 5785 5786 if (!(pXGI->useEXA) && pXGI->AccelInfoPtr) { 5787 XAADestroyInfoRec(pXGI->AccelInfoPtr); 5788 pXGI->AccelInfoPtr = NULL; 5789 } 5790#endif 5791 5792 if (pXGI->CursorInfoPtr) { 5793 xf86DestroyCursorInfoRec(pXGI->CursorInfoPtr); 5794 pXGI->CursorInfoPtr = NULL; 5795 } 5796 5797 if (pXGI->ShadowPtr) { 5798 xfree(pXGI->ShadowPtr); 5799 pXGI->ShadowPtr = NULL; 5800 } 5801 5802 if (pXGI->DGAModes) { 5803 xfree(pXGI->DGAModes); 5804 pXGI->DGAModes = NULL; 5805 } 5806 5807 if (pXGI->adaptor) { 5808 xfree(pXGI->adaptor); 5809 pXGI->adaptor = NULL; 5810 pXGI->ResetXv = pXGI->ResetXvGamma = NULL; 5811 } 5812 5813 pScrn->vtSema = FALSE; 5814 5815 /* Restore Blockhandler */ 5816 pScreen->BlockHandler = pXGI->BlockHandler; 5817 5818 pScreen->CloseScreen = pXGI->CloseScreen; 5819 5820 return (*pScreen->CloseScreen) (scrnIndex, pScreen); 5821} 5822 5823 5824/* Free up any per-generation data structures */ 5825 5826/* Optional */ 5827static void 5828XGIFreeScreen(int scrnIndex, int flags) 5829{ 5830 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) { 5831 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 5832 } 5833 5834 XGIFreeRec(xf86Screens[scrnIndex]); 5835} 5836 5837 5838/* Jong 07/02/2008; Validate user-defined mode */ 5839int XGIValidateUserDefMode(XGIPtr pXGI, DisplayModePtr mode) 5840{ 5841 UShort i = (pXGI->CurrentLayout.bitsPerPixel+7)/8 - 1; 5842 5843 5844#if 1 5845 if((mode->HDisplay >= 1600) && (mode->VDisplay >= 1200) && (mode->VRefresh > 60)) 5846 { 5847 ErrorF("Not support over (1600,1200) 60Hz ... Reduce to (1600,1200) 60Hz\n"); 5848 mode->type=48; /* not user-defined */ 5849 mode->VRefresh = 60.0; 5850 5851 mode->Clock=mode->SynthClock=162000; /* from XG20_Mode[] */ /* ((float)(mode->VTotal*mode->HTotal)+0.5) * (mode->VRefresh) / 1000.0; */ 5852 ErrorF("Update clock to %d...\n", mode->Clock); 5853 return(-111) ; 5854 } 5855#endif 5856 5857#if 0 5858 if(XGI_GetModeID(0, mode->HDisplay, mode->VDisplay, i, 0, 0) == 0) 5859 { 5860 /* Jong 11/10/2008; support custom mode without ModeID */ 5861 if( !((pXGI->HaveCustomModes) && (!(mode->type & M_T_DEFAULT))) ) 5862 { 5863 ErrorF("Can't get Mode ID...\n"); 5864 return(MODE_NOMODE) ; 5865 } 5866 } 5867#endif 5868 5869 return(MODE_OK); 5870} 5871 5872/* Checks if a mode is suitable for the selected chipset. */ 5873 5874static int 5875XGIValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 5876{ 5877 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 5878 XGIPtr pXGI = XGIPTR(pScrn); 5879 int HDisplay = mode->HDisplay; 5880 int VDisplay = mode->VDisplay; 5881 int Clock = mode->Clock; 5882 int i = 0; 5883 int VRefresh; 5884 5885 /* Jong 07/27/2009; support custom mode without ModeID */ 5886 pXGI->HaveCustomModes = TRUE; 5887 5888 VRefresh = 5889 (int) ((float) (Clock * 1000) / 5890 (float) (mode->VTotal * mode->HTotal) + 0.5); 5891 5892 /* Jong@09252009 */ 5893 if(mode->VRefresh == 0) 5894 mode->VRefresh = VRefresh; 5895 5896 if((mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C)) 5897 { 5898 VRefresh = mode->VRefresh; 5899 Clock = mode->Clock; 5900 } 5901 5902 PDEBUG5(ErrorF("\nXGIValidMode()-->")); 5903 PDEBUG5(ErrorF 5904 ("CLK=%5.3fMhz %dx%d@%d ", (float) Clock / 1000, HDisplay, 5905 VDisplay, VRefresh)); 5906 PDEBUG5(ErrorF("(VT,HT)=(%d,%d)\n", mode->VTotal, mode->HTotal)); 5907 PDEBUG5(ErrorF("flags = %d\n", flags)); 5908 if(flags == MODECHECK_FINAL) 5909 PDEBUG5(ErrorF("This is a final check...\n")); 5910 5911#if 1 5912 if((mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C)) 5913 { 5914 if(pScrn->monitor->DDC) 5915 { 5916 if(XGICheckModeByDDC(mode, pScrn->monitor->DDC) == FALSE) 5917 { 5918 ErrorF("It's a user-defined mode...rejected by EDID (pScrn->monitor->DDC)...return MODE_NOMODE\n"); 5919 return (MODE_NOMODE); 5920 } 5921 } 5922 5923 PDEBUG5(ErrorF("It's a user-defined mode...return MODE_OK (might need more checking here) \n")); 5924 return(MODE_OK); 5925 } 5926#else 5927 if((mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C)) 5928 { 5929 iRet=XGIValidateUserDefMode(pXGI, mode); 5930 if(iRet != -111) 5931 { 5932 if(iRet == MODE_OK) 5933 ErrorF("User-defined mode---MODE_OK\n"); 5934 else 5935 ErrorF("User-defined mode---MODE_NOMODE\n"); 5936 5937 return(iRet); 5938 } 5939 } 5940#endif 5941 5942 if(mode->VRefresh == 0) 5943 mode->VRefresh = VRefresh; 5944 5945#if 0 5946 if (pXGI->VBFlags & CRT2_LCD) { 5947 if ((HDisplay > 1600 && VDisplay > 1200) 5948 || (HDisplay < 640 && VDisplay < 480)) { 5949 PDEBUG5(ErrorF("skip by LCD limit\n")); 5950 return (MODE_NOMODE); 5951 } 5952 /* if( VRefresh != 60) return(MODE_NOMODE) ; */ 5953 } 5954 else if (pXGI->VBFlags & CRT2_TV) { 5955 if ((HDisplay > 1024 && VDisplay > 768) || 5956 (HDisplay < 640 && VDisplay < 480) || (VRefresh != 60)) { 5957 PDEBUG5(ErrorF("skip by TV limit\n")); 5958 return (MODE_NOMODE); 5959 } 5960 } 5961 else if (pXGI->VBFlags & CRT2_VGA) { 5962 if ((HDisplay > 1600 && VDisplay > 1200) || 5963 (HDisplay < 640 && VDisplay < 480)) { 5964 PDEBUG5(ErrorF("skip by CRT2 limit\n")); 5965 return (MODE_NOMODE); 5966 } 5967 } 5968#endif 5969 5970 if ((pXGI->Chipset == PCI_CHIP_XGIXG20) ||(pXGI->Chipset == PCI_CHIP_XGIXG21) ||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) { 5971 XgiMode = XG20_Mode; 5972 } 5973 else { 5974 XgiMode = XGI_Mode; 5975 } 5976 5977 while ((XgiMode[i].Clock != Clock) || 5978 (XgiMode[i].HDisplay != HDisplay) || 5979 (XgiMode[i].VDisplay != VDisplay)) { 5980 if (XgiMode[i].Clock == 0) { 5981 PDEBUG5(ErrorF 5982 ("--- Mode %dx%d@%dHz is not defined in support mode table of driver\n", HDisplay, 5983 VDisplay, VRefresh)); 5984 PDEBUG5(ErrorF("Mode is invalid...return MODE_NOMODE\n")); 5985 return (MODE_NOMODE); 5986 } 5987 else 5988 i++; 5989 } 5990 5991 if(pScrn->monitor->DDC) 5992 { 5993 if(XGICheckModeByDDC(mode, pScrn->monitor->DDC) == FALSE) 5994 { 5995 ErrorF("Rejected by EDID (pScrn->monitor->DDC)...return MODE_NOMODE\n"); 5996 return (MODE_NOMODE); 5997 } 5998 } 5999 6000 if (pXGI->Chipset == PCI_CHIP_XGIXG27) 6001 { 6002 if(((g_PowerSavingStatus & 0x03) < 0x03) && 6003 ((g_PowerSavingStatus & 0x04) == 0x00) && 6004 g_pMonitorDVI) 6005 { 6006 if(XGICheckModeByDDC(mode, g_pMonitorDVI) == FALSE) 6007 { 6008 PDEBUG5(ErrorF("Rejected by CRT2 EDID...return MODE_NOMODE\n")); 6009 return (MODE_NOMODE); 6010 } 6011 } 6012 } 6013 else /* Jong 12/05/2007; filter mode of CRT1 with CRT2 DDC for XG21 */ 6014 { 6015 if(g_pMonitorDVI) 6016 { 6017 if(XGICheckModeByDDC(mode, g_pMonitorDVI) == FALSE) 6018 { 6019 PDEBUG5(ErrorF("Rejected by DVI EDID...return MODE_NOMODE\n")); 6020 return (MODE_NOMODE); 6021 } 6022 } 6023 } 6024 6025 PDEBUG5(ErrorF("Mode is valid...return MODE_OK\n")); 6026 return (MODE_OK); 6027} 6028 6029/* Do screen blanking 6030 * 6031 * Mandatory 6032 */ 6033static Bool 6034XGISaveScreen(ScreenPtr pScreen, int mode) 6035{ 6036 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 6037 6038 if ((pScrn != NULL) && pScrn->vtSema) { 6039 6040 XGIPtr pXGI = XGIPTR(pScrn); 6041 6042#ifdef UNLOCK_ALWAYS 6043 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); 6044#endif 6045 } 6046 6047 return vgaHWSaveScreen(pScreen, mode); 6048} 6049 6050/* SaveScreen for dual head mode */ 6051static Bool 6052XGISaveScreenDH(ScreenPtr pScreen, int mode) 6053{ 6054#ifdef XGIDUALHEAD 6055 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 6056 6057 if ((pScrn != NULL) && pScrn->vtSema) { 6058 XGIPtr pXGI = XGIPTR(pScrn); 6059 6060 if (IS_SECOND_HEAD(pXGI) 6061 && ((!(pXGI->VBFlags & CRT1_LCDA)) 6062 || (pXGI->XGI_Pr->VBType & VB_XGI301C))) { 6063 6064 /* Slave head is always CRT1 */ 6065 if (pXGI->VBFlags & CRT1_LCDA) 6066 pXGI->Blank = xf86IsUnblank(mode) ? FALSE : TRUE; 6067 6068 return vgaHWSaveScreen(pScreen, mode); 6069 } 6070 else { 6071 /* Master head is always CRT2 */ 6072 /* But we land here if CRT1 is LCDA, too */ 6073 6074 /* We can only blank LCD, not other CRT2 devices */ 6075 if (!(pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA))) 6076 return TRUE; 6077 6078 /* enable access to extended sequencer registers */ 6079#ifdef UNLOCK_ALWAYS 6080 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); 6081#endif 6082 } 6083 } 6084#endif 6085 return TRUE; 6086} 6087 6088#ifdef DEBUG 6089static void 6090XGIDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode) 6091{ 6092 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock : %x\n", mode->Clock); 6093 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Display : %x\n", 6094 mode->CrtcHDisplay); 6095 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank Start : %x\n", 6096 mode->CrtcHBlankStart); 6097 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync Start : %x\n", 6098 mode->CrtcHSyncStart); 6099 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync End : %x\n", 6100 mode->CrtcHSyncEnd); 6101 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank End : %x\n", 6102 mode->CrtcHBlankEnd); 6103 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Total : %x\n", mode->CrtcHTotal); 6104 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew); 6105 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz HAdjusted : %x\n", 6106 mode->CrtcHAdjusted); 6107 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Display : %x\n", 6108 mode->CrtcVDisplay); 6109 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank Start : %x\n", 6110 mode->CrtcVBlankStart); 6111 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync Start : %x\n", 6112 mode->CrtcVSyncStart); 6113 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync End : %x\n", 6114 mode->CrtcVSyncEnd); 6115 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank End : %x\n", 6116 mode->CrtcVBlankEnd); 6117 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Total : %x\n", mode->CrtcVTotal); 6118 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt VAdjusted : %x\n", 6119 mode->CrtcVAdjusted); 6120} 6121#endif 6122 6123static void 6124XGIModifyModeInfo(DisplayModePtr mode) 6125{ 6126 if (mode->CrtcHBlankStart == mode->CrtcHDisplay) 6127 mode->CrtcHBlankStart++; 6128 if (mode->CrtcHBlankEnd == mode->CrtcHTotal) 6129 mode->CrtcHBlankEnd--; 6130 if (mode->CrtcVBlankStart == mode->CrtcVDisplay) 6131 mode->CrtcVBlankStart++; 6132 if (mode->CrtcVBlankEnd == mode->CrtcVTotal) 6133 mode->CrtcVBlankEnd--; 6134} 6135 6136/* Things to do before a ModeSwitch. We set up the 6137 * video bridge configuration and the TurboQueue. 6138 */ 6139void 6140XGIPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) 6141{ 6142 XGIPtr pXGI = XGIPTR(pScrn); 6143 unsigned char CR30, CR31, CR33; 6144 unsigned char CR3B = 0; 6145 unsigned char CR17, CR38 = 0; 6146 unsigned char CR35 = 0, CR79 = 0; 6147 unsigned long vbflag; 6148 int temp = 0; 6149 int crt1rateindex = 0; 6150 DisplayModePtr mymode; 6151#ifdef XGIMERGED 6152 DisplayModePtr mymode2 = NULL; 6153#endif 6154 6155#ifdef XGIMERGED 6156 if (pXGI->MergedFB) { 6157 mymode = ((XGIMergedDisplayModePtr) mode->Private)->CRT1; 6158 mymode2 = ((XGIMergedDisplayModePtr) mode->Private)->CRT2; 6159 } 6160 else 6161#endif 6162 mymode = mode; 6163 6164 vbflag = pXGI->VBFlags; 6165 PDEBUG(ErrorF("VBFlags=0x%lx\n", pXGI->VBFlags)); 6166 6167#ifdef UNLOCK_ALWAYS 6168 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); /* Unlock Registers */ 6169#endif 6170 6171 inXGIIDXREG(XGICR, 0x30, CR30); 6172 inXGIIDXREG(XGICR, 0x31, CR31); 6173 inXGIIDXREG(XGICR, 0x33, CR33); 6174 6175 inXGIIDXREG(XGICR, 0x3b, CR3B); 6176 xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4, 6177 "Before: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n", 6178 CR30, CR31, CR33, temp, CR38); 6179 6180 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "VBFlags=0x%lx\n", 6181 pXGI->VBFlags); 6182 6183 CR30 = 0x00; 6184 CR31 &= ~0x60; /* Clear VB_Drivermode & VB_OutputDisable */ 6185 CR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */ 6186 CR35 = 0x00; 6187 6188 6189 if (!pXGI->AllowHotkey) { 6190 CR31 |= 0x80; /* Disable hotkey-switch */ 6191 } 6192 CR79 &= ~0x10; /* Enable Backlight control on 315 series */ 6193 6194 6195 if ((vbflag & CRT1_LCDA) && (viewmode == XGI_MODE_CRT1)) { 6196 6197 CR38 |= 0x02; 6198 6199 } 6200 else { 6201 6202 switch (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) { 6203 6204 case CRT2_TV: 6205 6206 CR38 &= ~0xC0; /* Clear Pal M/N bits */ 6207 6208 if (vbflag & TV_YPBPR) { /* Video bridge */ 6209 if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR) { 6210 CR30 |= 0x80; 6211 CR38 |= 0x08; 6212 if (vbflag & TV_YPBPR525P) 6213 CR38 |= 0x10; 6214 else if (vbflag & TV_YPBPR750P) 6215 CR38 |= 0x20; 6216 else if (vbflag & TV_YPBPR1080I) 6217 CR38 |= 0x30; 6218 CR31 &= ~0x01; 6219 if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPRAR) { 6220 CR3B &= ~0x03; 6221 if ((vbflag & TV_YPBPRAR) == TV_YPBPR43LB) 6222 CR3B |= 0x00; 6223 else if ((vbflag & TV_YPBPRAR) == TV_YPBPR43) 6224 CR3B |= 0x03; 6225 else if ((vbflag & TV_YPBPRAR) == TV_YPBPR169) 6226 CR3B |= 0x01; 6227 else 6228 CR3B |= 0x03; 6229 } 6230 } 6231 } 6232 else { /* All */ 6233 if (vbflag & TV_SCART) 6234 CR30 |= 0x10; 6235 if (vbflag & TV_SVIDEO) 6236 CR30 |= 0x08; 6237 if (vbflag & TV_AVIDEO) 6238 CR30 |= 0x04; 6239 if (!(CR30 & 0x1C)) 6240 CR30 |= 0x08; /* default: SVIDEO */ 6241 6242 if (vbflag & TV_PAL) { 6243 CR31 |= 0x01; 6244 CR35 |= 0x01; 6245 if (pXGI->XGI_Pr->VBType & VB_XGIVB) { 6246 if (vbflag & TV_PALM) { 6247 CR38 |= 0x40; 6248 CR35 |= 0x04; 6249 } 6250 else if (vbflag & TV_PALN) { 6251 CR38 |= 0x80; 6252 CR35 |= 0x08; 6253 } 6254 } 6255 } 6256 else { 6257 CR31 &= ~0x01; 6258 CR35 &= ~0x01; 6259 if (vbflag & TV_NTSCJ) { 6260 CR38 |= 0x40; /* TW, not BIOS */ 6261 CR35 |= 0x02; 6262 } 6263 } 6264 if (vbflag & TV_SCART) { 6265 CR31 |= 0x01; 6266 CR35 |= 0x01; 6267 } 6268 } 6269 6270 CR31 &= ~0x04; /* Clear NotSimuMode */ 6271#ifdef XGI_CP 6272 XGI_CP_DRIVER_CONFIG 6273#endif 6274 break; 6275 6276 case CRT2_LCD: 6277 CR30 |= 0x20; 6278 break; 6279 6280 case CRT2_VGA: 6281 CR30 |= 0x40; 6282 break; 6283 6284 default: 6285 CR30 |= 0x00; 6286 CR31 |= 0x20; /* VB_OUTPUT_DISABLE */ 6287 } 6288 6289 } 6290 6291 if (vbflag & CRT1_LCDA) { 6292 switch (viewmode) { 6293 case XGI_MODE_CRT1: 6294 CR38 |= 0x01; 6295 break; 6296 case XGI_MODE_CRT2: 6297 if (vbflag & (CRT2_TV | CRT2_VGA)) { 6298 CR30 |= 0x02; 6299 CR38 |= 0x01; 6300 } 6301 else { 6302 CR38 |= 0x03; 6303 } 6304 break; 6305 case XGI_MODE_SIMU: 6306 default: 6307 if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) { 6308 CR30 |= 0x01; 6309 } 6310 break; 6311 } 6312 } 6313 else { 6314 if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) { 6315 CR30 |= 0x01; 6316 } 6317 } 6318 6319 CR31 |= 0x40; /* Set Drivermode */ 6320 CR31 &= ~0x06; /* Disable SlaveMode, disable SimuMode in SlaveMode */ 6321 crt1rateindex = XGISearchCRT1Rate(pScrn, mymode); 6322 6323 if (IS_DUAL_HEAD(pXGI)) { 6324 if (IS_SECOND_HEAD(pXGI)) { 6325 /* CRT1 */ 6326 CR33 &= 0xf0; 6327 if (!(vbflag & CRT1_LCDA)) { 6328 CR33 |= (crt1rateindex & 0x0f); 6329 } 6330 } 6331 else { 6332 /* CRT2 */ 6333 CR33 &= 0x0f; 6334 if (vbflag & CRT2_VGA) { 6335 CR33 |= ((crt1rateindex << 4) & 0xf0); 6336 } 6337 } 6338 } 6339 else 6340#ifdef XGIMERGED 6341 if (pXGI->MergedFB) { 6342 CR33 = 0; 6343 if (!(vbflag & CRT1_LCDA)) { 6344 CR33 |= (crt1rateindex & 0x0f); 6345 } 6346 if (vbflag & CRT2_VGA) { 6347 CR33 |= (XGISearchCRT1Rate(pScrn, mymode2) << 4); 6348 } 6349 } 6350 else 6351#endif 6352 { 6353 CR33 = 0; 6354 if (!(vbflag & CRT1_LCDA)) { 6355 CR33 |= (crt1rateindex & 0x0f); 6356 } 6357 if (vbflag & CRT2_VGA) { 6358 CR33 |= ((crt1rateindex & 0x0f) << 4); 6359 } 6360 if (vbflag & CRT2_ENABLE) { 6361 if (pXGI->CRT1off) 6362 CR33 &= 0xf0; 6363 } 6364 } 6365 outXGIIDXREG(XGICR, 0x30, CR30); 6366 outXGIIDXREG(XGICR, 0x31, CR31); 6367 outXGIIDXREG(XGICR, 0x33, CR33); 6368 if (temp) { 6369 outXGIIDXREG(XGICR, temp, CR38); 6370 } 6371 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, 6372 "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n", 6373 CR30, CR31, CR33, temp, CR38); 6374 6375 if (pXGI->VBFlags & CRT2_ENABLE) { 6376 /* Switch on CRT1 for modes that require the bridge in SlaveMode */ 6377 andXGIIDXREG(XGISR, 0x1f, 0x3f); 6378 inXGIIDXREG(XGICR, 0x17, CR17); 6379 if (!(CR17 & 0x80)) { 6380 orXGIIDXREG(XGICR, 0x17, 0x80); 6381 outXGIIDXREG(XGISR, 0x00, 0x01); 6382 usleep(10000); 6383 outXGIIDXREG(XGISR, 0x00, 0x03); 6384 } 6385 } 6386 6387 andXGIIDXREG(XGISR, 0x1f, 0xfb); /* disable DAC pedestal to reduce brightness */ 6388} 6389 6390/* PostSetMode: 6391 * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA; 6392 * VESA uses the bridge in SlaveMode and switching CRT1 off while 6393 * the bridge is in SlaveMode not that clever... 6394 * -) Check if overlay can be used (depending on dotclock) 6395 * -) Check if Panel Scaler is active on LVDS for overlay re-scaling 6396 * -) Save TV registers for further processing 6397 * -) Apply TV settings 6398 */ 6399static void 6400XGIPostSetMode(ScrnInfoPtr pScrn, XGIRegPtr xgiReg) 6401{ 6402 XGIPtr pXGI = XGIPTR(pScrn); 6403/* unsigned char usScratchCR17; 6404 Bool flag = FALSE; 6405 Bool doit = TRUE; */ 6406 int myclock; 6407 unsigned char sr2b, sr2c, tmpreg; 6408 float num, denum, postscalar, divider; 6409 PDEBUG(ErrorF(" XGIPostSetMode(). \n")); 6410#ifdef TWDEBUG 6411 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1off is %d\n", pXGI->CRT1off); 6412#endif 6413 6414#ifdef UNLOCK_ALWAYS 6415 xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); 6416#endif 6417 6418 /* Determine if the video overlay can be used */ 6419 if (!pXGI->NoXvideo) { 6420 inXGIIDXREG(XGISR, 0x2b, sr2b); 6421 inXGIIDXREG(XGISR, 0x2c, sr2c); 6422 divider = (sr2b & 0x80) ? 2.0 : 1.0; 6423 postscalar = (sr2c & 0x80) ? 6424 ((((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : 6425 (((sr2c >> 5) & 0x03) + 1.0); 6426 num = (sr2b & 0x7f) + 1.0; 6427 denum = (sr2c & 0x1f) + 1.0; 6428 myclock = 6429 (int) ((14318 * (divider / postscalar) * (num / denum)) / 1000); 6430 6431 pXGI->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT1OVERLAYGAMMA); 6432/* switch(pXGI->xgi_HwDevExt.jChipType) { 6433 break; 6434 } 6435 */ 6436 if (!(pXGI->MiscFlags & MISC_CRT1OVERLAY)) { 6437 if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI)) 6438 xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3, 6439 "Current dotclock (%dMhz) too high for video overlay on CRT1\n", 6440 myclock); 6441 } 6442 } 6443 6444 /* Determine if the Panel Link scaler is active */ 6445 pXGI->MiscFlags &= ~MISC_PANELLINKSCALER; 6446 if (pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)) { 6447 if (pXGI->VBFlags & CRT1_LCDA) { 6448 inXGIIDXREG(XGIPART1, 0x35, tmpreg); 6449 tmpreg &= 0x04; 6450 if (!tmpreg) 6451 pXGI->MiscFlags |= MISC_PANELLINKSCALER; 6452 } 6453 } 6454 6455 /* Determine if our very special TV mode is active */ 6456 pXGI->MiscFlags &= ~MISC_TVNTSC1024; 6457 if ((pXGI->XGI_Pr->VBType & VB_XGIVB) && (pXGI->VBFlags & CRT2_TV) 6458 && (!(pXGI->VBFlags & TV_HIVISION))) { 6459 if (((pXGI->VBFlags & TV_YPBPR) && (pXGI->VBFlags & TV_YPBPR525I)) 6460 || ((!(pXGI->VBFlags & TV_YPBPR)) 6461 && (pXGI->VBFlags & (TV_NTSC | TV_PALM)))) { 6462 inXGIIDXREG(XGICR, 0x34, tmpreg); 6463 tmpreg &= 0x7f; 6464 if ((tmpreg == 0x64) || (tmpreg == 0x4a) || (tmpreg == 0x38)) { 6465 pXGI->MiscFlags |= MISC_TVNTSC1024; 6466 } 6467 } 6468 } 6469 6470 /* Reset XV gamma correction */ 6471 if (pXGI->ResetXvGamma) { 6472 (pXGI->ResetXvGamma) (pScrn); 6473 } 6474 6475 /* Apply TV settings given by options 6476 * Do this even in DualHeadMode: 6477 * - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1 6478 * - if this is called by SetModeCRT2, CRT2 mode has changed (duh!) 6479 * -> Hence, in both cases, the settings must be re-applied. 6480 */ 6481} 6482 6483 6484USHORT 6485XGI_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, 6486 unsigned long VBFlags) 6487{ 6488 XGIPtr pXGI = XGIPTR(pScrn); 6489 UShort i = (pXGI->CurrentLayout.bitsPerPixel + 7) / 8 - 1; 6490 6491 if ((VBFlags & CRT1_LCDA)) { 6492 if ((mode->HDisplay > pXGI->LCDwidth) || 6493 (mode->VDisplay > pXGI->LCDheight)) { 6494 return 0; 6495 } 6496 } 6497 6498 return XGI_GetModeID(VBFlags, mode->HDisplay, mode->VDisplay, 6499 i, pXGI->LCDwidth, pXGI->LCDheight); 6500} 6501 6502/* Calculate the vertical refresh rate from a mode */ 6503int 6504XGICalcVRate(DisplayModePtr mode) 6505{ 6506 float hsync, refresh = 0; 6507 6508 if (mode->HSync > 0.0) 6509 hsync = mode->HSync; 6510 else if (mode->HTotal > 0) 6511 hsync = (float) mode->Clock / (float) mode->HTotal; 6512 else 6513 hsync = 0.0; 6514 6515 if (mode->VTotal > 0) 6516 refresh = hsync * 1000.0 / mode->VTotal; 6517 6518 if (mode->Flags & V_INTERLACE) 6519 refresh *= 2.0; 6520 6521 if (mode->Flags & V_DBLSCAN) 6522 refresh /= 2.0; 6523 6524 if (mode->VScan > 1) 6525 refresh /= mode->VScan; 6526 6527 if (mode->VRefresh > 0.0) 6528 refresh = mode->VRefresh; 6529 6530 if (hsync == 0 || refresh == 0) 6531 return (0); 6532 6533 return ((int) (refresh)); 6534} 6535 6536/* Calculate CR33 (rate index) for CRT1. 6537 * Calculation is done using currentmode, therefore it is 6538 * recommended to set VertRefresh and HorizSync to correct 6539 * values in config file. 6540 */ 6541unsigned char 6542XGISearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode) 6543{ 6544 XGIPtr pXGI = XGIPTR(pScrn); 6545 int i = 0; 6546 int irefresh; 6547 unsigned short xres = mode->HDisplay; 6548 unsigned short yres = mode->VDisplay; 6549 unsigned char index; 6550 BOOLEAN checkxgi730 = FALSE; 6551 6552 irefresh = XGICalcVRate(mode); 6553 if (!irefresh) { 6554 if (xres == 800 || xres == 1024 || xres == 1280) 6555 return 0x02; 6556 else 6557 return 0x01; 6558 } 6559 6560#ifdef TWDEBUG 6561 xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh); 6562#endif 6563 6564 /* We need the REAL refresh rate here */ 6565 if (mode->Flags & V_INTERLACE) 6566 irefresh /= 2; 6567 6568 /* Do not multiply by 2 when DBLSCAN! */ 6569 6570#ifdef TWDEBUG 6571 xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh); 6572#endif 6573 6574 index = 0; 6575 while ((xgix_vrate[i].idx != 0) && (xgix_vrate[i].xres <= xres)) { 6576 if ((xgix_vrate[i].xres == xres) && (xgix_vrate[i].yres == yres)) { 6577 if ((checkxgi730 == FALSE) 6578 || (xgix_vrate[i].XGI730valid32bpp == TRUE)) { 6579 if (xgix_vrate[i].refresh == irefresh) { 6580 index = xgix_vrate[i].idx; 6581 break; 6582 } 6583 else if (xgix_vrate[i].refresh > irefresh) { 6584 if ((xgix_vrate[i].refresh - irefresh) <= 3) { 6585 index = xgix_vrate[i].idx; 6586 } 6587 else if (((checkxgi730 == FALSE) 6588 || (xgix_vrate[i - 1].XGI730valid32bpp == TRUE)) 6589 && ((irefresh - xgix_vrate[i - 1].refresh) <= 2) 6590 && (xgix_vrate[i].idx != 1)) { 6591 index = xgix_vrate[i - 1].idx; 6592 } 6593 break; 6594 } 6595 else if ((irefresh - xgix_vrate[i].refresh) <= 2) { 6596 index = xgix_vrate[i].idx; 6597 break; 6598 } 6599 } 6600 } 6601 i++; 6602 } 6603 6604 /* Jong 10/19/2007; merge code */ 6605 /* Adjust to match table of VBIOS */ 6606 switch(pXGI->Chipset) 6607 { 6608 case PCI_CHIP_XGIXG20: 6609 case PCI_CHIP_XGIXG21: 6610 if((xres == 640) && (yres == 480)) 6611 { 6612 if (xgix_vrate[index].refresh>85) 6613 { 6614 index = 4; 6615 } 6616 } 6617 6618 if((xres == 800) && (yres == 600)) 6619 { 6620 if (xgix_vrate[index].refresh>85) 6621 { 6622 index = 5; 6623 } 6624 6625 if (index>0) 6626 { 6627 index --; 6628 } 6629 } 6630 6631 if((xres == 1024) && (yres == 768)) 6632 { 6633 if (xgix_vrate[index].refresh>85) 6634 { 6635 index = 5; 6636 } 6637 6638 if (index>0) 6639 { 6640 index --; 6641 } 6642 } 6643 6644 if((xres == 1280) && (yres == 1024)) 6645 { 6646 if (index>0) 6647 { 6648 index --; 6649 } 6650 } 6651 6652 if((xres == 1600) && (yres == 1200)) 6653 { 6654 if (xgix_vrate[index].refresh>85) 6655 { 6656 index = 5; 6657 } 6658 } 6659 6660 if((xres >= 1920) && (yres >= 1440)) 6661 { 6662 index = 0; 6663 } 6664 6665 break; 6666 6667 case PCI_CHIP_XGIXG27: 6668 6669 if((xres == 640) && (yres == 480)) 6670 { 6671 if (xgix_vrate[index].refresh>85) 6672 { 6673 index = 4; 6674 } 6675 } 6676 6677 if((xres == 800) && (yres == 600)) 6678 { 6679 if (xgix_vrate[index].refresh>85) 6680 { 6681 index = 5; 6682 } 6683 6684 if (index>0) 6685 { 6686 index --; 6687 } 6688 } 6689 6690 if((xres == 1024) && (yres == 768)) 6691 { 6692 if (xgix_vrate[index].refresh>85) 6693 { 6694 index = 5; 6695 } 6696 6697 if (index>0) 6698 { 6699 index --; 6700 } 6701 } 6702 6703 if((xres == 1280) && (yres == 1024)) 6704 { 6705 if (index>0) 6706 { 6707 index --; 6708 } 6709 } 6710 6711 if((xres == 1600) && (yres == 1200)) 6712 { 6713 if (xgix_vrate[index].refresh>85) 6714 { 6715 index = 5; 6716 } 6717 } 6718 6719 break; 6720 6721 default: 6722 break; 6723 } 6724 6725 if (index > 0) 6726 return index; 6727 else { 6728 /* Default Rate index */ 6729 if (xres == 800 || xres == 1024 || xres == 1280) 6730 return 0x02; 6731 else 6732 return 0x01; 6733 } 6734} 6735 6736 6737#define MODEID_OFF 0x449 6738 6739unsigned char 6740XGI_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id) 6741{ 6742 return (XGI_GetSetBIOSScratch(pScrn, MODEID_OFF, id)); 6743} 6744 6745unsigned char 6746XGI_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value) 6747{ 6748 unsigned char ret = 0; 6749#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__)) 6750 unsigned char *base; 6751 6752 base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000); 6753 if (!base) { 6754 XGIErrorLog(pScrn, "(Could not map BIOS scratch area)\n"); 6755 return 0; 6756 } 6757 6758 ret = *(base + offset); 6759 6760 /* value != 0xff means: set register */ 6761 if (value != 0xff) 6762 *(base + offset) = value; 6763 6764 xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000); 6765#endif 6766 return ret; 6767} 6768 6769void 6770xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1, 6771 unsigned char *reg2) 6772{ 6773 register unsigned char val; 6774 unsigned long mylockcalls; 6775 6776 pXGI->lockcalls++; 6777 mylockcalls = pXGI->lockcalls; 6778 6779 /* check if already unlocked */ 6780 inXGIIDXREG(XGISR, 0x05, val); 6781 if (val != 0xa1) { 6782 /* save State */ 6783 if (reg1) 6784 *reg1 = val; 6785 /* unlock */ 6786/* 6787 outb (0x3c4, 0x20); 6788 val4 = inb (0x3c5); 6789 val4 |= 0x20; 6790 outb (0x3c5, val4); 6791*/ 6792 outXGIIDXREG(XGISR, 0x05, 0x86); 6793 inXGIIDXREG(XGISR, 0x05, val); 6794 if (val != 0xA1) { 6795#ifdef TWDEBUG 6796 unsigned char val1, val2; 6797 int i; 6798#endif 6799 XGIErrorLog(pXGI->pScrn, 6800 "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n", 6801 (void *) pXGI, (unsigned long) pXGI->RelIO, val, 6802 mylockcalls); 6803#ifdef TWDEBUG 6804 for (i = 0; i <= 0x3f; i++) { 6805 inXGIIDXREG(XGISR, i, val1); 6806 /* inXGIIDXREG(0x3c4, i, val2); */ 6807 inXGIIDXREG(XGISR, i, val2); 6808 xf86DrvMsg(pXGI->pScrn->scrnIndex, X_INFO, 6809 "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n", 6810 i, val1, val2, mylockcalls); 6811 } 6812#endif 6813 } 6814 } 6815} 6816 6817void 6818xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1, unsigned char reg2) 6819{ 6820 /* restore lock */ 6821#ifndef UNLOCK_ALWAYS 6822 outXGIIDXREG(XGISR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00); 6823#endif 6824} 6825 6826/* Jong 12/03/2007; */ 6827/* 6828void XGICheckModeForMonitor(ScrnInfoPtr pScrn, ) 6829{ 6830 DisplayModePtr pCRT1Modes=pScrn->monitor->Modes; 6831 6832 if ((p = first = pScrn->monitor->Modes)) { 6833 do { 6834 xf86CheckModeForMonitor(p, 6835 n = p->next; 6836 p = n; 6837 } while (p != NULL && p != first); 6838 } 6839 6840 xf86PruneDriverModes(pXGI->CRT2pScrn); 6841} 6842*/ 6843 6844/* Jong 12/05/2007; filter mode list by monitor DDC */ 6845static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC) 6846{ 6847 DisplayModePtr first, p; 6848 6849 if ((p = first = pModeList)) 6850 { 6851 do 6852 { 6853 if(XGICheckModeByDDC(p, pMonitorDDC) == FALSE) 6854 xf86DeleteMode(&pModeList, pModeList); 6855 6856 p = p->next; 6857 } while (p != NULL && p != first); 6858 } 6859} 6860 6861/* Jong 12/05/2007; filter mode list by monitor DDC */ 6862static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC) 6863{ 6864 int i, j; 6865 float VF, HF; 6866 struct detailed_timings *pd_timings; 6867 struct monitor_ranges *pranges; 6868 struct std_timings *pstd_t; 6869 6870 int VRefresh=pMode->VRefresh; 6871 6872 if ((pMode == NULL) || (pMonitorDDC == NULL)) { 6873 return(FALSE); /* ignore */ 6874 } 6875 6876 if( pMode->VRefresh == 0) 6877 VRefresh = (int)((float)(pMode->Clock*1000)/(float)(pMode->VTotal*pMode->HTotal)+0.5); 6878 6879 6880 for (i = 0, j = 0; i < 8; i++, j++) 6881 { 6882 if (establish_timing[j].width == -1) 6883 { 6884 continue; 6885 } 6886 6887 if (pMonitorDDC->timings1.t1 & (1 << i)) 6888 { 6889 if( (establish_timing[j].width == pMode->HDisplay) && 6890 (establish_timing[j].height == pMode->VDisplay) && 6891 (establish_timing[j].VRefresh == VRefresh) ) 6892 return(TRUE); 6893 } 6894 } 6895 6896 for (i = 0; i < 8; i++, j++) 6897 { 6898 if (establish_timing[j].width == -1) 6899 { 6900 continue; 6901 } 6902 6903 if (pMonitorDDC->timings1.t2 & (1 << i)) 6904 { 6905 if( (establish_timing[j].width == pMode->HDisplay) && 6906 (establish_timing[j].height == pMode->VDisplay) && 6907 (establish_timing[j].VRefresh == VRefresh) ) 6908 return(TRUE); 6909 } 6910 } 6911 6912 for (i = 0; i < 8; i++) 6913 { 6914 if ((pMode->HDisplay == pMonitorDDC->timings2[i].hsize) && 6915 (pMode->VDisplay == pMonitorDDC->timings2[i].vsize) && 6916 (VRefresh == pMonitorDDC->timings2[i].refresh)) 6917 return(TRUE); 6918 } 6919 6920/* Jong 12/05/2007; Don't know how to do? */ 6921#if 0 6922 for (i = 0; i < 4; i++) 6923 { 6924 switch (pMonitorDDC->det_mon[i].type) 6925 { 6926 case DS_RANGES: 6927 pranges = &(pMonitorDDC->det_mon[i].section.ranges); 6928 PDEBUG5(ErrorF 6929 ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n", 6930 pranges->min_v, pranges->max_v, pranges->min_h, 6931 pranges->max_h, pranges->max_clock)); 6932 6933 if (range->loH > pranges->min_h) 6934 range->loH = pranges->min_h; 6935 if (range->loV > pranges->min_v) 6936 range->loV = pranges->min_v; 6937 if (range->hiH < pranges->max_h) 6938 range->hiH = pranges->max_h; 6939 if (range->hiV < pranges->max_v) 6940 range->hiV = pranges->max_v; 6941 PDEBUG5(ErrorF 6942 ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, 6943 range->loV, range->hiH, range->hiV)); 6944 break; 6945 6946 case DS_STD_TIMINGS: 6947 pstd_t = pMonitorDDC->det_mon[i].section.std_t; 6948 for (j = 0; j < 5; j++) { 6949 int k; 6950 PDEBUG5(ErrorF 6951 ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n", 6952 j, pstd_t[j].hsize, pstd_t[j].vsize, 6953 pstd_t[j].refresh, pstd_t[j].id)); 6954 for (k = 0; StdTiming[k].width != -1; k++) { 6955 if ((StdTiming[k].width == pstd_t[j].hsize) && 6956 (StdTiming[k].height == pstd_t[j].vsize) && 6957 (StdTiming[k].VRefresh == pstd_t[j].refresh)) { 6958 if (range->loH > StdTiming[k].HSync) 6959 range->loH = StdTiming[k].HSync; 6960 if (range->hiH < StdTiming[k].HSync) 6961 range->hiH = StdTiming[k].HSync; 6962 if (range->loV > StdTiming[k].VRefresh) 6963 range->loV = StdTiming[k].VRefresh; 6964 if (range->hiV < StdTiming[k].VRefresh) 6965 range->hiV = StdTiming[k].VRefresh; 6966 break; 6967 } 6968 6969 } 6970 } 6971 break; 6972 6973 case DT: 6974 6975 pd_timings = &pMonitorDDC->det_mon[i].section.d_timings; 6976 6977 HF = pd_timings->clock / (pd_timings->h_active + 6978 pd_timings->h_blanking); 6979 VF = HF / (pd_timings->v_active + pd_timings->v_blanking); 6980 HF /= 1000; /* into KHz Domain */ 6981 if (range->loH > HF) 6982 range->loH = HF; 6983 if (range->hiH < HF) 6984 range->hiH = HF; 6985 if (range->loV > VF) 6986 range->loV = VF; 6987 if (range->hiV < VF) 6988 range->hiV = VF; 6989 PDEBUG(ErrorF 6990 ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n", 6991 HF, VF, range->loH, range->loV, range->hiH, range->hiV)); 6992 break; 6993 } 6994 } 6995#endif 6996 6997 return(FALSE); 6998} 6999 7000#ifdef DEBUG 7001void 7002XGIDumpSR(ScrnInfoPtr pScrn) 7003{ 7004 XGIPtr pXGI = XGIPTR(pScrn); 7005 7006 int i, j; 7007 unsigned long temp; 7008 7009 ErrorF 7010 ("----------------------------------------------------------------------\n"); 7011 ErrorF("SR xx\n"); 7012 ErrorF 7013 ("----------------------------------------------------------------------\n"); 7014 for (i = 0; i < 0x40; i += 0x10) { 7015 ErrorF("SR[%02X]:", i); 7016 for (j = 0; j < 16; j++) { 7017 inXGIIDXREG(XGISR, (i + j), temp); 7018 ErrorF(" %02lX", temp); 7019 } 7020 ErrorF("\n"); 7021 } 7022 ErrorF("\n"); 7023} 7024 7025void 7026XGIDumpCR(ScrnInfoPtr pScrn) 7027{ 7028 XGIPtr pXGI = XGIPTR(pScrn); 7029 7030 int i, j; 7031 unsigned long temp; 7032 7033 ErrorF 7034 ("----------------------------------------------------------------------\n"); 7035 ErrorF("CR xx\n"); 7036 ErrorF 7037 ("----------------------------------------------------------------------\n"); 7038 for (i = 0; i < 0x100; i += 0x10) { 7039 ErrorF("CR[%02X]:", i); 7040 for (j = 0; j < 16; j++) { 7041 inXGIIDXREG(XGICR, (i + j), temp); 7042 ErrorF(" %02lX", temp); 7043 } 7044 ErrorF("\n"); 7045 } 7046} 7047 7048void 7049XGIDumpGR(ScrnInfoPtr pScrn) 7050{ 7051 XGIPtr pXGI = XGIPTR(pScrn); 7052 7053 int i; 7054 unsigned long temp; 7055 7056 ErrorF 7057 ("----------------------------------------------------------------------\n"); 7058 ErrorF("GR xx\n"); 7059 ErrorF 7060 ("----------------------------------------------------------------------\n"); 7061 ErrorF("GR:"); 7062 for (i = 0; i < 0x9; i += 0x10) { 7063 inXGIIDXREG(XGISR, i, temp); 7064 ErrorF(" %02lX", temp); 7065 } 7066 ErrorF("\n"); 7067} 7068 7069#if 0 7070void 7071XGIDumpPart0(ScrnInfoPtr pScrn) 7072{ 7073 XGIPtr pXGI = XGIPTR(pScrn); 7074 int i, j; 7075 unsigned long temp; 7076 7077 ErrorF 7078 ("----------------------------------------------------------------------\n"); 7079 ErrorF("PART0 xx\n"); 7080 ErrorF 7081 ("----------------------------------------------------------------------\n"); 7082 for (i = 0; i < 0x50; i += 0x10) { 7083 ErrorF("PART0[%02X]:", i); 7084 for (j = 0; j < 0x10; j++) { 7085 inXGIIDXREG(XGIPART0, (i + j), temp); 7086 ErrorF(" %02lX", temp); 7087 } 7088 ErrorF("\n"); 7089 } 7090} 7091 7092void 7093XGIDumpPart05(ScrnInfoPtr pScrn) 7094{ 7095 XGIPtr pXGI = XGIPTR(pScrn); 7096 int i, j; 7097 unsigned long temp; 7098 ErrorF 7099 ("----------------------------------------------------------------------\n"); 7100 ErrorF("PART05 xx\n"); 7101 ErrorF 7102 ("----------------------------------------------------------------------\n"); 7103 for (i = 0; i < 0x50; i += 0x10) { 7104 ErrorF("PART05[%02X]:", i); 7105 for (j = 0; j < 0x10; j++) { 7106 inXGIIDXREG(XGIPART05, (i + j), temp); 7107 ErrorF(" %02lX", temp); 7108 } 7109 ErrorF("\n"); 7110 } 7111} 7112 7113void 7114XGIDumpPart1(ScrnInfoPtr pScrn) 7115{ 7116 XGIPtr pXGI = XGIPTR(pScrn); 7117 7118 int i, j; 7119 unsigned long temp; 7120 7121 ErrorF 7122 ("----------------------------------------------------------------------\n"); 7123 ErrorF("PART1 xx\n"); 7124 ErrorF 7125 ("----------------------------------------------------------------------\n"); 7126 for (i = 0; i < 0x100; i += 0x10) { 7127 ErrorF("PART1[%02X]:", i); 7128 for (j = 0; j < 0x10; j++) { 7129 inXGIIDXREG(XGIPART1, (i + j), temp); 7130 ErrorF(" %02lX", temp); 7131 } 7132 ErrorF("\n"); 7133 } 7134} 7135 7136void 7137XGIDumpPart2(ScrnInfoPtr pScrn) 7138{ 7139 XGIPtr pXGI = XGIPTR(pScrn); 7140 7141 int i, j; 7142 unsigned long temp; 7143 7144 ErrorF 7145 ("----------------------------------------------------------------------\n"); 7146 ErrorF("PART2 xx\n"); 7147 ErrorF 7148 ("----------------------------------------------------------------------\n"); 7149 for (i = 0; i < 0x100; i += 0x10) { 7150 ErrorF("PART2[%02X]:", i); 7151 for (j = 0; j < 0x10; j++) { 7152 inXGIIDXREG(XGIPART2, (i + j), temp); 7153 ErrorF(" %02lX", temp); 7154 } 7155 ErrorF("\n"); 7156 } 7157} 7158 7159void 7160XGIDumpPart3(ScrnInfoPtr pScrn) 7161{ 7162 XGIPtr pXGI = XGIPTR(pScrn); 7163 7164 int i, j; 7165 unsigned long temp; 7166 7167 ErrorF 7168 ("----------------------------------------------------------------------\n"); 7169 ErrorF("PART3 xx\n"); 7170 ErrorF 7171 ("----------------------------------------------------------------------\n"); 7172 7173 for (i = 0; i < 0x100; i += 0x10) { 7174 ErrorF("PART3[%02X]:", i); 7175 for (j = 0; j < 0x10; j++) { 7176 inXGIIDXREG(XGIPART3, (i + j), temp); 7177 ErrorF(" %02lX", temp); 7178 } 7179 ErrorF("\n"); 7180 } 7181} 7182 7183void 7184XGIDumpPart4(ScrnInfoPtr pScrn) 7185{ 7186 XGIPtr pXGI = XGIPTR(pScrn); 7187 7188 int i, j; 7189 unsigned long temp; 7190 7191 ErrorF 7192 ("----------------------------------------------------------------------\n"); 7193 ErrorF("PART4 xx\n"); 7194 ErrorF 7195 ("----------------------------------------------------------------------\n"); 7196 for (i = 0; i < 0x100; i += 0x10) { 7197 ErrorF("PART4[%02X]:", i); 7198 for (j = 0; j < 0x10; j++) { 7199 inXGIIDXREG(XGIPART4, (i + j), temp); 7200 ErrorF(" %02lX", temp); 7201 } 7202 ErrorF("\n"); 7203 } 7204} 7205#endif 7206 7207void 7208XGIDumpMMIO(ScrnInfoPtr pScrn) 7209{ 7210 XGIPtr pXGI = XGIPTR(pScrn); 7211 7212 int i; 7213 unsigned long temp; 7214/* 7215 ErrorF("----------------------------------------------------------------------\n") ; 7216 ErrorF("MMIO 85xx\n") ; 7217 ErrorF("----------------------------------------------------------------------\n") ; 7218 for( i = 0x8500 ; i < 0x8600 ; i+=0x10 ) 7219 { 7220 ErrorF("[%04X]: %08lX %08lX %08lX %08lX\n",i, 7221 XGIMMIOLONG(i), 7222 XGIMMIOLONG(i+4), 7223 XGIMMIOLONG(i+8), 7224 XGIMMIOLONG(i+12)) ; 7225 } 7226*/ 7227} 7228#endif /* DEBUG */ 7229 7230void 7231XGIDumpRegs(ScrnInfoPtr pScrn) 7232{ 7233#ifdef DEBUG 7234 7235 XGIPtr pXGI = XGIPTR(pScrn); 7236 7237 XGIDumpSR(pScrn); 7238 XGIDumpCR(pScrn); 7239// XGIDumpGR(pScrn); 7240// XGIDumpPalette(pScrn); 7241 XGIDumpMMIO(pScrn); 7242 7243 /* 7244 if (pXGI->Chipset != PCI_CHIP_XGIXG20) { 7245 XGIDumpPart0(pScrn); 7246 XGIDumpPart05(pScrn); 7247 XGIDumpPart1(pScrn); 7248 XGIDumpPart2(pScrn); 7249 XGIDumpPart3(pScrn); 7250 XGIDumpPart4(pScrn); 7251 } */ 7252 7253#endif /* DEBUG */ 7254} 7255 7256 7257void 7258XGIDumpPalette(ScrnInfoPtr pScrn) 7259{ 7260#ifdef DEBUG 7261 XGIPtr pXGI = XGIPTR(pScrn); 7262 unsigned temp[3]; 7263 int i, j; 7264 7265 ErrorF 7266 ("----------------------------------------------------------------------\n"); 7267 ErrorF("Palette \n"); 7268 ErrorF 7269 ("----------------------------------------------------------------------\n"); 7270 for (i = 0; i < 0xFF; i += 0x04) { 7271 for (j = 0; j < 16; j++) { 7272 /* outb(0x3c7, i + j); */ 7273 outb(XGISR+3, i + j); 7274 7275 /* 7276 temp[0] = inb(0x3c9); 7277 temp[1] = inb(0x3c9); 7278 temp[2] = inb(0x3c9); */ 7279 temp[0] = inb(XGISR+5); 7280 temp[1] = inb(XGISR+5); 7281 temp[2] = inb(XGISR+5); 7282 7283 ErrorF("PA[%02X]: %02X %02X %02X", i + j, 7284 temp[0], temp[1], temp[2]); 7285 } 7286 ErrorF("\n"); 7287 } 7288 ErrorF("\n"); 7289#endif 7290} 7291 7292