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