ast_driver.c revision de78e416
1/* 2 * Copyright (c) 2005 ASPEED Technology Inc. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of the authors not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. The authors makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include <config.h> 25#endif 26#include "xf86.h" 27#include "xf86_OSproc.h" 28#include "xf86Resources.h" 29#include "xf86RAC.h" 30#include "xf86cmap.h" 31#include "compiler.h" 32#include "mibstore.h" 33#include "vgaHW.h" 34#include "mipointer.h" 35#include "micmap.h" 36 37#include "fb.h" 38#include "regionstr.h" 39#include "xf86xv.h" 40#include <X11/extensions/Xv.h> 41#include "vbe.h" 42 43#include "xf86PciInfo.h" 44#include "xf86Pci.h" 45 46/* framebuffer offscreen manager */ 47#include "xf86fbman.h" 48 49/* include xaa includes */ 50#include "xaa.h" 51#include "xaarop.h" 52 53/* H/W cursor support */ 54#include "xf86Cursor.h" 55 56/* Driver specific headers */ 57#include "ast.h" 58 59/* external reference fucntion */ 60extern Bool ASTMapMem(ScrnInfoPtr pScrn); 61extern Bool ASTUnmapMem(ScrnInfoPtr pScrn); 62extern Bool ASTMapMMIO(ScrnInfoPtr pScrn); 63extern void ASTUnmapMMIO(ScrnInfoPtr pScrn); 64 65extern void vASTOpenKey(ScrnInfoPtr pScrn); 66extern Bool bASTRegInit(ScrnInfoPtr pScrn); 67extern void GetDRAMInfo(ScrnInfoPtr pScrn); 68extern ULONG GetVRAMInfo(ScrnInfoPtr pScrn); 69extern ULONG GetMaxDCLK(ScrnInfoPtr pScrn); 70extern void GetChipType(ScrnInfoPtr pScrn); 71extern void vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual); 72extern void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); 73extern void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base); 74extern Bool ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode); 75extern Bool GetVGA2EDID(ScrnInfoPtr pScrn, unsigned char *pEDIDBuffer); 76extern void vInitDRAMReg(ScrnInfoPtr pScrn); 77extern Bool bIsVGAEnabled(ScrnInfoPtr pScrn); 78extern void ASTBlankScreen(ScrnInfoPtr pScreen, Bool unblack); 79extern Bool InitVGA(ScrnInfoPtr pScrn); 80 81extern Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST); 82extern Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST); 83extern void vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST); 84 85extern Bool ASTAccelInit(ScreenPtr pScreen); 86 87extern Bool ASTCursorInit(ScreenPtr pScreen); 88extern void ASTHideCursor(ScrnInfoPtr pScrn); 89 90/* Mandatory functions */ 91static void ASTIdentify(int flags); 92const OptionInfoRec *ASTAvailableOptions(int chipid, int busid); 93static Bool ASTProbe(DriverPtr drv, int flags); 94static Bool ASTPreInit(ScrnInfoPtr pScrn, int flags); 95static Bool ASTScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); 96Bool ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 97void ASTAdjustFrame(int scrnIndex, int x, int y, int flags); 98static Bool ASTEnterVT(int scrnIndex, int flags); 99static void ASTLeaveVT(int scrnIndex, int flags); 100static void ASTFreeScreen(int scrnIndex, int flags); 101static ModeStatus ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); 102 103/* Internally used functions */ 104static Bool ASTGetRec(ScrnInfoPtr pScrn); 105static void ASTFreeRec(ScrnInfoPtr pScrn); 106static Bool ASTSaveScreen(ScreenPtr pScreen, Bool unblack); 107static Bool ASTCloseScreen(int scrnIndex, ScreenPtr pScreen); 108static void ASTSave(ScrnInfoPtr pScrn); 109static void ASTRestore(ScrnInfoPtr pScrn); 110static void ASTProbeDDC(ScrnInfoPtr pScrn, int index); 111static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index); 112static void vFillASTModeInfo (ScrnInfoPtr pScrn); 113static Bool ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 114 115/* 116 * This is intentionally screen-independent. It indicates the binding 117 * choice made in the first PreInit. 118 */ 119_X_EXPORT DriverRec AST = { 120 AST_VERSION, 121 AST_DRIVER_NAME, 122 ASTIdentify, 123 ASTProbe, 124 ASTAvailableOptions, 125 NULL, 126 0 127}; 128 129/* Chipsets */ 130static SymTabRec ASTChipsets[] = { 131 {PCI_CHIP_AST2000, "ASPEED Graphics Family"}, 132 {PCI_CHIP_AST2100, "ASPEED Graphics Family"}, 133 {-1, NULL} 134}; 135 136static PciChipsets ASTPciChipsets[] = { 137 {PCI_CHIP_AST2000, PCI_CHIP_AST2000, RES_SHARED_VGA}, 138 {PCI_CHIP_AST2100, PCI_CHIP_AST2100, RES_SHARED_VGA}, 139 {-1, -1, RES_UNDEFINED } 140}; 141 142typedef enum { 143 OPTION_NOACCEL, 144 OPTION_MMIO2D, 145 OPTION_SW_CURSOR, 146 OPTION_HWC_NUM, 147 OPTION_ENG_CAPS, 148 OPTION_DBG_SELECT, 149 OPTION_NO_DDC, 150 OPTION_VGA2_CLONE 151} ASTOpts; 152 153static const OptionInfoRec ASTOptions[] = { 154 {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, 155 {OPTION_MMIO2D, "MMIO2D", OPTV_BOOLEAN, {0}, FALSE}, 156 {OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, 157 {OPTION_HWC_NUM, "HWCNumber", OPTV_INTEGER, {0}, FALSE}, 158 {OPTION_ENG_CAPS, "ENGCaps", OPTV_INTEGER, {0}, FALSE}, 159 {OPTION_DBG_SELECT, "DBGSelect", OPTV_INTEGER, {0}, FALSE}, 160 {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE}, 161 {OPTION_VGA2_CLONE, "VGA2Clone", OPTV_BOOLEAN, {0}, FALSE}, 162 {-1, NULL, OPTV_NONE, {0}, FALSE} 163}; 164 165#ifdef XFree86LOADER 166 167static MODULESETUPPROTO(astSetup); 168 169static XF86ModuleVersionInfo astVersRec = { 170 AST_DRIVER_NAME, 171 MODULEVENDORSTRING, 172 MODINFOSTRING1, 173 MODINFOSTRING2, 174 XORG_VERSION_CURRENT, 175 AST_MAJOR_VERSION, AST_MINOR_VERSION, AST_PATCH_VERSION, 176 ABI_CLASS_VIDEODRV, 177#ifdef PATCH_ABI_VERSION 178 ABI_VIDEODRV_VERSION_PATCH, 179#else 180 ABI_VIDEODRV_VERSION, 181#endif 182 MOD_CLASS_VIDEODRV, 183 {0, 0, 0, 0} 184}; 185 186_X_EXPORT XF86ModuleData astModuleData = { &astVersRec, astSetup, NULL }; 187 188static pointer 189astSetup(pointer module, pointer opts, int *errmaj, int *errmin) 190{ 191 static Bool setupDone = FALSE; 192 193 /* This module should be loaded only once, but check to be sure. 194 */ 195 if (!setupDone) { 196 setupDone = TRUE; 197 xf86AddDriver(&AST, module, 0); 198 199 /* 200 * The return value must be non-NULL on success even though there 201 * is no TearDownProc. 202 */ 203 return (pointer) TRUE; 204 } else { 205 if (errmaj) 206 *errmaj = LDR_ONCEONLY; 207 return NULL; 208 } 209} 210 211#endif /* XFree86LOADER */ 212 213/* 214 * ASTIdentify -- 215 * 216 * Returns the string name for the driver based on the chipset. In this 217 * case it will always be an AST, so we can return a static string. 218 * 219 */ 220static void 221ASTIdentify(int flags) 222{ 223 xf86PrintChipsets(AST_NAME, "Driver for ASPEED Graphics Chipsets", 224 ASTChipsets); 225} 226 227const OptionInfoRec * 228ASTAvailableOptions(int chipid, int busid) 229{ 230 231 return ASTOptions; 232 233} 234 235/* 236 * ASTProbe -- 237 * 238 * Look through the PCI bus to find cards that are AST boards. 239 * Setup the dispatch table for the rest of the driver functions. 240 * 241 */ 242static Bool 243ASTProbe(DriverPtr drv, int flags) 244{ 245 int i, numUsed, numDevSections, *usedChips; 246 Bool foundScreen = FALSE; 247 GDevPtr *devSections; 248 249 /* 250 * Find the config file Device sections that match this 251 * driver, and return if there are none. 252 */ 253 if ((numDevSections = 254 xf86MatchDevice(AST_DRIVER_NAME, &devSections)) <= 0) { 255 return FALSE; 256 } 257 258#ifndef XSERVER_LIBPCIACCESS 259 /* 260 * This probing is just checking the PCI data the server already 261 * collected. 262 */ 263 if (xf86GetPciVideoInfo() == NULL) { 264 return FALSE; 265 } 266#endif 267 268 numUsed = xf86MatchPciInstances(AST_NAME, PCI_VENDOR_AST, 269 ASTChipsets, ASTPciChipsets, 270 devSections, numDevSections, 271 drv, &usedChips); 272 273 xfree(devSections); 274 275 if (flags & PROBE_DETECT) { 276 if (numUsed > 0) 277 foundScreen = TRUE; 278 } else { 279 for (i = 0; i < numUsed; i++) { 280 ScrnInfoPtr pScrn = NULL; 281 282 /* Allocate new ScrnInfoRec and claim the slot */ 283 if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], 284 ASTPciChipsets, 0, 0, 0, 0, 0))) 285 { 286 EntityInfoPtr pEnt; 287 288 pEnt = xf86GetEntityInfo(usedChips[i]); 289 290 pScrn->driverVersion = AST_VERSION; 291 pScrn->driverName = AST_DRIVER_NAME; 292 pScrn->name = AST_NAME; 293 294 pScrn->Probe = ASTProbe; 295 pScrn->PreInit = ASTPreInit; 296 pScrn->ScreenInit = ASTScreenInit; 297 pScrn->SwitchMode = ASTSwitchMode; 298 pScrn->AdjustFrame = ASTAdjustFrame; 299 pScrn->EnterVT = ASTEnterVT; 300 pScrn->LeaveVT = ASTLeaveVT; 301 pScrn->FreeScreen = ASTFreeScreen; 302 pScrn->ValidMode = ASTValidMode; 303 304 foundScreen = TRUE; 305 306 } /* end of if */ 307 } /* end of for-loop */ 308 } /* end of if flags */ 309 310 xfree(usedChips); 311 312 return foundScreen; 313} 314 315/* 316 * ASTPreInit -- 317 * 318 * Do initial setup of the board before we know what resolution we will 319 * be running at. 320 * 321 */ 322static Bool 323ASTPreInit(ScrnInfoPtr pScrn, int flags) 324{ 325 EntityInfoPtr pEnt; 326 vgaHWPtr hwp; 327 int flags24; 328 rgb defaultWeight = { 0, 0, 0 }; 329 330 ASTRecPtr pAST; 331 332 ClockRangePtr clockRanges; 333 int i; 334 MessageType from; 335 336 /* Suport one adapter only now */ 337 if (pScrn->numEntities != 1) 338 return FALSE; 339 340 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 341 342 if (flags & PROBE_DETECT) { 343 ASTProbeDDC(pScrn, pEnt->index); 344 return TRUE; 345 } 346 347 if (pEnt->location.type != BUS_PCI) 348 return FALSE; 349 350 if (xf86RegisterResources(pEnt->index, 0, ResExclusive)) 351 return FALSE; 352 353 /* The vgahw module should be loaded here when needed */ 354 if (!xf86LoadSubModule(pScrn, "vgahw")) 355 return FALSE; 356 357 /* The fb module should be loaded here when needed */ 358 if (!xf86LoadSubModule(pScrn, "fb")) 359 return FALSE; 360 361 /* Allocate a vgaHWRec */ 362 if (!vgaHWGetHWRec(pScrn)) 363 return FALSE; 364 hwp = VGAHWPTR(pScrn); 365 366 /* Color Depth Check */ 367 flags24 = Support32bppFb; 368 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) { 369 return FALSE; 370 } else { 371 switch (pScrn->depth) { 372 case 8: 373 case 16: 374 case 24: 375 break; 376 default: 377 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 378 "Given depth (%d) is not supported by ast driver\n", 379 pScrn->depth); 380 return FALSE; 381 } 382 } 383 xf86PrintDepthBpp(pScrn); 384 385 switch (pScrn->bitsPerPixel) { 386 case 8: 387 case 16: 388 case 32: 389 break; 390 default: 391 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 392 "Given bpp (%d) is not supported by ast driver\n", 393 pScrn->bitsPerPixel); 394 return FALSE; 395 } 396 397 /* fill pScrn misc. */ 398 pScrn->progClock = TRUE; 399 pScrn->rgbBits = 6; 400 pScrn->monitor = pScrn->confScreen->monitor; /* should be initialized before set gamma */ 401 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 402 pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 403 404 /* 405 * If the driver can do gamma correction, it should call xf86SetGamma() 406 * here. 407 */ 408 { 409 Gamma zeros = { 0.0, 0.0, 0.0 }; 410 411 if (!xf86SetGamma(pScrn, zeros)) { 412 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call xf86SetGamma failed \n"); 413 return FALSE; 414 } 415 } 416 417 418 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) { 419 return FALSE; 420 } 421 422 if (!xf86SetDefaultVisual(pScrn, -1)) { 423 return FALSE; 424 } 425 426 /* Allocate driverPrivate */ 427 if (!ASTGetRec(pScrn)) { 428 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call ASTGetRec failed \n"); 429 return FALSE; 430 } 431 432 /* Fill AST Info */ 433 pAST = ASTPTR(pScrn); 434 pAST->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 435 pAST->PciInfo = xf86GetPciInfoForEntity(pAST->pEnt->index); 436#ifndef XSERVER_LIBPCIACCESS 437 pAST->PciTag = pciTag(pAST->PciInfo->bus, pAST->PciInfo->device, 438 pAST->PciInfo->func); 439#endif 440 441 /* Process the options 442 * pScrn->confScreen, pScrn->display, pScrn->monitor, pScrn->numEntities, 443 * and pScrn->entityList should be initialized before 444 */ 445 xf86CollectOptions(pScrn, NULL); 446 if (!(pAST->Options = xalloc(sizeof(ASTOptions)))) 447 { 448 ASTFreeRec(pScrn); 449 return FALSE; 450 } 451 memcpy(pAST->Options, ASTOptions, sizeof(ASTOptions)); 452 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAST->Options); 453 454 /* 455 * Set the Chipset and ChipRev, allowing config file entries to 456 * override. 457 */ 458 if (pAST->pEnt->device->chipset && *pAST->pEnt->device->chipset) { 459 pScrn->chipset = pAST->pEnt->device->chipset; 460 from = X_CONFIG; 461 } else if (pAST->pEnt->device->chipID >= 0) { 462 pScrn->chipset = (char *)xf86TokenToString(ASTChipsets, 463 pAST->pEnt->device->chipID); 464 from = X_CONFIG; 465 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 466 pAST->pEnt->device->chipID); 467 } else { 468 from = X_PROBED; 469 pScrn->chipset = (char *)xf86TokenToString(ASTChipsets, 470 PCI_DEV_DEVICE_ID(pAST->PciInfo)); 471 } 472 if (pAST->pEnt->device->chipRev >= 0) { 473 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 474 pAST->pEnt->device->chipRev); 475 } 476 477 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", 478 (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown ast"); 479 480 /* Resource Allocation */ 481 pAST->IODBase = pScrn->domainIOBase; 482 /* "Patch" the PIOOffset inside vgaHW in order to force 483 * the vgaHW module to use our relocated i/o ports. 484 */ 485 VGAHWPTR(pScrn)->PIOOffset = pAST->PIOOffset = pAST->IODBase + PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) - 0x380; 486 487 pAST->RelocateIO = (IOADDRESS)(PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) + pAST->IODBase); 488 489 if (pAST->pEnt->device->MemBase != 0) { 490 pAST->FBPhysAddr = pAST->pEnt->device->MemBase; 491 from = X_CONFIG; 492 } else { 493 if (PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) != 0) { 494 pAST->FBPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) & 0xFFF00000; 495 from = X_PROBED; 496 } else { 497 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 498 "No valid FB address in PCI config space\n"); 499 ASTFreeRec(pScrn); 500 return FALSE; 501 } 502 } 503 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Linear framebuffer at 0x%lX\n", 504 (unsigned long) pAST->FBPhysAddr); 505 506 if (pAST->pEnt->device->IOBase != 0) { 507 pAST->MMIOPhysAddr = pAST->pEnt->device->IOBase; 508 from = X_CONFIG; 509 } else { 510 if (PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM)) { 511 pAST->MMIOPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM) & 0xFFFF0000; 512 from = X_PROBED; 513 } else { 514 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 515 "No valid MMIO address in PCI config space\n"); 516 ASTFreeRec(pScrn); 517 return FALSE; 518 } 519 } 520 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IO registers at addr 0x%lX\n", 521 (unsigned long) pAST->MMIOPhysAddr); 522 523 /* Map MMIO */ 524 pAST->MMIOMapSize = DEFAULT_MMIO_SIZE; 525 if (!ASTMapMMIO(pScrn)) { 526 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map Memory Map IO Failed \n"); 527 return FALSE; 528 } 529 530 /* Init VGA Adapter */ 531 if (!xf86IsPrimaryPci(pAST->PciInfo)) 532 { 533 InitVGA(pScrn); 534 } 535 536 vASTOpenKey(pScrn); 537 bASTRegInit(pScrn); 538 539 /* Get Chip Type */ 540 if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10) 541 GetChipType(pScrn); 542 else 543 pAST->jChipType = AST2000; 544 545 /* Get DRAM Info */ 546 GetDRAMInfo(pScrn); 547 548 /* Map Framebuffer */ 549 pScrn->videoRam = GetVRAMInfo(pScrn) / 1024; 550 from = X_DEFAULT; 551 552 if (pAST->pEnt->device->videoRam) { 553 pScrn->videoRam = pAST->pEnt->device->videoRam; 554 from = X_CONFIG; 555 } 556 557 pAST->FbMapSize = pScrn->videoRam * 1024; 558 559#if 0 560 if (!ASTMapMem(pScrn)) { 561 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); 562 return FALSE; 563 } 564#endif 565 566 pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr; 567 pScrn->fbOffset = 0; 568 569 /* Do DDC 570 * should be done after xf86CollectOptions 571 */ 572 pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index); 573 574 /* Mode Valid */ 575 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 576 clockRanges->next = NULL; 577 clockRanges->minClock = 9500; 578 clockRanges->maxClock = GetMaxDCLK(pScrn) * 1000; 579 clockRanges->clockIndex = -1; 580 clockRanges->interlaceAllowed = FALSE; 581 clockRanges->doubleScanAllowed = FALSE; 582 583 /* Add for AST2100, ycchen@061807 */ 584 if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200)) 585 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 586 pScrn->display->modes, clockRanges, 587 0, 320, 1920, 8 * pScrn->bitsPerPixel, 588 200, 1200, 589 pScrn->display->virtualX, pScrn->display->virtualY, 590 pAST->FbMapSize, LOOKUP_BEST_REFRESH); 591 else 592 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 593 pScrn->display->modes, clockRanges, 594 0, 320, 1600, 8 * pScrn->bitsPerPixel, 595 200, 1200, 596 pScrn->display->virtualX, pScrn->display->virtualY, 597 pAST->FbMapSize, LOOKUP_BEST_REFRESH); 598 599 if (i == -1) { 600 ASTFreeRec(pScrn); 601 return FALSE; 602 } 603 604 xf86PruneDriverModes(pScrn); 605 606 if (!i || !pScrn->modes) { 607 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 608 ASTFreeRec(pScrn); 609 return FALSE; 610 } 611 612 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 613 614 pScrn->currentMode = pScrn->modes; 615 616 xf86PrintModes(pScrn); 617 618 xf86SetDpi(pScrn, 0, 0); 619 620 /* Accelaration Check */ 621 pAST->noAccel = TRUE; 622 pAST->AccelInfoPtr = NULL; 623 pAST->pCMDQPtr = NULL; 624 pAST->CMDQInfo.ulCMDQSize = 0; 625#ifdef Accel_2D 626 if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE)) 627 { 628 if (!xf86LoadSubModule(pScrn, "xaa")) { 629 ASTFreeRec(pScrn); 630 return FALSE; 631 } 632 633 pAST->noAccel = FALSE; 634 635 pAST->MMIO2D = TRUE; 636#ifndef MMIO_2D 637 if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) { 638 pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE; 639 pAST->MMIO2D = FALSE; 640 } 641#endif 642 643 pAST->ENGCaps = ENG_CAP_ALL; 644 if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) { 645 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n"); 646 } 647 648 pAST->DBGSelect = 0; 649 if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) { 650 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n"); 651 } 652 } 653#endif 654 655 /* HW Cursor Check */ 656 pAST->noHWC = TRUE; 657 pAST->HWCInfoPtr = NULL; 658 pAST->pHWCPtr = NULL; 659#ifdef HWC 660 if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) { 661 if (!xf86LoadSubModule(pScrn, "ramdac")) { 662 ASTFreeRec(pScrn); 663 return FALSE; 664 } 665 666 pAST->noHWC = FALSE; 667 pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; 668 if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) { 669 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n"); 670 } 671 672 } 673#endif 674 675 /* We won't be using the VGA access after the probe */ 676 xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr); 677 xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr); 678 679 return TRUE; 680} 681 682 683static Bool 684ASTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 685{ 686 ScrnInfoPtr pScrn; 687 ASTRecPtr pAST; 688 vgaHWPtr hwp; 689 VisualPtr visual; 690 691 /* for FB Manager */ 692 BoxRec FBMemBox; 693 int AvailFBSize; 694 695 pScrn = xf86Screens[pScreen->myNum]; 696 pAST = ASTPTR(pScrn); 697 hwp = VGAHWPTR(pScrn); 698 699 if (!ASTMapMem(pScrn)) { 700 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); 701 return FALSE; 702 } 703 704/* if (!pAST->noAccel) */ 705 { 706 /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */ 707 AvailFBSize = pAST->FbMapSize; 708 709 FBMemBox.x1 = 0; 710 FBMemBox.y1 = 0; 711 FBMemBox.x2 = pScrn->displayWidth; 712 FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1; 713 714 if (!xf86InitFBManager(pScreen, &FBMemBox)) { 715 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); 716 return FALSE; 717 } 718 719 } 720 721 vgaHWGetIOBase(hwp); 722 723 vFillASTModeInfo (pScrn); 724 725 ASTSave(pScrn); 726 if (!ASTModeInit(pScrn, pScrn->currentMode)) { 727 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n"); 728 return FALSE; 729 } 730 731 ASTSaveScreen(pScreen, FALSE); 732 ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 733 734 miClearVisualTypes(); 735 736 /* Re-implemented Direct Color support, -jens */ 737 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 738 pScrn->rgbBits, pScrn->defaultVisual)) 739 return FALSE; 740 741 if (!miSetPixmapDepths()) 742 { 743 ASTSaveScreen(pScreen, SCREEN_SAVER_OFF); 744 return FALSE; 745 } 746 747 switch(pScrn->bitsPerPixel) { 748 case 8: 749 case 16: 750 case 32: 751 if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset, 752 pScrn->virtualX, pScrn->virtualY, 753 pScrn->xDpi, pScrn->yDpi, 754 pScrn->displayWidth, pScrn->bitsPerPixel)) 755 return FALSE; 756 break; 757 default: 758 return FALSE; 759 760 } 761 762 if (pScrn->bitsPerPixel > 8) { 763 /* Fixup RGB ordering */ 764 visual = pScreen->visuals + pScreen->numVisuals; 765 while (--visual >= pScreen->visuals) { 766 if ((visual->class | DynamicClass) == DirectColor) { 767 visual->offsetRed = pScrn->offset.red; 768 visual->offsetGreen = pScrn->offset.green; 769 visual->offsetBlue = pScrn->offset.blue; 770 visual->redMask = pScrn->mask.red; 771 visual->greenMask = pScrn->mask.green; 772 visual->blueMask = pScrn->mask.blue; 773 } 774 } 775 } 776 777 fbPictureInit(pScreen, 0, 0); 778 779 xf86SetBlackWhitePixels(pScreen); 780 781#ifdef Accel_2D 782 if (!pAST->noAccel) 783 { 784 if (!ASTAccelInit(pScreen)) { 785 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n"); 786 pAST->noAccel = TRUE; 787 } 788 } 789#endif /* end of Accel_2D */ 790 791 miInitializeBackingStore(pScreen); 792 xf86SetBackingStore(pScreen); 793 xf86SetSilkenMouse(pScreen); 794 795 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 796 797 if (!pAST->noHWC) 798 { 799 if (!ASTCursorInit(pScreen)) { 800 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n"); 801 pAST->noHWC = TRUE; 802 } 803 } 804 805 if (!miCreateDefColormap(pScreen)) 806 return FALSE; 807 808 if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, 809 vASTLoadPalette, NULL, 810 CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { 811 return FALSE; 812 } 813 814 xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0); 815 816 pScreen->SaveScreen = ASTSaveScreen; 817 pAST->CloseScreen = pScreen->CloseScreen; 818 pScreen->CloseScreen = ASTCloseScreen; 819 820 if (serverGeneration == 1) 821 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 822 823 return TRUE; 824 825} /* ASTScreenInit */ 826 827 828Bool 829ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 830{ 831 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 832 ASTRecPtr pAST = ASTPTR(pScrn); 833 834#ifdef HWC 835 if (pAST->pHWCPtr) { 836 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 837 pAST->pHWCPtr = NULL; 838 } 839 ASTHideCursor(pScrn); 840#endif 841 842#ifdef Accel_2D 843 if (pAST->pCMDQPtr) { 844 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 845 pAST->pCMDQPtr = NULL; 846 } 847 vDisable2D(pScrn, pAST); 848#endif 849 850 ASTRestore(pScrn); 851 852 return ASTModeInit(pScrn, mode); 853 854} 855 856void 857ASTAdjustFrame(int scrnIndex, int x, int y, int flags) 858{ 859 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 860 ASTRecPtr pAST = ASTPTR(pScrn); 861 ULONG base; 862 863 base = y * pAST->VideoModeInfo.ScreenWidth + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8); 864 base = base >> 2; /* DW unit */ 865 866 vSetStartAddressCRT1(pAST, base); 867 868} 869 870/* enter into X Server */ 871static Bool 872ASTEnterVT(int scrnIndex, int flags) 873{ 874 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 875 876 /* Fixed suspend can't resume issue */ 877 if (!bIsVGAEnabled(pScrn)) 878 { 879 InitVGA(pScrn); 880 ASTRestore(pScrn); 881 } 882 883 if (!ASTModeInit(pScrn, pScrn->currentMode)) 884 return FALSE; 885 ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 886 887 return TRUE; 888 889} 890 891/* leave X server */ 892static void 893ASTLeaveVT(int scrnIndex, int flags) 894{ 895 896 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 897 vgaHWPtr hwp = VGAHWPTR(pScrn); 898 ASTRecPtr pAST = ASTPTR(pScrn); 899 900#ifdef HWC 901 if (pAST->pHWCPtr) { 902 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 903 pAST->pHWCPtr = NULL; 904 } 905 ASTHideCursor(pScrn); 906#endif 907 908#ifdef Accel_2D 909 if (pAST->pCMDQPtr) { 910 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 911 pAST->pCMDQPtr = NULL; 912 } 913 vDisable2D(pScrn, pAST); 914#endif 915 916 ASTRestore(pScrn); 917 vgaHWLock(hwp); 918 919} 920 921static void 922ASTFreeScreen(int scrnIndex, int flags) 923{ 924 ASTFreeRec(xf86Screens[scrnIndex]); 925 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 926 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 927} 928 929 930static ModeStatus 931ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 932{ 933 934 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 935 ASTRecPtr pAST = ASTPTR(pScrn); 936 Bool Flags = MODE_NOMODE; 937 938 if (mode->Flags & V_INTERLACE) { 939 if (verbose) { 940 xf86DrvMsg(scrnIndex, X_PROBED, 941 "Removing interlaced mode \"%s\"\n", mode->name); 942 } 943 return MODE_NO_INTERLACE; 944 } 945 946 if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) { 947 if (verbose) { 948 xf86DrvMsg(scrnIndex, X_PROBED, 949 "Removing the mode \"%s\"\n", mode->name); 950 } 951 return Flags; 952 } 953 954 /* Add for AST2100, ycchen@061807 */ 955 if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200)) 956 { 957 if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) ) 958 return MODE_OK; 959 } 960 961 switch (mode->CrtcHDisplay) 962 { 963 case 640: 964 if (mode->CrtcVDisplay == 480) Flags=MODE_OK; 965 break; 966 case 800: 967 if (mode->CrtcVDisplay == 600) Flags=MODE_OK; 968 break; 969 case 1024: 970 if (mode->CrtcVDisplay == 768) Flags=MODE_OK; 971 break; 972 case 1280: 973 if (mode->CrtcVDisplay == 1024) Flags=MODE_OK; 974 break; 975 case 1600: 976 if (mode->CrtcVDisplay == 1200) Flags=MODE_OK; 977 break; 978 default: 979 return Flags; 980 } 981 982 return Flags; 983 984} 985 986 987/* Internal used modules */ 988/* 989 * ASTGetRec and ASTFreeRec -- 990 * 991 * Private data for the driver is stored in the screen structure. 992 * These two functions create and destroy that private data. 993 * 994 */ 995static Bool 996ASTGetRec(ScrnInfoPtr pScrn) 997{ 998 if (pScrn->driverPrivate) 999 return TRUE; 1000 1001 pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1); 1002 return TRUE; 1003} 1004 1005static void 1006ASTFreeRec(ScrnInfoPtr pScrn) 1007{ 1008 if (!pScrn) 1009 return; 1010 if (!pScrn->driverPrivate) 1011 return; 1012 xfree(pScrn->driverPrivate); 1013 pScrn->driverPrivate = 0; 1014} 1015 1016static Bool 1017ASTSaveScreen(ScreenPtr pScreen, Bool unblack) 1018{ 1019 /* replacement of vgaHWBlankScreen(pScrn, unblank) without seq reset */ 1020 /* return vgaHWSaveScreen(pScreen, unblack); */ 1021 ScrnInfoPtr pScrn = NULL; 1022 1023 if (pScreen != NULL) 1024 pScrn = xf86Screens[pScreen->myNum]; 1025 1026 if ((pScrn != NULL) && pScrn->vtSema) { 1027 ASTBlankScreen(pScrn, unblack); 1028 } 1029 return (TRUE); 1030} 1031 1032static Bool 1033ASTCloseScreen(int scrnIndex, ScreenPtr pScreen) 1034{ 1035 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1036 vgaHWPtr hwp = VGAHWPTR(pScrn); 1037 ASTRecPtr pAST = ASTPTR(pScrn); 1038 1039 if (pScrn->vtSema == TRUE) 1040 { 1041#ifdef HWC 1042 if (pAST->pHWCPtr) { 1043 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 1044 pAST->pHWCPtr = NULL; 1045 } 1046 ASTHideCursor(pScrn); 1047#endif 1048 1049#ifdef Accel_2D 1050 if (pAST->pCMDQPtr) { 1051 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 1052 pAST->pCMDQPtr = NULL; 1053 } 1054 vDisable2D(pScrn, pAST); 1055#endif 1056 1057 ASTRestore(pScrn); 1058 vgaHWLock(hwp); 1059 } 1060 1061 ASTUnmapMem(pScrn); 1062 vgaHWUnmapMem(pScrn); 1063 1064 if(pAST->AccelInfoPtr) { 1065 XAADestroyInfoRec(pAST->AccelInfoPtr); 1066 pAST->AccelInfoPtr = NULL; 1067 } 1068 1069 if(pAST->HWCInfoPtr) { 1070 xf86DestroyCursorInfoRec(pAST->HWCInfoPtr); 1071 pAST->HWCInfoPtr = NULL; 1072 } 1073 1074 pScrn->vtSema = FALSE; 1075 pScreen->CloseScreen = pAST->CloseScreen; 1076 return (*pScreen->CloseScreen) (scrnIndex, pScreen); 1077} 1078 1079static void 1080ASTSave(ScrnInfoPtr pScrn) 1081{ 1082 ASTRecPtr pAST; 1083 vgaRegPtr vgaReg; 1084 ASTRegPtr astReg; 1085 int i, icount=0; 1086 1087 pAST = ASTPTR(pScrn); 1088 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 1089 astReg = &pAST->SavedReg; 1090 1091 /* do save */ 1092 if (xf86IsPrimaryPci(pAST->PciInfo)) { 1093 vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); 1094 } 1095 else { 1096 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE); 1097 } 1098 1099 /* Ext. Save */ 1100 vASTOpenKey(pScrn); 1101 1102 /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ 1103 for (i=0x81; i<=0xB6; i++) 1104 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1105 for (i=0xBC; i<=0xC1; i++) 1106 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1107 GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); 1108 1109} 1110 1111static void 1112ASTRestore(ScrnInfoPtr pScrn) 1113{ 1114 ASTRecPtr pAST; 1115 vgaRegPtr vgaReg; 1116 ASTRegPtr astReg; 1117 int i, icount=0; 1118 1119 pAST = ASTPTR(pScrn); 1120 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 1121 astReg = &pAST->SavedReg; 1122 1123 /* do restore */ 1124 vgaHWProtect(pScrn, TRUE); 1125 if (xf86IsPrimaryPci(pAST->PciInfo)) 1126 vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); 1127 else 1128 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 1129 vgaHWProtect(pScrn, FALSE); 1130 1131 /* Ext. restore */ 1132 vASTOpenKey(pScrn); 1133 1134 /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ 1135 for (i=0x81; i<=0xB6; i++) 1136 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1137 for (i=0xBC; i<=0xC1; i++) 1138 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1139 SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); 1140 1141} 1142 1143static void 1144ASTProbeDDC(ScrnInfoPtr pScrn, int index) 1145{ 1146 vbeInfoPtr pVbe; 1147 1148 if (xf86LoadSubModule(pScrn, "vbe")) { 1149 pVbe = VBEInit(NULL, index); 1150 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 1151 vbeFree(pVbe); 1152 } 1153} 1154 1155#define SkipDT 0x00 1156#define DT1 0x01 1157#define DT2 0x02 1158 1159static xf86MonPtr 1160ASTDoDDC(ScrnInfoPtr pScrn, int index) 1161{ 1162 vbeInfoPtr pVbe; 1163 xf86MonPtr MonInfo = NULL, MonInfo1 = NULL, MonInfo2 = NULL; 1164 ASTRecPtr pAST = ASTPTR(pScrn); 1165 unsigned long i, j, k; 1166 unsigned char DDC_data[128]; 1167 struct monitor_ranges ranges, ranges1, ranges2; 1168 int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0; 1169 struct std_timings stdtiming, *stdtiming1, *stdtiming2; 1170 1171 /* Honour Option "noDDC" */ 1172 if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) { 1173 return MonInfo; 1174 } 1175 1176 if (xf86LoadSubModule(pScrn, "vbe") && (pVbe = VBEInit(NULL, index))) { 1177 MonInfo1 = vbeDoEDID(pVbe, NULL); 1178 MonInfo = MonInfo1; 1179 1180 /* For VGA2 CLONE Support, ycchen@012508 */ 1181 if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) { 1182 if (GetVGA2EDID(pScrn, DDC_data) == TRUE) { 1183 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n"); 1184 MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); 1185 if (MonInfo1 == NULL) /* No DDC1 EDID */ 1186 MonInfo = MonInfo2; 1187 else { /* Check with VGA1 & VGA2 EDID */ 1188 /* Update establishment timing */ 1189 MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1; 1190 MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2; 1191 MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu; 1192 1193 /* Update Std. Timing */ 1194 for (i=0; i<8; i++) { 1195 stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; 1196 for (j=0; j<8; j++) { 1197 if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \ 1198 (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \ 1199 (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) { 1200 stdtiming = MonInfo1->timings2[i]; 1201 break; 1202 } 1203 } 1204 1205 MonInfo->timings2[i] = stdtiming; 1206 } /* Std. Timing */ 1207 1208 /* Get Detailed Timing */ 1209 for (i=0;i<4;i++) { 1210 if (MonInfo1->det_mon[i].type == 0xFD) 1211 ranges1 = MonInfo1->det_mon[i].section.ranges; 1212 else if (MonInfo1->det_mon[i].type == 0xFA) 1213 stdtiming1 = MonInfo1->det_mon[i].section.std_t; 1214 else if (MonInfo1->det_mon[i].type == 0x00) { 1215 if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1) 1216 dclock1 = MonInfo1->det_mon[i].section.d_timings.clock; 1217 if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1) 1218 h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active; 1219 if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1) 1220 v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active; 1221 } 1222 if (MonInfo2->det_mon[i].type == 0xFD) 1223 ranges2 = MonInfo2->det_mon[i].section.ranges; 1224 else if (MonInfo1->det_mon[i].type == 0xFA) 1225 stdtiming2 = MonInfo2->det_mon[i].section.std_t; 1226 else if (MonInfo2->det_mon[i].type == 0x00) { 1227 if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2) 1228 dclock2 = MonInfo2->det_mon[i].section.d_timings.clock; 1229 if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2) 1230 h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active; 1231 if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2) 1232 v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active; 1233 } 1234 } /* Get Detailed Timing */ 1235 1236 /* Chk Detailed Timing */ 1237 if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2)) 1238 DTSelect = DT2; 1239 else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1)) 1240 DTSelect = DT1; 1241 else 1242 DTSelect = SkipDT; 1243 1244 /* Chk Monitor Descriptor */ 1245 ranges = ranges1; 1246 ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h; 1247 ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v; 1248 ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h; 1249 ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v; 1250 ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock; 1251 1252 /* Update Detailed Timing */ 1253 for (i=0; i<4; i++) 1254 { 1255 if (MonInfo->det_mon[i].type == 0xFD) { 1256 MonInfo->det_mon[i].section.ranges = ranges; 1257 } 1258 else if (MonInfo->det_mon[i].type == 0xFA) { 1259 for (j=0; j<5; j++) { 1260 stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; 1261 for (k=0; k<5; k++) { 1262 if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \ 1263 (stdtiming1[j].vsize == stdtiming2[k].vsize) && \ 1264 (stdtiming1[j].refresh == stdtiming2[k].refresh)) { 1265 stdtiming = stdtiming1[j]; 1266 break; 1267 } 1268 } 1269 stdtiming1[j] = stdtiming; 1270 } /* Std. Timing */ 1271 } /* FA */ 1272 else if (MonInfo->det_mon[i].type == 0x00) { 1273 if (DTSelect == DT2) 1274 MonInfo->det_mon[i] = MonInfo2->det_mon[i]; 1275 else if (DTSelect == DT1) 1276 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1277 else /* SkipDT */ 1278 { /* use 1024x768 as default */ 1279 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1280 MonInfo->det_mon[i].section.d_timings.clock = 65000000; 1281 MonInfo->det_mon[i].section.d_timings.h_active = 1024; 1282 MonInfo->det_mon[i].section.d_timings.h_blanking = 320; 1283 MonInfo->det_mon[i].section.d_timings.v_active = 768; 1284 MonInfo->det_mon[i].section.d_timings.v_blanking = 38; 1285 MonInfo->det_mon[i].section.d_timings.h_sync_off = 24; 1286 MonInfo->det_mon[i].section.d_timings.h_sync_width = 136; 1287 MonInfo->det_mon[i].section.d_timings.v_sync_off = 3; 1288 MonInfo->det_mon[i].section.d_timings.v_sync_width = 6; 1289 } 1290 } /* 00 */ 1291 else { /* use Monitor 1 as default */ 1292 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1293 } 1294 1295 } /* Update Detailed Timing */ 1296 1297 /* set feature size */ 1298 if (DTSelect == DT2) { 1299 MonInfo->features.hsize = MonInfo2->features.hsize; 1300 MonInfo->features.vsize = MonInfo2->features.vsize; 1301 } 1302 else if (DTSelect == DT1) { 1303 MonInfo->features.hsize = MonInfo1->features.hsize; 1304 MonInfo->features.vsize = MonInfo1->features.vsize; 1305 } 1306 else /* Skip DT */ 1307 { /* use 1024x768 as default */ 1308 MonInfo->features.hsize = 0x20; 1309 MonInfo->features.vsize = 0x18; 1310 } 1311 1312 } /* Check with VGA1 & VGA2 EDID */ 1313 1314 } /* GetVGA2EDID */ 1315 else { 1316 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n"); 1317 } 1318 1319 } 1320 1321 xf86PrintEDID(MonInfo); 1322 xf86SetDDCproperties(pScrn, MonInfo); 1323 vbeFree(pVbe); 1324 } else { 1325 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1326 "this driver cannot do DDC without VBE\n"); 1327 } 1328 1329 return MonInfo; 1330} 1331 1332static void 1333vFillASTModeInfo (ScrnInfoPtr pScrn) 1334{ 1335 ASTRecPtr pAST; 1336 1337 pAST = ASTPTR(pScrn); 1338 1339 pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX; 1340 pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY; 1341 pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel; 1342 /* Fixed screen pitch incorrect in some specific monitor, ycchen@071707 */ 1343 pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ; 1344 1345} 1346 1347static Bool 1348ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1349{ 1350 vgaHWPtr hwp; 1351 ASTRecPtr pAST; 1352 1353 hwp = VGAHWPTR(pScrn); 1354 pAST = ASTPTR(pScrn); 1355 1356 vgaHWUnlock(hwp); 1357 1358 if (!vgaHWInit(pScrn, mode)) 1359 return FALSE; 1360 1361 pScrn->vtSema = TRUE; 1362 pAST->ModePtr = mode; 1363 1364 if (!ASTSetMode(pScrn, mode)) 1365 return FALSE; 1366 1367 vgaHWProtect(pScrn, FALSE); 1368 1369 return TRUE; 1370} 1371