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