ast_driver.c revision e8b4ed9f
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 "vgaHW.h" 35#include "mipointer.h" 36#include "micmap.h" 37 38#include "fb.h" 39#include "regionstr.h" 40#include "xf86xv.h" 41#include <X11/extensions/Xv.h> 42 43#include "xf86Pci.h" 44 45/* framebuffer offscreen manager */ 46#include "xf86fbman.h" 47 48/* include xaa includes */ 49#ifdef HAVE_XAA_H 50#include "xaa.h" 51#include "xaarop.h" 52#endif 53 54/* H/W cursor support */ 55#include "xf86Cursor.h" 56 57/* Driver specific headers */ 58#include "ast.h" 59#include "ast_mode.h" 60#include "ast_vgatool.h" 61#include "ast_2dtool.h" 62 63/* Mandatory functions */ 64static void ASTIdentify(int flags); 65const OptionInfoRec *ASTAvailableOptions(int chipid, int busid); 66static Bool ASTProbe(DriverPtr drv, int flags); 67static Bool ASTPreInit(ScrnInfoPtr pScrn, int flags); 68static Bool ASTScreenInit(SCREEN_INIT_ARGS_DECL); 69Bool ASTSwitchMode(SWITCH_MODE_ARGS_DECL); 70void ASTAdjustFrame(ADJUST_FRAME_ARGS_DECL); 71static Bool ASTEnterVT(VT_FUNC_ARGS_DECL); 72static void ASTLeaveVT(VT_FUNC_ARGS_DECL); 73static void ASTFreeScreen(FREE_SCREEN_ARGS_DECL); 74static ModeStatus ASTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags); 75 76/* Internally used functions */ 77static Bool ASTGetRec(ScrnInfoPtr pScrn); 78static void ASTFreeRec(ScrnInfoPtr pScrn); 79static Bool ASTSaveScreen(ScreenPtr pScreen, Bool unblack); 80static Bool ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL); 81static void ASTSave(ScrnInfoPtr pScrn); 82static void ASTRestore(ScrnInfoPtr pScrn); 83static void ASTProbeDDC(ScrnInfoPtr pScrn, int index); 84static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index); 85static void vFillASTModeInfo (ScrnInfoPtr pScrn); 86static Bool ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 87 88#ifdef AstVideo 89/* video function */ 90static void ASTInitVideo(ScreenPtr pScreen); 91static int ASTPutImage( ScrnInfoPtr, 92 short, short, short, short, short, short, short, short, 93 int, unsigned char*, short, short, Bool, RegionPtr, pointer 94#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1 95 , DrawablePtr pDraw 96#endif 97 ); 98#endif 99 100/* 101 * This is intentionally screen-independent. It indicates the binding 102 * choice made in the first PreInit. 103 */ 104_X_EXPORT DriverRec AST = { 105 AST_VERSION, 106 AST_DRIVER_NAME, 107 ASTIdentify, 108 ASTProbe, 109 ASTAvailableOptions, 110 NULL, 111 0 112}; 113 114/* Chipsets */ 115static SymTabRec ASTChipsets[] = { 116 {PCI_CHIP_AST2000, "ASPEED Graphics Family"}, 117 {PCI_CHIP_AST2100, "ASPEED Graphics Family"}, 118 {PCI_CHIP_AST1180, "ASPEED AST1180 Graphics"}, 119 {-1, NULL} 120}; 121 122static PciChipsets ASTPciChipsets[] = { 123 {PCI_CHIP_AST2000, PCI_CHIP_AST2000, RES_SHARED_VGA}, 124 {PCI_CHIP_AST2100, PCI_CHIP_AST2100, RES_SHARED_VGA}, 125 {PCI_CHIP_AST1180, PCI_CHIP_AST1180, RES_SHARED_VGA}, 126 {-1, -1, RES_UNDEFINED } 127}; 128 129typedef enum { 130 OPTION_NOACCEL, 131 OPTION_MMIO2D, 132 OPTION_SW_CURSOR, 133 OPTION_HWC_NUM, 134 OPTION_ENG_CAPS, 135 OPTION_DBG_SELECT, 136 OPTION_NO_DDC, 137 OPTION_VGA2_CLONE, 138 OPTION_SHADOW_FB 139} ASTOpts; 140 141static const OptionInfoRec ASTOptions[] = { 142 {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, 143 {OPTION_MMIO2D, "MMIO2D", OPTV_BOOLEAN, {0}, FALSE}, 144 {OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, 145 {OPTION_HWC_NUM, "HWCNumber", OPTV_INTEGER, {0}, FALSE}, 146 {OPTION_ENG_CAPS, "ENGCaps", OPTV_INTEGER, {0}, FALSE}, 147 {OPTION_DBG_SELECT, "DBGSelect", OPTV_INTEGER, {0}, FALSE}, 148 {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE}, 149 {OPTION_VGA2_CLONE, "VGA2Clone", OPTV_BOOLEAN, {0}, FALSE}, 150 {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, 151 {-1, NULL, OPTV_NONE, {0}, FALSE} 152}; 153 154#ifdef XFree86LOADER 155 156static MODULESETUPPROTO(astSetup); 157 158static XF86ModuleVersionInfo astVersRec = { 159 AST_DRIVER_NAME, 160 MODULEVENDORSTRING, 161 MODINFOSTRING1, 162 MODINFOSTRING2, 163 XORG_VERSION_CURRENT, 164 AST_MAJOR_VERSION, AST_MINOR_VERSION, AST_PATCH_VERSION, 165 ABI_CLASS_VIDEODRV, 166#ifdef PATCH_ABI_VERSION 167 ABI_VIDEODRV_VERSION_PATCH, 168#else 169 ABI_VIDEODRV_VERSION, 170#endif 171 MOD_CLASS_VIDEODRV, 172 {0, 0, 0, 0} 173}; 174 175_X_EXPORT XF86ModuleData astModuleData = { &astVersRec, astSetup, NULL }; 176 177static pointer 178astSetup(pointer module, pointer opts, int *errmaj, int *errmin) 179{ 180 static Bool setupDone = FALSE; 181 182 /* This module should be loaded only once, but check to be sure. 183 */ 184 if (!setupDone) { 185 setupDone = TRUE; 186 xf86AddDriver(&AST, module, 0); 187 188 /* 189 * The return value must be non-NULL on success even though there 190 * is no TearDownProc. 191 */ 192 return (pointer) TRUE; 193 } else { 194 if (errmaj) 195 *errmaj = LDR_ONCEONLY; 196 return NULL; 197 } 198} 199 200#endif /* XFree86LOADER */ 201 202/* 203 * ASTIdentify -- 204 * 205 * Returns the string name for the driver based on the chipset. In this 206 * case it will always be an AST, so we can return a static string. 207 * 208 */ 209static void 210ASTIdentify(int flags) 211{ 212 xf86PrintChipsets(AST_NAME, "Driver for ASPEED Graphics Chipsets", 213 ASTChipsets); 214} 215 216const OptionInfoRec * 217ASTAvailableOptions(int chipid, int busid) 218{ 219 220 return ASTOptions; 221 222} 223 224/* 225 * ASTProbe -- 226 * 227 * Look through the PCI bus to find cards that are AST boards. 228 * Setup the dispatch table for the rest of the driver functions. 229 * 230 */ 231static Bool 232ASTProbe(DriverPtr drv, int flags) 233{ 234 int i, numUsed, numDevSections, *usedChips; 235 Bool foundScreen = FALSE; 236 GDevPtr *devSections; 237 238 /* 239 * Find the config file Device sections that match this 240 * driver, and return if there are none. 241 */ 242 if ((numDevSections = 243 xf86MatchDevice(AST_DRIVER_NAME, &devSections)) <= 0) { 244 return FALSE; 245 } 246 247#ifndef XSERVER_LIBPCIACCESS 248 /* 249 * This probing is just checking the PCI data the server already 250 * collected. 251 */ 252 if (xf86GetPciVideoInfo() == NULL) { 253 return FALSE; 254 } 255#endif 256 257 numUsed = xf86MatchPciInstances(AST_NAME, PCI_VENDOR_AST, 258 ASTChipsets, ASTPciChipsets, 259 devSections, numDevSections, 260 drv, &usedChips); 261 262 if (numUsed <= 0) { 263 free(devSections); 264 return FALSE; 265 } 266 267 if (flags & PROBE_DETECT) { 268 if (numUsed > 0) 269 foundScreen = TRUE; 270 } else { 271 for (i = 0; i < numUsed; i++) { 272 ScrnInfoPtr pScrn = NULL; 273 274#ifdef XSERVER_LIBPCIACCESS 275 { 276 struct pci_device *pPci = xf86GetPciInfoForEntity(usedChips[i]); 277 278 if (pci_device_has_kernel_driver(pPci)) { 279 xf86DrvMsg(0, X_ERROR, 280 "ast: The PCI device 0x%x at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n", 281 pPci->device_id, pPci->bus, pPci->domain, pPci->dev, pPci->func); 282 xf86DrvMsg(0, X_ERROR, 283 "ast: This driver cannot operate until it has been unloaded.\n"); 284 xf86UnclaimPciSlot(pPci 285#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 13 286 , devSections[0] 287#endif 288 ); 289 free(devSections); 290 return FALSE; 291 } 292 } 293#endif 294 295 /* Allocate new ScrnInfoRec and claim the slot */ 296 if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], 297 ASTPciChipsets, 0, 0, 0, 0, 0))) 298 { 299 EntityInfoPtr pEnt; 300 301 pEnt = xf86GetEntityInfo(usedChips[i]); 302 303 pScrn->driverVersion = AST_VERSION; 304 pScrn->driverName = AST_DRIVER_NAME; 305 pScrn->name = AST_NAME; 306 307 pScrn->Probe = ASTProbe; 308 pScrn->PreInit = ASTPreInit; 309 pScrn->ScreenInit = ASTScreenInit; 310 pScrn->SwitchMode = ASTSwitchMode; 311 pScrn->AdjustFrame = ASTAdjustFrame; 312 pScrn->EnterVT = ASTEnterVT; 313 pScrn->LeaveVT = ASTLeaveVT; 314 pScrn->FreeScreen = ASTFreeScreen; 315 pScrn->ValidMode = ASTValidMode; 316 317 foundScreen = TRUE; 318 319 } /* end of if */ 320 } /* end of for-loop */ 321 } /* end of if flags */ 322 323 free(devSections); 324 free(usedChips); 325 326 return foundScreen; 327} 328 329#ifdef Support_ShadowFB 330static void * 331ASTWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 332 CARD32 *size, void *closure) 333{ 334 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 335 ASTPtr pAST = ASTPTR(pScrn); 336 int stride = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8); 337 338 *size = stride; 339 return ((uint8_t *)pAST->FBVirtualAddr + pScrn->fbOffset + row * stride + offset); 340 341} 342 343static void 344ASTUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) 345{ 346 shadowUpdatePacked(pScreen, pBuf); 347} 348 349static Bool 350ASTCreateScreenResources(ScreenPtr pScreen) 351{ 352 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 353 ASTPtr pAST = ASTPTR(pScrn); 354 Bool ret; 355 356 pScreen->CreateScreenResources = pAST->CreateScreenResources; 357 ret = pScreen->CreateScreenResources(pScreen); 358 pScreen->CreateScreenResources = ASTCreateScreenResources; 359 shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), pAST->update, 360 pAST->window, 0, 0); 361 362 return ret; 363} 364#endif /* Support_ShadowFB */ 365 366/* 367 * ASTPreInit -- 368 * 369 * Do initial setup of the board before we know what resolution we will 370 * be running at. 371 * 372 */ 373static Bool 374ASTPreInit(ScrnInfoPtr pScrn, int flags) 375{ 376 EntityInfoPtr pEnt; 377 int flags24; 378 rgb defaultWeight = { 0, 0, 0 }; 379#if !(defined(__sparc__)) && !(defined(__mips__)) 380 vgaHWPtr hwp; 381#endif 382 383 ASTRecPtr pAST; 384 385 ClockRangePtr clockRanges; 386 int i; 387 MessageType from; 388 int maxPitch, maxHeight; 389 390 /* Support one adapter only now */ 391 if (pScrn->numEntities != 1) 392 return FALSE; 393 394 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 395 396 if (flags & PROBE_DETECT) { 397 ASTProbeDDC(pScrn, pEnt->index); 398 return TRUE; 399 } 400 401 if (pEnt->location.type != BUS_PCI) 402 return FALSE; 403 404#ifndef XSERVER_LIBPCIACCESS 405 if (xf86RegisterResources(pEnt->index, 0, ResExclusive)) 406 return FALSE; 407#endif 408 409#if !(defined(__sparc__)) && !(defined(__mips__)) 410 /* The vgahw module should be loaded here when needed */ 411 if (!xf86LoadSubModule(pScrn, "vgahw")) 412 return FALSE; 413#endif 414 415 /* The fb module should be loaded here when needed */ 416 if (!xf86LoadSubModule(pScrn, "fb")) 417 return FALSE; 418 419#if !(defined(__sparc__)) && !(defined(__mips__)) 420 /* Allocate a vgaHWRec */ 421 if (!vgaHWGetHWRec(pScrn)) 422 return FALSE; 423 hwp = VGAHWPTR(pScrn); 424 vgaHWSetStdFuncs(hwp); 425#endif 426 427 /* Color Depth Check */ 428 flags24 = Support32bppFb; 429 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) { 430 return FALSE; 431 } else { 432 switch (pScrn->depth) { 433 case 8: 434 case 16: 435 case 24: 436 break; 437 default: 438 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 439 "Given depth (%d) is not supported by ast driver\n", 440 pScrn->depth); 441 return FALSE; 442 } 443 } 444 xf86PrintDepthBpp(pScrn); 445 446 switch (pScrn->bitsPerPixel) { 447 case 8: 448 case 16: 449 case 32: 450 break; 451 default: 452 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 453 "Given bpp (%d) is not supported by ast driver\n", 454 pScrn->bitsPerPixel); 455 return FALSE; 456 } 457 458 /* fill pScrn misc. */ 459 pScrn->progClock = TRUE; 460 pScrn->rgbBits = 6; 461 pScrn->monitor = pScrn->confScreen->monitor; /* should be initialized before set gamma */ 462#ifndef XSERVER_LIBPCIACCESS 463 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 464 pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 465#endif 466 467 /* 468 * If the driver can do gamma correction, it should call xf86SetGamma() 469 * here. 470 */ 471 { 472 Gamma zeros = { 0.0, 0.0, 0.0 }; 473 474 if (!xf86SetGamma(pScrn, zeros)) { 475 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call xf86SetGamma failed \n"); 476 return FALSE; 477 } 478 } 479 480 481 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) { 482 return FALSE; 483 } 484 485 if (!xf86SetDefaultVisual(pScrn, -1)) { 486 return FALSE; 487 } 488 489 /* Allocate driverPrivate */ 490 if (!ASTGetRec(pScrn)) { 491 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call ASTGetRec failed \n"); 492 return FALSE; 493 } 494 495 /* Fill AST Info */ 496 pAST = ASTPTR(pScrn); 497 pAST->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 498 pAST->PciInfo = xf86GetPciInfoForEntity(pAST->pEnt->index); 499#ifndef XSERVER_LIBPCIACCESS 500 pAST->PciTag = pciTag(pAST->PciInfo->bus, pAST->PciInfo->device, 501 pAST->PciInfo->func); 502#endif 503 504 /* Process the options 505 * pScrn->confScreen, pScrn->display, pScrn->monitor, pScrn->numEntities, 506 * and pScrn->entityList should be initialized before 507 */ 508 xf86CollectOptions(pScrn, NULL); 509 if (!(pAST->Options = malloc(sizeof(ASTOptions)))) 510 { 511 ASTFreeRec(pScrn); 512 return FALSE; 513 } 514 memcpy(pAST->Options, ASTOptions, sizeof(ASTOptions)); 515 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAST->Options); 516 517 /* 518 * Set the Chipset and ChipRev, allowing config file entries to 519 * override. 520 */ 521 if (pAST->pEnt->device->chipset && *pAST->pEnt->device->chipset) { 522 pScrn->chipset = pAST->pEnt->device->chipset; 523 from = X_CONFIG; 524 } else if (pAST->pEnt->device->chipID >= 0) { 525 pScrn->chipset = (char *)xf86TokenToString(ASTChipsets, 526 pAST->pEnt->device->chipID); 527 from = X_CONFIG; 528 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 529 pAST->pEnt->device->chipID); 530 } else { 531 from = X_PROBED; 532 pScrn->chipset = (char *)xf86TokenToString(ASTChipsets, 533 PCI_DEV_DEVICE_ID(pAST->PciInfo)); 534 } 535 if (pAST->pEnt->device->chipRev >= 0) { 536 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 537 pAST->pEnt->device->chipRev); 538 } 539 540 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", 541 (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown ast"); 542 543 544#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 545 /* "Patch" the PIOOffset inside vgaHW in order to force 546 * the vgaHW module to use our relocated i/o ports. 547 */ 548 VGAHWPTR(pScrn)->PIOOffset = 549 pScrn->domainIOBase + PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO) - 0x380; 550 551 pAST->RelocateIO = pScrn->domainIOBase + 552 PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO); 553#else 554 pAST->RelocateIO = (PCI_REGION_BASE(pAST->PciInfo, 2, REGION_IO)); 555 556#endif 557 558 559 if (pAST->pEnt->device->MemBase != 0) { 560 pAST->FBPhysAddr = pAST->pEnt->device->MemBase; 561 from = X_CONFIG; 562 } else { 563 if (PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) != 0) { 564 pAST->FBPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 0, REGION_MEM) & 0xFFF00000; 565 from = X_PROBED; 566 } else { 567 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 568 "No valid FB address in PCI config space\n"); 569 ASTFreeRec(pScrn); 570 return FALSE; 571 } 572 } 573 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Linear framebuffer at 0x%lX\n", 574 (unsigned long) pAST->FBPhysAddr); 575 576 if (pAST->pEnt->device->IOBase != 0) { 577 pAST->MMIOPhysAddr = pAST->pEnt->device->IOBase; 578 from = X_CONFIG; 579 } else { 580 if (PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM)) { 581 pAST->MMIOPhysAddr = PCI_REGION_BASE(pAST->PciInfo, 1, REGION_MEM) & 0xFFFF0000; 582 from = X_PROBED; 583 } else { 584 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 585 "No valid MMIO address in PCI config space\n"); 586 ASTFreeRec(pScrn); 587 return FALSE; 588 } 589 } 590 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IO registers at addr 0x%lX\n", 591 (unsigned long) pAST->MMIOPhysAddr); 592 593 /* Map MMIO */ 594 pAST->MMIOMapSize = DEFAULT_MMIO_SIZE; 595 if (!ASTMapMMIO(pScrn)) { 596 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map Memory Map IO Failed \n"); 597 return FALSE; 598 } 599 600 if (PCI_DEV_DEVICE_ID(pAST->PciInfo) == PCI_CHIP_AST1180) 601 { 602 pAST->jChipType = AST1180; 603 604 /* validate mode */ 605 if ( (pScrn->bitsPerPixel == 8) || (pScrn->depth == 8) ) 606 { 607 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 608 "Given bpp (%d) is not supported by ast driver\n", 609 pScrn->bitsPerPixel); 610 return FALSE; 611 } 612 613 /* Init AST1180 */ 614 bASTInitAST1180(pScrn); 615 616 /* Get AST1180 Information */ 617 ASTGetAST1180DRAMInfo(pScrn); 618 pScrn->videoRam = pAST->ulVRAMSize / 1024; 619 620 } 621 else 622 { 623 /* Enable VGA MMIO Access */ 624 vASTEnableVGAMMIO(pScrn); 625 626 /* Get Chip Type */ 627 if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x40) 628 pAST->jChipType = AST2500; 629 else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x30) 630 pAST->jChipType = AST2400; 631 else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x20) 632 pAST->jChipType = AST2300; 633 else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10) 634 ASTGetChipType(pScrn); 635 else 636 pAST->jChipType = AST2000; 637 638 /* Init VGA Adapter */ 639 if (!xf86IsPrimaryPci(pAST->PciInfo)) 640 { 641 ASTInitVGA(pScrn, 0); 642 } 643 644 vASTOpenKey(pScrn); 645 bASTRegInit(pScrn); 646 647 /* Get Options from Scratch */ 648 ASTGetScratchOptions(pScrn); 649 650 /* Get DRAM Info */ 651 ASTGetDRAMInfo(pScrn); 652 pAST->ulVRAMSize = ASTGetVRAMInfo(pScrn); 653 pScrn->videoRam = pAST->ulVRAMSize / 1024; 654 } 655 656 /* Map Framebuffer */ 657 from = X_DEFAULT; 658 if (pAST->pEnt->device->videoRam) { 659 pScrn->videoRam = pAST->pEnt->device->videoRam; 660 from = X_CONFIG; 661 } 662 663 pAST->FbMapSize = pScrn->videoRam * 1024; 664 665#if 0 666 if (!ASTMapMem(pScrn)) { 667 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); 668 return FALSE; 669 } 670#endif 671 672 pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr; 673 pScrn->fbOffset = 0; 674 675 /* Do DDC 676 * should be done after xf86CollectOptions 677 */ 678 pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index); 679 680 /* Mode Valid */ 681 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 682 clockRanges->next = NULL; 683 clockRanges->minClock = 9500; 684 clockRanges->maxClock = ASTGetMaxDCLK(pScrn) * 1000; 685 clockRanges->clockIndex = -1; 686 clockRanges->interlaceAllowed = FALSE; 687 clockRanges->doubleScanAllowed = FALSE; 688 689 /* Add for AST2100, ycchen@061807 */ 690 if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500) || (pAST->jChipType == AST1180)) 691 { 692 maxPitch = 1920; 693 maxHeight = 1200; 694 } 695 else 696 { 697 maxPitch = 1600; 698 maxHeight = 1200; 699 } 700 701 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 702 pScrn->display->modes, clockRanges, 703 0, 320, maxPitch, 8 * pScrn->bitsPerPixel, 704 200, maxHeight, 705 pScrn->display->virtualX, pScrn->display->virtualY, 706 pAST->FbMapSize, LOOKUP_BEST_REFRESH); 707 708 /* fixed some monitors can't get properly validated modes using estimated ratio modes */ 709 if (i < 2) /* validate modes are too few */ 710 { 711 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 712 pScrn->display->modes, clockRanges, 713 0, 320, maxPitch, 8 * pScrn->bitsPerPixel, 714 200, maxHeight, 715 pAST->mon_h_active, pAST->mon_v_active, 716 pAST->FbMapSize, LOOKUP_BEST_REFRESH); 717 } 718 719 if (i == -1) { 720 ASTFreeRec(pScrn); 721 return FALSE; 722 } 723 724 xf86PruneDriverModes(pScrn); 725 726 if (!i || !pScrn->modes) { 727 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 728 ASTFreeRec(pScrn); 729 return FALSE; 730 } 731 732 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 733 734 pScrn->currentMode = pScrn->modes; 735 736 xf86PrintModes(pScrn); 737 738 xf86SetDpi(pScrn, 0, 0); 739 740 /* Acceleration Check */ 741 pAST->noAccel = TRUE; 742 pAST->pCMDQPtr = NULL; 743 pAST->CMDQInfo.ulCMDQSize = 0; 744 pAST->CMDQInfo.pjCmdQBasePort = pAST->MMIOVirtualAddr+ 0x8044; 745 pAST->CMDQInfo.pjWritePort = pAST->MMIOVirtualAddr+ 0x8048; 746 pAST->CMDQInfo.pjReadPort = pAST->MMIOVirtualAddr+ 0x804C; 747 pAST->CMDQInfo.pjEngStatePort = pAST->MMIOVirtualAddr+ 0x804C; 748#ifdef HAVE_XAA_H 749 pAST->AccelInfoPtr = NULL; 750#ifdef Accel_2D 751 if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE)) 752 { 753 if (xf86LoadSubModule(pScrn, "xaa")) { 754 755 pAST->noAccel = FALSE; 756 pAST->MMIO2D = TRUE; 757#ifndef MMIO_2D 758 if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) { 759 pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE; 760 pAST->MMIO2D = FALSE; 761 } 762#endif 763 764 pAST->ENGCaps = ENG_CAP_ALL; 765 if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) { 766 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n"); 767 } 768 769 pAST->DBGSelect = 0; 770 if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) { 771 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n"); 772 } 773 } 774 } 775#endif 776#endif /* HAVE_XAA_H */ 777 778 /* HW Cursor Check */ 779 pAST->noHWC = TRUE; 780 pAST->HWCInfoPtr = NULL; 781 pAST->pHWCPtr = NULL; 782#ifdef HWC 783 if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) { 784 if (!xf86LoadSubModule(pScrn, "ramdac")) { 785 ASTFreeRec(pScrn); 786 return FALSE; 787 } 788 789 pAST->noHWC = FALSE; 790 pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; 791 if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) { 792 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n"); 793 } 794 795 } 796#endif 797 798 /* ShadowFB */ 799#ifdef Support_ShadowFB 800 pAST->shadowFB = FALSE; 801 if (pAST->noAccel == TRUE) /* enable shadowFB only noAccel */ 802 { 803 if (xf86ReturnOptValBool(pAST->Options, OPTION_SHADOW_FB, TRUE)) 804 { 805 if (xf86LoadSubModule(pScrn, "shadow")) { 806 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using \"Shadow Framebuffer\"\n"); 807 pAST->shadowFB = TRUE; 808 } 809 } 810 } 811#endif 812 813#ifndef XSERVER_LIBPCIACCESS 814 /* We won't be using the VGA access after the probe */ 815 xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr); 816 xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr); 817#endif 818 819 return TRUE; 820} 821 822 823static Bool 824ASTScreenInit(SCREEN_INIT_ARGS_DECL) 825{ 826 ScrnInfoPtr pScrn; 827 ASTRecPtr pAST; 828 VisualPtr visual; 829 /* for FB Manager */ 830 BoxRec FBMemBox; 831 int AvailFBSize; 832 833 pScrn = xf86ScreenToScrn(pScreen); 834 pAST = ASTPTR(pScrn); 835 836 if (!ASTMapMem(pScrn)) { 837 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); 838 return FALSE; 839 } 840 841/* if (!pAST->noAccel) */ 842 { 843 /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */ 844 AvailFBSize = pAST->FbMapSize; 845 846 FBMemBox.x1 = 0; 847 FBMemBox.y1 = 0; 848 FBMemBox.x2 = pScrn->displayWidth; 849 FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1; 850 851 if (FBMemBox.y2 < 0) 852 FBMemBox.y2 = 32767; 853 if (FBMemBox.y2 < pScrn->virtualY) 854 return FALSE; 855 856 if (!xf86InitFBManager(pScreen, &FBMemBox)) { 857 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); 858 return FALSE; 859 } 860 861 } 862 863#if !(defined(__sparc__)) && !(defined(__mips__)) 864 vgaHWPtr hwp; 865 hwp = VGAHWPTR(pScrn); 866 vgaHWSetMmioFuncs(hwp, pAST->MMIOVirtualAddr, 0); 867#endif 868 869 vFillASTModeInfo (pScrn); 870 871 ASTSave(pScrn); 872 if (!ASTModeInit(pScrn, pScrn->currentMode)) { 873 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n"); 874 return FALSE; 875 } 876 877 ASTSaveScreen(pScreen, FALSE); 878 ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 879 880 miClearVisualTypes(); 881 882 /* Re-implemented Direct Color support, -jens */ 883 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 884 pScrn->rgbBits, pScrn->defaultVisual)) 885 return FALSE; 886 887 if (!miSetPixmapDepths()) 888 { 889 ASTSaveScreen(pScreen, SCREEN_SAVER_OFF); 890 return FALSE; 891 } 892 893 /* allocate shadowFB */ 894#ifdef Support_ShadowFB 895 pAST->shadowFB_validation = FALSE; 896 if (pAST->shadowFB) { 897 pAST->shadow = calloc(1, pScrn->displayWidth * pScrn->virtualY * 898 ((pScrn->bitsPerPixel + 7) / 8)); 899 if (!pAST->shadow) { 900 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow buffer\n"); 901 } 902 else 903 pAST->shadowFB_validation = TRUE; 904 } 905#endif 906 907 switch(pScrn->bitsPerPixel) { 908 case 8: 909 case 16: 910 case 32: 911#ifdef Support_ShadowFB 912 if (!fbScreenInit(pScreen, pAST->shadowFB_validation ? pAST->shadow : (pAST->FBVirtualAddr + pScrn->fbOffset), 913 pScrn->virtualX, pScrn->virtualY, 914 pScrn->xDpi, pScrn->yDpi, 915 pScrn->displayWidth, pScrn->bitsPerPixel)) 916#else 917 if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset, 918 pScrn->virtualX, pScrn->virtualY, 919 pScrn->xDpi, pScrn->yDpi, 920 pScrn->displayWidth, pScrn->bitsPerPixel)) 921#endif 922 return FALSE; 923 break; 924 default: 925 return FALSE; 926 927 } 928 929 if (pScrn->bitsPerPixel > 8) { 930 /* Fixup RGB ordering */ 931 visual = pScreen->visuals + pScreen->numVisuals; 932 while (--visual >= pScreen->visuals) { 933 if ((visual->class | DynamicClass) == DirectColor) { 934 visual->offsetRed = pScrn->offset.red; 935 visual->offsetGreen = pScrn->offset.green; 936 visual->offsetBlue = pScrn->offset.blue; 937 visual->redMask = pScrn->mask.red; 938 visual->greenMask = pScrn->mask.green; 939 visual->blueMask = pScrn->mask.blue; 940 } 941 } 942 } 943 944 /* Must be after RGB order fixed */ 945 fbPictureInit(pScreen, 0, 0); 946 947 /* shadowFB setup */ 948#ifdef Support_ShadowFB 949 if (pAST->shadowFB_validation) { 950 pAST->update = ASTUpdatePacked; 951 pAST->window = ASTWindowLinear; 952 953 if (!shadowSetup(pScreen)) 954 { 955 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to setup shadow buffer\n"); 956 return FALSE; 957 } 958 959 pAST->CreateScreenResources = pScreen->CreateScreenResources; 960 pScreen->CreateScreenResources = ASTCreateScreenResources; 961 } 962#endif 963 964 xf86SetBlackWhitePixels(pScreen); 965 966#ifdef HAVE_XAA_H 967#ifdef Accel_2D 968 if (!pAST->noAccel) 969 { 970 if (!ASTAccelInit(pScreen)) { 971 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n"); 972 pAST->noAccel = TRUE; 973 } 974 } 975#endif /* end of Accel_2D */ 976#endif 977 978 xf86SetBackingStore(pScreen); 979 xf86SetSilkenMouse(pScreen); 980 981 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 982 983 if (!pAST->noHWC) 984 { 985 if (!ASTCursorInit(pScreen)) { 986 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n"); 987 pAST->noHWC = TRUE; 988 } 989 } 990 991 if (!miCreateDefColormap(pScreen)) 992 return FALSE; 993 994 if (pAST->jChipType != AST1180) 995 { 996 if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, 997 vASTLoadPalette, NULL, 998 CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { 999 return FALSE; 1000 } 1001 } 1002 1003 xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0); 1004 1005#ifdef AstVideo 1006 if ( (pAST->jChipType == AST1180) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500) ) 1007 { 1008 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"AST Initial Video()\n"); 1009 ASTInitVideo(pScreen); 1010 } 1011#endif 1012 1013 pScreen->SaveScreen = ASTSaveScreen; 1014 pAST->CloseScreen = pScreen->CloseScreen; 1015 pScreen->CloseScreen = ASTCloseScreen; 1016 1017 if (serverGeneration == 1) 1018 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1019 1020 return TRUE; 1021 1022} /* ASTScreenInit */ 1023 1024 1025Bool 1026ASTSwitchMode(SWITCH_MODE_ARGS_DECL) 1027{ 1028 SCRN_INFO_PTR(arg); 1029 ASTRecPtr pAST = ASTPTR(pScrn); 1030 1031 /* VideoMode validate */ 1032 if (mode->CrtcHDisplay > pScrn->displayWidth) 1033 return FALSE; 1034 if ((pAST->VideoModeInfo.ScreenPitch * mode->CrtcVDisplay) > pAST->ulVRAMSize) 1035 return FALSE; 1036 1037 /* VideModeInfo Update */ 1038 pAST->VideoModeInfo.ScreenWidth = mode->CrtcHDisplay; 1039 pAST->VideoModeInfo.ScreenHeight = mode->CrtcVDisplay; 1040 pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ; 1041 1042#ifdef HWC 1043 if (pAST->pHWCPtr) { 1044 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 1045 pAST->pHWCPtr = NULL; 1046 } 1047 ASTDisableHWC(pScrn); 1048#endif 1049 1050#ifdef Accel_2D 1051 if (pAST->pCMDQPtr) { 1052 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 1053 pAST->pCMDQPtr = NULL; 1054 } 1055 vASTDisable2D(pScrn, pAST); 1056#endif 1057 1058 /* Fixed display abnormal on the of the screen if run xvidtune, ycchen@122909 */ 1059 /* ASTRestore(pScrn); */ 1060 1061 return ASTModeInit(pScrn, mode); 1062 1063} 1064 1065void 1066ASTAdjustFrame(ADJUST_FRAME_ARGS_DECL) 1067{ 1068 SCRN_INFO_PTR(arg); 1069 ASTRecPtr pAST = ASTPTR(pScrn); 1070 ULONG base; 1071 1072 base = y * pAST->VideoModeInfo.ScreenPitch + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8); 1073 /* base = base >> 2; */ /* DW unit */ 1074 1075 vASTSetStartAddressCRT1(pAST, base); 1076 1077} 1078 1079/* enter into X Server */ 1080static Bool 1081ASTEnterVT(VT_FUNC_ARGS_DECL) 1082{ 1083 SCRN_INFO_PTR(arg); 1084 ASTRecPtr pAST = ASTPTR(pScrn); 1085 1086 /* Fixed suspend can't resume issue */ 1087 if (!bASTIsVGAEnabled(pScrn)) 1088 { 1089 if (pAST->jChipType == AST1180) 1090 bASTInitAST1180(pScrn); 1091 else 1092 { 1093 vASTEnableVGAMMIO(pScrn); 1094 ASTInitVGA(pScrn, 1); 1095 } 1096 ASTRestore(pScrn); 1097 } 1098 1099 if (!ASTModeInit(pScrn, pScrn->currentMode)) 1100 return FALSE; 1101 ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 1102 1103 return TRUE; 1104 1105} 1106 1107/* leave X server */ 1108static void 1109ASTLeaveVT(VT_FUNC_ARGS_DECL) 1110{ 1111 1112 SCRN_INFO_PTR(arg); 1113 ASTRecPtr pAST = ASTPTR(pScrn); 1114#if !(defined(__sparc__)) && !(defined(__mips__)) 1115 vgaHWPtr hwp = VGAHWPTR(pScrn); 1116#endif 1117 1118#ifdef HWC 1119 if (pAST->pHWCPtr) { 1120 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 1121 pAST->pHWCPtr = NULL; 1122 } 1123 ASTDisableHWC(pScrn); 1124#endif 1125 1126#ifdef Accel_2D 1127 if (pAST->pCMDQPtr) { 1128 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 1129 pAST->pCMDQPtr = NULL; 1130 } 1131 vASTDisable2D(pScrn, pAST); 1132#endif 1133 1134 ASTRestore(pScrn); 1135 1136 if (pAST->jChipType == AST1180) 1137 ASTBlankScreen(pScrn, 0); 1138 1139#if !(defined(__sparc__)) && !(defined(__mips__)) 1140 vgaHWLock(hwp); 1141#endif 1142 1143} 1144 1145static void 1146ASTFreeScreen(FREE_SCREEN_ARGS_DECL) 1147{ 1148 SCRN_INFO_PTR(arg); 1149 ASTFreeRec(pScrn); 1150#if !(defined(__sparc__)) && !(defined(__mips__)) 1151 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 1152 vgaHWFreeHWRec(pScrn); 1153#endif 1154} 1155 1156static ModeStatus 1157ASTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 1158{ 1159 SCRN_INFO_PTR(arg); 1160 ASTRecPtr pAST = ASTPTR(pScrn); 1161 ModeStatus Flags = MODE_NOMODE; 1162 UCHAR jReg; 1163 ULONG RequestBufferSize; 1164 1165 if (mode->Flags & V_INTERLACE) { 1166 if (verbose) { 1167 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1168 "Removing interlaced mode \"%s\"\n", mode->name); 1169 } 1170 return MODE_NO_INTERLACE; 1171 } 1172 1173 if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) { 1174 if (verbose) { 1175 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1176 "Removing the mode \"%s\"\n", mode->name); 1177 } 1178 return Flags; 1179 } 1180 1181 /* Valid Framebuffer size */ 1182 RequestBufferSize = mode->CrtcHDisplay * ((pScrn->bitsPerPixel + 1) / 8) * mode->CrtcVDisplay; 1183 if (RequestBufferSize > pAST->ulVRAMSize) 1184 return Flags; 1185 1186 /* Valid Wide Screen Mode */ 1187 if (pAST->SupportWideScreen) 1188 { 1189 if ( (mode->CrtcHDisplay == 1680) && (mode->CrtcVDisplay == 1050) ) 1190 return MODE_OK; 1191 if ( (mode->CrtcHDisplay == 1280) && (mode->CrtcVDisplay == 800) ) 1192 return MODE_OK; 1193 if ( (mode->CrtcHDisplay == 1440) && (mode->CrtcVDisplay == 900) ) 1194 return MODE_OK; 1195 if ( (mode->CrtcHDisplay == 1360) && (mode->CrtcVDisplay == 768) ) 1196 return MODE_OK; 1197 if ( (mode->CrtcHDisplay == 1600) && (mode->CrtcVDisplay == 900) ) 1198 return MODE_OK; 1199 1200 if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST2500) || (pAST->jChipType == AST1180) ) 1201 { 1202 if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1080) ) 1203 return MODE_OK; 1204 1205 if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) ) 1206 { 1207 GetIndexRegMask(CRTC_PORT, 0xD1, 0xFF, jReg); 1208 if (jReg & 0x01) 1209 return MODE_NOMODE; 1210 else 1211 return MODE_OK; 1212 } 1213 } 1214 } 1215 1216 switch (mode->CrtcHDisplay) 1217 { 1218 case 640: 1219 if (mode->CrtcVDisplay == 480) Flags=MODE_OK; 1220 break; 1221 case 800: 1222 if (mode->CrtcVDisplay == 600) Flags=MODE_OK; 1223 break; 1224 case 1024: 1225 if (mode->CrtcVDisplay == 768) Flags=MODE_OK; 1226 break; 1227 case 1280: 1228 if (mode->CrtcVDisplay == 1024) Flags=MODE_OK; 1229 break; 1230 case 1600: 1231 if (mode->CrtcVDisplay == 1200) Flags=MODE_OK; 1232 break; 1233 default: 1234 return Flags; 1235 } 1236 1237 return Flags; 1238} 1239 1240/* Internal used modules */ 1241/* 1242 * ASTGetRec and ASTFreeRec -- 1243 * 1244 * Private data for the driver is stored in the screen structure. 1245 * These two functions create and destroy that private data. 1246 * 1247 */ 1248static Bool 1249ASTGetRec(ScrnInfoPtr pScrn) 1250{ 1251 if (pScrn->driverPrivate) 1252 return TRUE; 1253 1254 pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1); 1255 return TRUE; 1256} 1257 1258static void 1259ASTFreeRec(ScrnInfoPtr pScrn) 1260{ 1261 ASTRecPtr pAST = ASTPTR(pScrn); 1262 1263 if (!pScrn) 1264 return; 1265 if (!pScrn->driverPrivate) 1266 return; 1267 if (pAST->pDP501FWBufferVirtualAddress) 1268 free(pAST->pDP501FWBufferVirtualAddress); 1269 free(pScrn->driverPrivate); 1270 pScrn->driverPrivate = 0; 1271} 1272 1273static Bool 1274ASTSaveScreen(ScreenPtr pScreen, Bool unblack) 1275{ 1276#if !(defined(__sparc__)) && !(defined(__mips__)) 1277 /* replacement of vgaHWBlankScreen(pScrn, unblank) without seq reset */ 1278 /* return vgaHWSaveScreen(pScreen, unblack); */ 1279 ScrnInfoPtr pScrn = NULL; 1280 1281 if (pScreen != NULL) 1282 pScrn = xf86ScreenToScrn(pScreen); 1283 1284 if ((pScrn != NULL) && pScrn->vtSema) { 1285 ASTBlankScreen(pScrn, unblack); 1286 } 1287 return (TRUE); 1288#endif 1289} 1290 1291static Bool 1292ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL) 1293{ 1294 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1295 ASTRecPtr pAST = ASTPTR(pScrn); 1296#if !(defined(__sparc__)) && !(defined(__mips__)) 1297 vgaHWPtr hwp = VGAHWPTR(pScrn); 1298#endif 1299 1300 if (pScrn->vtSema == TRUE) 1301 { 1302#ifdef HWC 1303 if (pAST->pHWCPtr) { 1304 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 1305 pAST->pHWCPtr = NULL; 1306 } 1307 ASTDisableHWC(pScrn); 1308#endif 1309 1310#ifdef Accel_2D 1311 if (pAST->pCMDQPtr) { 1312 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 1313 pAST->pCMDQPtr = NULL; 1314 } 1315 vASTDisable2D(pScrn, pAST); 1316#endif 1317 1318 ASTRestore(pScrn); 1319 1320 if (pAST->jChipType == AST1180) 1321 ASTBlankScreen(pScrn, 0); 1322 1323#if !(defined(__sparc__)) && !(defined(__mips__)) 1324 vgaHWLock(hwp); 1325#endif 1326 } 1327 1328 ASTUnmapMem(pScrn); 1329#if !(defined(__sparc__)) && !(defined(__mips__)) 1330 vgaHWUnmapMem(pScrn); 1331#endif 1332 1333#ifdef HAVE_XAA_H 1334 if(pAST->AccelInfoPtr) { 1335 XAADestroyInfoRec(pAST->AccelInfoPtr); 1336 pAST->AccelInfoPtr = NULL; 1337 } 1338#endif 1339 if(pAST->HWCInfoPtr) { 1340 xf86DestroyCursorInfoRec(pAST->HWCInfoPtr); 1341 pAST->HWCInfoPtr = NULL; 1342 } 1343 1344#ifdef Support_ShadowFB 1345 if (pAST->shadowFB_validation) { 1346 shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); 1347 free(pAST->shadow); 1348 pScreen->CreateScreenResources = pAST->CreateScreenResources; 1349 } 1350#endif 1351 1352 pScrn->vtSema = FALSE; 1353 pScreen->CloseScreen = pAST->CloseScreen; 1354 return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS); 1355} 1356 1357static void 1358ASTSave(ScrnInfoPtr pScrn) 1359{ 1360 ASTRecPtr pAST; 1361 ASTRegPtr astReg; 1362 int i, icount=0; 1363 ULONG ulData; 1364 1365 pAST = ASTPTR(pScrn); 1366 astReg = &pAST->SavedReg; 1367 1368 if (pAST->jChipType == AST1180) 1369 { 1370 for (i=0; i<12; i++) 1371 { 1372 ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData); 1373 astReg->GFX[i] = ulData; 1374 } 1375 } 1376 else 1377 { 1378#if defined(__sparc__) || defined(__mips__) 1379 UCHAR jReg; 1380 1381 /* Save Misc */ 1382 astReg->MISC = GetReg(MISC_PORT_READ); 1383 1384 /* Save SR */ 1385 for (i=0; i<4; i++) 1386 GetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]); 1387 1388 /* Save CR */ 1389 for (i=0; i<25; i++) 1390 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]); 1391 1392 /* Save GR */ 1393 for (i=0; i<9; i++) 1394 GetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]); 1395 1396 /* Save AR */ 1397 jReg = GetReg(INPUT_STATUS1_READ); 1398 for (i=0; i<20; i++) 1399 GetIndexReg(AR_PORT_WRITE, (UCHAR) (i), astReg->AR[i]); 1400 jReg = GetReg(INPUT_STATUS1_READ); 1401 SetReg (AR_PORT_WRITE, 0x20); /* set POS */ 1402#else 1403 vgaRegPtr vgaReg; 1404 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 1405 1406 /* do save */ 1407 if (xf86IsPrimaryPci(pAST->PciInfo)) { 1408 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS); 1409 } 1410 else { 1411 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE); 1412 } 1413#endif 1414 1415 /* Save Ext. */ 1416 vASTOpenKey(pScrn); 1417 1418 /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ 1419 for (i=0x81; i<=0xB6; i++) 1420 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1421 for (i=0xBC; i<=0xC1; i++) 1422 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1423 GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); 1424 1425 /* Save DAC */ 1426 for (i=0; i<256; i++) 1427 VGA_GET_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]); 1428 1429 /* Save 2D */ 1430 astReg->ENG8044 = 0; 1431 GetIndexReg(CRTC_PORT, 0xA4, astReg->REGA4); 1432 if (astReg->REGA4 & 0x01) /* 2D enabled */ 1433 astReg->ENG8044 = *(ULONG *) (pAST->MMIOVirtualAddr + 0x8044); 1434 } 1435 1436} 1437 1438static void 1439ASTRestore(ScrnInfoPtr pScrn) 1440{ 1441 ASTRecPtr pAST; 1442 ASTRegPtr astReg; 1443 int i, icount=0; 1444 ULONG ulData; 1445 1446 pAST = ASTPTR(pScrn); 1447 astReg = &pAST->SavedReg; 1448 1449 ASTDisplayPowerManagementSet(pScrn, DPMSModeOff, 0); 1450 1451 if (pAST->jChipType == AST1180) 1452 { 1453 for (i=0; i<12; i++) 1454 { 1455 ulData = astReg->GFX[i]; 1456 WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData); 1457 } 1458 } 1459 else 1460 { 1461#if defined(__sparc__) || defined(__mips__) 1462 UCHAR jReg; 1463 1464 /* Restore Misc */ 1465 SetReg(MISC_PORT_WRITE, astReg->MISC); 1466 1467 /* Restore SR */ 1468 for (i=0; i<4; i++) 1469 SetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]); 1470 1471 /* Restore CR */ 1472 SetIndexRegMask(CRTC_PORT,0x11, 0x7F, 0x00); 1473 for (i=0; i<25; i++) 1474 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]); 1475 1476 /* Restore GR */ 1477 for (i=0; i<9; i++) 1478 SetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]); 1479 1480 /* Restore AR */ 1481 jReg = GetReg(INPUT_STATUS1_READ); 1482 for (i=0; i<20; i++) 1483 { 1484 SetReg(AR_PORT_WRITE, (UCHAR) i); 1485 SetReg(AR_PORT_WRITE, astReg->AR[i]); 1486 } 1487 SetReg(AR_PORT_WRITE, 0x14); 1488 SetReg(AR_PORT_WRITE, 0x00); 1489 1490 jReg = GetReg(INPUT_STATUS1_READ); 1491 SetReg (AR_PORT_WRITE, 0x20); /* set POS */ 1492#else 1493 vgaRegPtr vgaReg; 1494 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 1495 1496 /* do restore */ 1497 vgaHWProtect(pScrn, TRUE); 1498 if (xf86IsPrimaryPci(pAST->PciInfo)) 1499 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS); 1500 else 1501 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 1502 vgaHWProtect(pScrn, FALSE); 1503#endif 1504 1505 /* Ext. restore */ 1506 vASTOpenKey(pScrn); 1507 1508 /* Restore DAC */ 1509 for (i=0; i<256; i++) 1510 VGA_LOAD_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]); 1511 1512 /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ 1513 for (i=0x81; i<=0xB6; i++) 1514 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1515 for (i=0xBC; i<=0xC1; i++) 1516 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1517 SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); 1518 } 1519 1520} 1521 1522static void 1523ASTProbeDDC(ScrnInfoPtr pScrn, int index) 1524{ 1525 ASTRecPtr pAST = ASTPTR(pScrn); 1526 unsigned char DDC_data[128]; 1527 Bool Flags; 1528 1529 if (xf86LoadSubModule(pScrn, "ddc")) 1530 { 1531 if (pAST->jChipType == AST1180) 1532 Flags = ASTGetVGA2EDID(pScrn, DDC_data); 1533 else if (pAST->jTxChipType == Tx_DP501) 1534 { 1535 Flags = ASTReadEDID_M68K(pScrn, DDC_data); 1536 if (Flags == FALSE) 1537 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1538 } 1539 else 1540 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1541 1542 if (Flags) 1543 { 1544 ConfiguredMonitor = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); 1545 } 1546 else 1547 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Get EDID Properly \n"); 1548 } 1549 else 1550 { 1551 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n"); 1552 } 1553 1554} 1555 1556#define SkipDT 0x00 1557#define DT1 0x01 1558#define DT2 0x02 1559 1560static xf86MonPtr 1561ASTDoDDC(ScrnInfoPtr pScrn, int index) 1562{ 1563 xf86MonPtr MonInfo = NULL; 1564 ASTRecPtr pAST = ASTPTR(pScrn); 1565 unsigned char DDC_data[128]; 1566 Bool Flags; 1567 1568 xf86MonPtr MonInfo1 = NULL, MonInfo2 = NULL; 1569 unsigned long i, j, k; 1570 struct monitor_ranges ranges, ranges1, ranges2; 1571 int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0; 1572 struct std_timings stdtiming, *stdtiming1, *stdtiming2; 1573 1574 /* Honour Option "noDDC" */ 1575 if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) { 1576 return MonInfo; 1577 } 1578 1579 if (xf86LoadSubModule(pScrn, "ddc")) 1580 { 1581 if (pAST->jChipType == AST1180) 1582 Flags = ASTGetVGA2EDID(pScrn, DDC_data); 1583 else if (pAST->jTxChipType == Tx_DP501) 1584 { 1585 pAST->DP501_MaxVCLK = 0xFF; 1586 Flags = ASTReadEDID_M68K(pScrn, DDC_data); 1587 if (Flags) pAST->DP501_MaxVCLK = ASTGetLinkMaxCLK(pScrn); 1588 else 1589 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1590 } 1591 else 1592 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1593 1594 if (Flags) 1595 { 1596 MonInfo = MonInfo1 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); 1597 1598 /* Valid Wide Screen Support */ 1599 if ( (MonInfo) && (MonInfo->det_mon[0].type == 0x00) ) 1600 { 1601 if ( (MonInfo->det_mon[0].section.d_timings.h_active * 10 / MonInfo->det_mon[0].section.d_timings.v_active) < 14 ) 1602 pAST->SupportWideScreen = FALSE; 1603 } 1604 } 1605 1606 /* For VGA2 CLONE Support, ycchen@012508 */ 1607 if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) { 1608 if (ASTGetVGA2EDID(pScrn, DDC_data) == TRUE) { 1609 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n"); 1610 MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); 1611 if (MonInfo1 == NULL) /* No DDC1 EDID */ 1612 MonInfo = MonInfo2; 1613 else { /* Check with VGA1 & VGA2 EDID */ 1614 /* Update establishment timing */ 1615 MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1; 1616 MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2; 1617 MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu; 1618 1619 /* Update Std. Timing */ 1620 for (i=0; i<8; i++) { 1621 stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; 1622 for (j=0; j<8; j++) { 1623 if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \ 1624 (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \ 1625 (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) { 1626 stdtiming = MonInfo1->timings2[i]; 1627 break; 1628 } 1629 } 1630 1631 MonInfo->timings2[i] = stdtiming; 1632 } /* Std. Timing */ 1633 1634 /* Get Detailed Timing */ 1635 for (i=0;i<4;i++) { 1636 if (MonInfo1->det_mon[i].type == 0xFD) 1637 ranges1 = MonInfo1->det_mon[i].section.ranges; 1638 else if (MonInfo1->det_mon[i].type == 0xFA) 1639 stdtiming1 = MonInfo1->det_mon[i].section.std_t; 1640 else if (MonInfo1->det_mon[i].type == 0x00) { 1641 if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1) 1642 dclock1 = MonInfo1->det_mon[i].section.d_timings.clock; 1643 if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1) 1644 h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active; 1645 if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1) 1646 v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active; 1647 } 1648 if (MonInfo2->det_mon[i].type == 0xFD) 1649 ranges2 = MonInfo2->det_mon[i].section.ranges; 1650 else if (MonInfo1->det_mon[i].type == 0xFA) 1651 stdtiming2 = MonInfo2->det_mon[i].section.std_t; 1652 else if (MonInfo2->det_mon[i].type == 0x00) { 1653 if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2) 1654 dclock2 = MonInfo2->det_mon[i].section.d_timings.clock; 1655 if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2) 1656 h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active; 1657 if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2) 1658 v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active; 1659 } 1660 } /* Get Detailed Timing */ 1661 1662 /* Chk Detailed Timing */ 1663 if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2)) 1664 DTSelect = DT2; 1665 else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1)) 1666 DTSelect = DT1; 1667 else 1668 DTSelect = SkipDT; 1669 1670 /* Chk Monitor Descriptor */ 1671 ranges = ranges1; 1672 ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h; 1673 ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v; 1674 ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h; 1675 ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v; 1676 ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock; 1677 1678 /* Update Detailed Timing */ 1679 for (i=0; i<4; i++) 1680 { 1681 if (MonInfo->det_mon[i].type == 0xFD) { 1682 MonInfo->det_mon[i].section.ranges = ranges; 1683 } 1684 else if (MonInfo->det_mon[i].type == 0xFA) { 1685 for (j=0; j<5; j++) { 1686 stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; 1687 for (k=0; k<5; k++) { 1688 if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \ 1689 (stdtiming1[j].vsize == stdtiming2[k].vsize) && \ 1690 (stdtiming1[j].refresh == stdtiming2[k].refresh)) { 1691 stdtiming = stdtiming1[j]; 1692 break; 1693 } 1694 } 1695 stdtiming1[j] = stdtiming; 1696 } /* Std. Timing */ 1697 } /* FA */ 1698 else if (MonInfo->det_mon[i].type == 0x00) { 1699 if (DTSelect == DT2) 1700 MonInfo->det_mon[i] = MonInfo2->det_mon[i]; 1701 else if (DTSelect == DT1) 1702 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1703 else /* SkipDT */ 1704 { /* use 1024x768 as default */ 1705 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1706 MonInfo->det_mon[i].section.d_timings.clock = 65000000; 1707 MonInfo->det_mon[i].section.d_timings.h_active = 1024; 1708 MonInfo->det_mon[i].section.d_timings.h_blanking = 320; 1709 MonInfo->det_mon[i].section.d_timings.v_active = 768; 1710 MonInfo->det_mon[i].section.d_timings.v_blanking = 38; 1711 MonInfo->det_mon[i].section.d_timings.h_sync_off = 24; 1712 MonInfo->det_mon[i].section.d_timings.h_sync_width = 136; 1713 MonInfo->det_mon[i].section.d_timings.v_sync_off = 3; 1714 MonInfo->det_mon[i].section.d_timings.v_sync_width = 6; 1715 } 1716 } /* 00 */ 1717 else { /* use Monitor 1 as default */ 1718 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1719 } 1720 1721 } /* Update Detailed Timing */ 1722 1723 /* set feature size */ 1724 if (DTSelect == DT2) { 1725 MonInfo->features.hsize = MonInfo2->features.hsize; 1726 MonInfo->features.vsize = MonInfo2->features.vsize; 1727 } 1728 else if (DTSelect == DT1) { 1729 MonInfo->features.hsize = MonInfo1->features.hsize; 1730 MonInfo->features.vsize = MonInfo1->features.vsize; 1731 } 1732 else /* Skip DT */ 1733 { /* use 1024x768 as default */ 1734 MonInfo->features.hsize = 0x20; 1735 MonInfo->features.vsize = 0x18; 1736 } 1737 1738 } /* Check with VGA1 & VGA2 EDID */ 1739 1740 } /* ASTGetVGA2EDID */ 1741 else { 1742 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n"); 1743 } 1744 } /* VGA2Clone */ 1745 1746 xf86PrintEDID(MonInfo); 1747 xf86SetDDCproperties(pScrn, MonInfo); 1748 } 1749 else 1750 { 1751 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTDoDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n"); 1752 } 1753 1754 /* Fill pAST Monitor Info */ 1755 if (MonInfo == NULL) 1756 { /* default for Non-EDID */ 1757 pAST->mon_h_active = 1024; 1758 pAST->mon_v_active = 768; 1759 } 1760 else 1761 { /* save MonInfo to Private */ 1762 pAST->mon_h_active = MonInfo->det_mon[0].section.d_timings.h_active; 1763 pAST->mon_v_active = MonInfo->det_mon[0].section.d_timings.v_active; 1764 } 1765 1766 return MonInfo; 1767} 1768 1769static void 1770vFillASTModeInfo (ScrnInfoPtr pScrn) 1771{ 1772 ASTRecPtr pAST; 1773 1774 pAST = ASTPTR(pScrn); 1775 1776 pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX; 1777 pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY; 1778 pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel; 1779 /* Fixed screen pitch incorrect in some specific monitor, ycchen@071707 */ 1780 pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ; 1781 1782} 1783 1784static Bool 1785ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1786{ 1787 ASTRecPtr pAST; 1788 1789 pAST = ASTPTR(pScrn); 1790 1791 pScrn->vtSema = TRUE; 1792 pAST->ModePtr = mode; 1793 1794#if defined(__sparc__) || defined(__mips__) 1795 if (!ASTSetMode(pScrn, mode)) 1796 return FALSE; 1797#else 1798 vgaHWPtr hwp; 1799 1800 hwp = VGAHWPTR(pScrn); 1801 1802 vgaHWUnlock(hwp); 1803 1804 if (!vgaHWInit(pScrn, mode)) 1805 return FALSE; 1806 1807 pScrn->vtSema = TRUE; 1808 pAST->ModePtr = mode; 1809 1810 if (!ASTSetMode(pScrn, mode)) 1811 return FALSE; 1812 1813 vgaHWProtect(pScrn, FALSE); 1814#endif 1815 1816 return TRUE; 1817} 1818 1819#ifdef AstVideo 1820/* 1821 * Video Part by ic_yang 1822 */ 1823#include "fourcc.h" 1824 1825#define NUM_ATTRIBUTES 8 1826#define NUM_IMAGES 8 1827#define NUM_FORMATS 3 1828 1829#define IMAGE_MIN_WIDTH 32 1830#define IMAGE_MIN_HEIGHT 24 1831#define IMAGE_MAX_WIDTH 1920 1832#define IMAGE_MAX_HEIGHT 1080 1833 1834#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 1835 1836static XF86ImageRec ASTImages[NUM_IMAGES] = 1837{ 1838 XVIMAGE_YUY2, /* If order is changed, ASTOffscreenImages must be adapted */ 1839}; 1840 1841static XF86VideoFormatRec ASTFormats[NUM_FORMATS] = 1842{ 1843 { 8, PseudoColor}, 1844 {16, TrueColor}, 1845 {24, TrueColor} 1846}; 1847 1848/* client libraries expect an encoding */ 1849static XF86VideoEncodingRec DummyEncoding = 1850{ 1851 0, 1852 "XV_IMAGE", 1853 0, 0, /* Will be filled in */ 1854 {1, 1} 1855}; 1856 1857static char astxvcolorkey[] = "XV_COLORKEY"; 1858static char astxvbrightness[] = "XV_BRIGHTNESS"; 1859static char astxvcontrast[] = "XV_CONTRAST"; 1860static char astxvsaturation[] = "XV_SATURATION"; 1861static char astxvhue[] = "XV_HUE"; 1862static char astxvgammared[] = "XV_GAMMA_RED"; 1863static char astxvgammagreen[] = "XV_GAMMA_GREEN"; 1864static char astxvgammablue[] = "XV_GAMMA_BLUE"; 1865 1866static XF86AttributeRec ASTAttributes[NUM_ATTRIBUTES] = 1867{ 1868 {XvSettable | XvGettable, 0, (1 << 24) - 1, astxvcolorkey}, 1869 {XvSettable | XvGettable, -128, 127, astxvbrightness}, 1870 {XvSettable | XvGettable, 0, 255, astxvcontrast}, 1871 {XvSettable | XvGettable, -180, 180, astxvsaturation}, 1872 {XvSettable | XvGettable, -180, 180, astxvhue}, 1873 {XvSettable | XvGettable, 100, 10000, astxvgammared}, 1874 {XvSettable | XvGettable, 100, 10000, astxvgammagreen}, 1875 {XvSettable | XvGettable, 100, 10000, astxvgammablue}, 1876}; 1877 1878static void ASTStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) 1879{ 1880 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 1881 ASTPtr pAST = ASTPTR(pScrn); 1882 1883 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1884 1885 if(exit) 1886 { 1887 if(pPriv->fbAreaPtr) 1888 { 1889 xf86FreeOffscreenArea(pPriv->fbAreaPtr); 1890 pPriv->fbAreaPtr = NULL; 1891 pPriv->fbSize = 0; 1892 } 1893 /* clear all flag */ 1894 pPriv->videoStatus = 0; 1895 } 1896 else 1897 { 1898#if 0 1899 if(pPriv->videoStatus & CLIENT_VIDEO_ON) 1900 { 1901 pPriv->videoStatus |= OFF_TIMER; 1902 1903 } 1904#endif 1905 } 1906} 1907 1908static int ASTSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data) 1909{ 1910 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 1911 ASTPtr pAST = ASTPTR(pScrn); 1912 1913 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTSetPortAttribute(),attribute=%x\n", attribute); 1914 1915 if (attribute == pAST->xvBrightness) 1916 { 1917 if((value < -128) || (value > 127)) 1918 return BadValue; 1919 1920 pPriv->brightness = value; 1921 } 1922 else if (attribute == pAST->xvContrast) 1923 { 1924 if ((value < 0) || (value > 255)) 1925 return BadValue; 1926 1927 pPriv->contrast = value; 1928 } 1929 else if (attribute == pAST->xvSaturation) 1930 { 1931 if ((value < -180) || (value > 180)) 1932 return BadValue; 1933 1934 pPriv->saturation = value; 1935 } 1936 else if (attribute == pAST->xvHue) 1937 { 1938 if ((value < -180) || (value > 180)) 1939 return BadValue; 1940 1941 pPriv->hue = value; 1942 } 1943 else if (attribute == pAST->xvColorKey) 1944 { 1945 pPriv->colorKey = value; 1946 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1947 } 1948 else if(attribute == pAST->xvGammaRed) 1949 { 1950 if((value < 100) || (value > 10000)) 1951 return BadValue; 1952 pPriv->gammaR = value; 1953 } 1954 else if(attribute == pAST->xvGammaGreen) 1955 { 1956 if((value < 100) || (value > 10000)) 1957 return BadValue; 1958 pPriv->gammaG = value; 1959 } 1960 else if(attribute == pAST->xvGammaBlue) 1961 { 1962 if((value < 100) || (value > 10000)) 1963 return BadValue; 1964 pPriv->gammaB = value; 1965 } 1966 else 1967 { 1968 return BadMatch; 1969 } 1970 1971 return Success; 1972} 1973 1974static int ASTGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data) 1975{ 1976 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 1977 ASTPtr pAST = ASTPTR(pScrn); 1978 1979 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTGetPortAttribute(),attribute=%x\n", attribute); 1980 1981 if (attribute == pAST->xvBrightness) 1982 { 1983 *value = pPriv->brightness; 1984 } 1985 else if (attribute == pAST->xvContrast) 1986 { 1987 *value = pPriv->contrast; 1988 } 1989 else if (attribute == pAST->xvSaturation) 1990 { 1991 *value = pPriv->saturation; 1992 } 1993 else if (attribute == pAST->xvHue) 1994 { 1995 *value = pPriv->hue; 1996 } 1997 else if(attribute == pAST->xvGammaRed) 1998 { 1999 *value = pPriv->gammaR; 2000 2001 } 2002 else if(attribute == pAST->xvGammaGreen) 2003 { 2004 *value = pPriv->gammaG; 2005 } 2006 else if(attribute == pAST->xvGammaBlue) 2007 { 2008 *value = pPriv->gammaB; 2009 } 2010 else if (attribute == pAST->xvColorKey) 2011 { 2012 *value = pPriv->colorKey; 2013 } 2014 else 2015 return BadMatch; 2016 2017 return Success; 2018} 2019 2020static void ASTQueryBestSize(ScrnInfoPtr pScrn, Bool motion, 2021 short vid_w, short vid_h, 2022 short drw_w, short drw_h, 2023 unsigned int *p_w, unsigned int *p_h, 2024 pointer data) 2025{ 2026 *p_w = drw_w; 2027 *p_h = drw_h; 2028 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryBestSize()\n"); 2029 /* TODO: report the HW limitation */ 2030} 2031 2032static int ASTQueryImageAttributes(ScrnInfoPtr pScrn, int id, 2033 unsigned short *w, unsigned short *h, 2034 int *pitches, int *offsets) 2035{ 2036 int pitchY, pitchUV; 2037 int size, sizeY, sizeUV; 2038 2039 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryImageAttributes()\n"); 2040 2041 if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH; 2042 if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT; 2043 2044 switch(id) { 2045 case PIXEL_FMT_YV12: 2046 *w = (*w + 7) & ~7; 2047 *h = (*h + 1) & ~1; 2048 pitchY = *w; 2049 pitchUV = *w >> 1; 2050 if(pitches) { 2051 pitches[0] = pitchY; 2052 pitches[1] = pitches[2] = pitchUV; 2053 } 2054 sizeY = pitchY * (*h); 2055 sizeUV = pitchUV * ((*h) >> 1); 2056 if(offsets) { 2057 offsets[0] = 0; 2058 offsets[1] = sizeY; 2059 offsets[2] = sizeY + sizeUV; 2060 } 2061 size = sizeY + (sizeUV << 1); 2062 break; 2063 case PIXEL_FMT_NV12: 2064 case PIXEL_FMT_NV21: 2065 *w = (*w + 7) & ~7; 2066 *h = (*h + 1) & ~1; 2067 pitchY = *w; 2068 pitchUV = *w; 2069 if(pitches) { 2070 pitches[0] = pitchY; 2071 pitches[1] = pitchUV; 2072 } 2073 sizeY = pitchY * (*h); 2074 sizeUV = pitchUV * ((*h) >> 1); 2075 if(offsets) { 2076 offsets[0] = 0; 2077 offsets[1] = sizeY; 2078 } 2079 size = sizeY + (sizeUV << 1); 2080 break; 2081 case PIXEL_FMT_YUY2: 2082 case PIXEL_FMT_UYVY: 2083 case PIXEL_FMT_YVYU: 2084 case PIXEL_FMT_RGB6: 2085 case PIXEL_FMT_RGB5: 2086 default: 2087 *w = (*w + 1) & ~1; 2088 pitchY = *w << 1; 2089 if(pitches) pitches[0] = pitchY; 2090 if(offsets) offsets[0] = 0; 2091 size = pitchY * (*h); 2092 break; 2093 } 2094 2095 return size; 2096} 2097 2098static int ASTPutImage(ScrnInfoPtr pScrn, 2099 short src_x, short src_y, 2100 short drw_x, short drw_y, 2101 short src_w, short src_h, 2102 short drw_w, short drw_h, 2103 int id, unsigned char* buf, 2104 short width, short height, 2105 Bool sync, 2106 RegionPtr clipBoxes, pointer data 2107#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1 2108 , DrawablePtr pDraw 2109#endif 2110) 2111{ 2112 ASTPtr pAST = ASTPTR(pScrn); 2113 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 2114 int i; 2115 int totalSize=0; 2116 2117 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImage()\n"); 2118 /* int depth = pAST->CurrentLayout.bitsPerPixel >> 3; */ 2119 2120 pPriv->drw_x = drw_x; 2121 pPriv->drw_y = drw_y; 2122 pPriv->drw_w = drw_w; 2123 pPriv->drw_h = drw_h; 2124 pPriv->src_x = src_x; 2125 pPriv->src_y = src_y; 2126 pPriv->src_w = src_w; 2127 pPriv->src_h = src_h; 2128 pPriv->id = id; 2129 pPriv->height = height; 2130 2131 switch(id) 2132 { 2133 case PIXEL_FMT_YV12: 2134 case PIXEL_FMT_NV12: 2135 case PIXEL_FMT_NV21: 2136 pPriv->srcPitch = (width + 7) & ~7; 2137 totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */ 2138 break; 2139 case PIXEL_FMT_YUY2: 2140 case PIXEL_FMT_UYVY: 2141 case PIXEL_FMT_YVYU: 2142 case PIXEL_FMT_RGB6: 2143 case PIXEL_FMT_RGB5: 2144 default: 2145 pPriv->srcPitch = ((width << 1) + 3) & ~3; /* Verified */ 2146 totalSize = pPriv->srcPitch * height; 2147 } 2148 2149 totalSize += 15; 2150 totalSize &= ~15; 2151 /* allocate memory */ 2152 2153 if(totalSize == pPriv->fbSize) 2154 { 2155 ; 2156 } 2157 else 2158 { 2159 int lines, pitch, depth; 2160 BoxPtr pBox = NULL; 2161 2162 pPriv->fbSize = totalSize; 2163 2164 if(pPriv->fbAreaPtr) 2165 { 2166 xf86FreeOffscreenArea(pPriv->fbAreaPtr); 2167 } 2168 2169 depth = (pScrn->bitsPerPixel + 7 ) / 8; 2170 pitch = pScrn->displayWidth * depth; 2171 lines = ((totalSize * 2) / pitch) + 1; 2172 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImagelines=%x, pitch=%x, displayWidth=%x\n", lines, pitch, pScrn->displayWidth); 2173 2174 2175 pPriv->fbAreaPtr = xf86AllocateOffscreenArea(pScrn->pScreen, 2176 pScrn->displayWidth, 2177 lines, 0, NULL, NULL, NULL); 2178 2179 if(!pPriv->fbAreaPtr) 2180 { 2181 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Allocate video memory fails\n"); 2182 return BadAlloc; 2183 } 2184 2185 pBox = &(pPriv->fbAreaPtr->box); 2186 pPriv->bufAddr[0] = (pBox->y1 * pitch) + (pBox->x1 * depth); 2187 pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; 2188 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, pPriv->bufAddr[0]=0x%08X\n", pPriv->bufAddr[0]); 2189 2190 } 2191 2192 /* copy data */ 2193 if(totalSize < 16) 2194 { 2195 #ifdef NewPath 2196 memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); 2197 #else /* NewPath */ 2198 switch(id) 2199 { 2200 case PIXEL_FMT_YUY2: 2201 case PIXEL_FMT_UYVY: 2202 case PIXEL_FMT_YVYU: 2203 { 2204 BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); 2205 for(i=0; i<height; i++) 2206 memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2); 2207 break; 2208 } 2209 default: 2210 memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); 2211 break; 2212 } /* switch */ 2213 #endif /* NewPath */ 2214 } 2215 else 2216 { 2217 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, copy buf\n"); 2218 2219 #ifdef NewPath 2220 memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); 2221 #else /* NewPath */ 2222 switch(id) 2223 { 2224 case PIXEL_FMT_YUY2: 2225 case PIXEL_FMT_UYVY: 2226 case PIXEL_FMT_YVYU: 2227 { 2228 BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); 2229 for(i=0; i<height; i++) 2230 memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2); 2231 2232 /*for(i=0; i<height; i++) 2233 for(j=0; j<width*2; j++) 2234 *(Base+i*pPriv->srcPitch+j) = *(buf + width*i + j);*/ 2235 break; 2236 } 2237 default: 2238 { BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); 2239 int j; 2240 for(i=0; i<height; i++) 2241 for(j=0; j<width; j++) 2242 *(Base + width*i + j) = *(buf + width * i + j); 2243 break; 2244 } 2245 } /* end of switch */ 2246 #endif /* NewPath */ 2247 } 2248 2249 ASTDisplayVideo(pScrn, pPriv, clipBoxes, id); 2250 2251 /* update cliplist 2252 if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) 2253 { 2254 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 2255 } 2256 else 2257 { 2258 xf86XVFillKeyHelper(pScrn->pScreen, 0xFFFFFFFF, clipBoxes); 2259 } 2260 */ 2261 pPriv->currentBuf ^= 1; 2262 2263 return Success; 2264} 2265 2266static XF86VideoAdaptorPtr ASTSetupImageVideo(ScreenPtr pScreen) 2267{ 2268 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2269 ASTPtr pAST = ASTPTR(pScrn); 2270 XF86VideoAdaptorPtr adapt; 2271 ASTPortPrivPtr pPriv; 2272 2273 2274 if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 2275 sizeof(DevUnion) + 2276 sizeof(ASTPortPrivRec)))) 2277 return NULL; 2278 2279 adapt->type = XvWindowMask | XvInputMask | XvImageMask | XvVideoMask; 2280 adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 2281 adapt->name = "AST Video"; 2282 2283 adapt->nEncodings = 1; 2284 adapt->pEncodings = &DummyEncoding; 2285 2286 adapt->nFormats = NUM_FORMATS; 2287 adapt->pFormats = ASTFormats; 2288 adapt->nPorts = 1; 2289 adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 2290 2291 pPriv = (ASTPortPrivPtr)(&adapt->pPortPrivates[1]); 2292 2293 adapt->pPortPrivates->ptr = (pointer)(pPriv); 2294 adapt->pAttributes = ASTAttributes; 2295 adapt->nAttributes = NUM_ATTRIBUTES; 2296 adapt->nImages = NUM_IMAGES; 2297 adapt->pImages = ASTImages; 2298 2299 adapt->PutVideo = NULL; 2300 2301 adapt->PutStill = NULL; 2302 adapt->GetVideo = NULL; 2303 adapt->GetStill = NULL; 2304 adapt->StopVideo = ASTStopVideo; 2305 adapt->SetPortAttribute = ASTSetPortAttribute; 2306 adapt->GetPortAttribute = ASTGetPortAttribute; 2307 adapt->QueryBestSize = ASTQueryBestSize; 2308 adapt->PutImage = ASTPutImage; 2309 adapt->QueryImageAttributes = ASTQueryImageAttributes; 2310 2311 2312 pPriv->currentBuf = 0; 2313 pPriv->linear = NULL; 2314 pPriv->fbAreaPtr = NULL; 2315 pPriv->fbSize = 0; 2316 pPriv->videoStatus = 0; 2317 2318 pPriv->colorKey = 0x000101fe; 2319 pPriv->brightness = 0; 2320 pPriv->contrast = 128; 2321 pPriv->saturation = 0; 2322 pPriv->hue = 0; 2323 2324 /* gotta uninit this someplace */ 2325#if defined(REGION_NULL) 2326 REGION_NULL(pScreen, &pPriv->clip); 2327#else 2328 REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); 2329#endif 2330 2331 pAST->adaptor = adapt; 2332 2333 pAST->xvBrightness = MAKE_ATOM(astxvbrightness); 2334 pAST->xvContrast = MAKE_ATOM(astxvcontrast); 2335 pAST->xvColorKey = MAKE_ATOM(astxvcolorkey); 2336 pAST->xvSaturation = MAKE_ATOM(astxvsaturation); 2337 pAST->xvHue = MAKE_ATOM(astxvhue); 2338 pAST->xvGammaRed = MAKE_ATOM(astxvgammared); 2339 pAST->xvGammaGreen = MAKE_ATOM(astxvgammagreen); 2340 pAST->xvGammaBlue = MAKE_ATOM(astxvgammablue); 2341 2342 return adapt; 2343} 2344 2345void ASTInitVideo(ScreenPtr pScreen) 2346{ 2347 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2348 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 2349 XF86VideoAdaptorPtr ASTAdaptor = NULL; 2350 int num_adaptors; 2351 2352 ASTAdaptor = ASTSetupImageVideo(pScreen); 2353 2354 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 2355 2356 if(ASTAdaptor) 2357 { 2358 if(!num_adaptors) 2359 { 2360 num_adaptors = 1; 2361 adaptors = &ASTAdaptor; 2362 } 2363 else 2364 { 2365 newAdaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); 2366 if(newAdaptors) 2367 { 2368 memcpy(newAdaptors, adaptors, num_adaptors * 2369 sizeof(XF86VideoAdaptorPtr)); 2370 newAdaptors[num_adaptors] = ASTAdaptor; 2371 adaptors = newAdaptors; 2372 num_adaptors++; 2373 } 2374 } 2375 } 2376 2377 if(num_adaptors) 2378 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 2379 2380 if(newAdaptors) 2381 free(newAdaptors); 2382 2383} 2384#endif /* AstVideo */ 2385