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