ast_driver.c revision 621ff18c
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 /* Suport 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 /* Init VGA Adapter */ 627 if (!xf86IsPrimaryPci(pAST->PciInfo)) 628 { 629 ASTInitVGA(pScrn, 0); 630 } 631 632 vASTOpenKey(pScrn); 633 bASTRegInit(pScrn); 634 635 /* Get Chip Type */ 636 if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x30) 637 pAST->jChipType = AST2400; 638 else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x20) 639 pAST->jChipType = AST2300; 640 else if (PCI_DEV_REVISION(pAST->PciInfo) >= 0x10) 641 ASTGetChipType(pScrn); 642 else 643 pAST->jChipType = AST2000; 644 645 /* Get Options from Scratch */ 646 ASTGetScratchOptions(pScrn); 647 648 /* Get DRAM Info */ 649 ASTGetDRAMInfo(pScrn); 650 pAST->ulVRAMSize = ASTGetVRAMInfo(pScrn); 651 pScrn->videoRam = pAST->ulVRAMSize / 1024; 652 } 653 654 /* Map Framebuffer */ 655 from = X_DEFAULT; 656 if (pAST->pEnt->device->videoRam) { 657 pScrn->videoRam = pAST->pEnt->device->videoRam; 658 from = X_CONFIG; 659 } 660 661 pAST->FbMapSize = pScrn->videoRam * 1024; 662 663#if 0 664 if (!ASTMapMem(pScrn)) { 665 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); 666 return FALSE; 667 } 668#endif 669 670 pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr; 671 pScrn->fbOffset = 0; 672 673 /* Do DDC 674 * should be done after xf86CollectOptions 675 */ 676 pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index); 677 678 /* Mode Valid */ 679 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 680 clockRanges->next = NULL; 681 clockRanges->minClock = 9500; 682 clockRanges->maxClock = ASTGetMaxDCLK(pScrn) * 1000; 683 clockRanges->clockIndex = -1; 684 clockRanges->interlaceAllowed = FALSE; 685 clockRanges->doubleScanAllowed = FALSE; 686 687 /* Add for AST2100, ycchen@061807 */ 688 if ((pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST1180)) 689 { 690 maxPitch = 1920; 691 maxHeight = 1200; 692 } 693 else 694 { 695 maxPitch = 1600; 696 maxHeight = 1200; 697 } 698 699 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 700 pScrn->display->modes, clockRanges, 701 0, 320, maxPitch, 8 * pScrn->bitsPerPixel, 702 200, maxHeight, 703 pScrn->display->virtualX, pScrn->display->virtualY, 704 pAST->FbMapSize, LOOKUP_BEST_REFRESH); 705 706 /* fixed some monitors can't get propery validate modes using estimated ratio modes */ 707 if (i < 2) /* validate modes are too few */ 708 { 709 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 710 pScrn->display->modes, clockRanges, 711 0, 320, maxPitch, 8 * pScrn->bitsPerPixel, 712 200, maxHeight, 713 pAST->mon_h_active, pAST->mon_v_active, 714 pAST->FbMapSize, LOOKUP_BEST_REFRESH); 715 } 716 717 if (i == -1) { 718 ASTFreeRec(pScrn); 719 return FALSE; 720 } 721 722 xf86PruneDriverModes(pScrn); 723 724 if (!i || !pScrn->modes) { 725 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 726 ASTFreeRec(pScrn); 727 return FALSE; 728 } 729 730 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 731 732 pScrn->currentMode = pScrn->modes; 733 734 xf86PrintModes(pScrn); 735 736 xf86SetDpi(pScrn, 0, 0); 737 738 /* Accelaration Check */ 739 pAST->noAccel = TRUE; 740 pAST->pCMDQPtr = NULL; 741 pAST->CMDQInfo.ulCMDQSize = 0; 742 pAST->CMDQInfo.pjCmdQBasePort = pAST->MMIOVirtualAddr+ 0x8044; 743 pAST->CMDQInfo.pjWritePort = pAST->MMIOVirtualAddr+ 0x8048; 744 pAST->CMDQInfo.pjReadPort = pAST->MMIOVirtualAddr+ 0x804C; 745 pAST->CMDQInfo.pjEngStatePort = pAST->MMIOVirtualAddr+ 0x804C; 746#ifdef HAVE_XAA_H 747 pAST->AccelInfoPtr = NULL; 748#ifdef Accel_2D 749 if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE)) 750 { 751 if (xf86LoadSubModule(pScrn, "xaa")) { 752 753 pAST->noAccel = FALSE; 754 pAST->MMIO2D = TRUE; 755#ifndef MMIO_2D 756 if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) { 757 pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE; 758 pAST->MMIO2D = FALSE; 759 } 760#endif 761 762 pAST->ENGCaps = ENG_CAP_ALL; 763 if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) { 764 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n"); 765 } 766 767 pAST->DBGSelect = 0; 768 if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) { 769 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n"); 770 } 771 } 772 } 773#endif 774#endif /* HAVE_XAA_H */ 775 776 /* HW Cursor Check */ 777 pAST->noHWC = TRUE; 778 pAST->HWCInfoPtr = NULL; 779 pAST->pHWCPtr = NULL; 780#ifdef HWC 781 if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) { 782 if (!xf86LoadSubModule(pScrn, "ramdac")) { 783 ASTFreeRec(pScrn); 784 return FALSE; 785 } 786 787 pAST->noHWC = FALSE; 788 pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; 789 if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) { 790 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n"); 791 } 792 793 } 794#endif 795 796 /* ShadowFB */ 797#ifdef Support_ShadowFB 798 pAST->shadowFB = FALSE; 799 if (pAST->noAccel == TRUE) /* enable shadowFB only noAccel */ 800 { 801 if (xf86ReturnOptValBool(pAST->Options, OPTION_SHADOW_FB, TRUE)) 802 { 803 if (xf86LoadSubModule(pScrn, "shadow")) { 804 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using \"Shadow Framebuffer\"\n"); 805 pAST->shadowFB = TRUE; 806 } 807 } 808 } 809#endif 810 811#ifndef XSERVER_LIBPCIACCESS 812 /* We won't be using the VGA access after the probe */ 813 xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr); 814 xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr); 815#endif 816 817 return TRUE; 818} 819 820 821static Bool 822ASTScreenInit(SCREEN_INIT_ARGS_DECL) 823{ 824 ScrnInfoPtr pScrn; 825 ASTRecPtr pAST; 826 VisualPtr visual; 827 /* for FB Manager */ 828 BoxRec FBMemBox; 829 int AvailFBSize; 830 831 pScrn = xf86ScreenToScrn(pScreen); 832 pAST = ASTPTR(pScrn); 833 834 if (!ASTMapMem(pScrn)) { 835 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); 836 return FALSE; 837 } 838 839/* if (!pAST->noAccel) */ 840 { 841 /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */ 842 AvailFBSize = pAST->FbMapSize; 843 844 FBMemBox.x1 = 0; 845 FBMemBox.y1 = 0; 846 FBMemBox.x2 = pScrn->displayWidth; 847 FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1; 848 849 if (FBMemBox.y2 < 0) 850 FBMemBox.y2 = 32767; 851 if (FBMemBox.y2 < pScrn->virtualY) 852 return FALSE; 853 854 if (!xf86InitFBManager(pScreen, &FBMemBox)) { 855 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); 856 return FALSE; 857 } 858 859 } 860 861#if !(defined(__sparc__)) && !(defined(__mips__)) 862 vgaHWPtr hwp; 863 hwp = VGAHWPTR(pScrn); 864 vgaHWSetMmioFuncs(hwp, pAST->MMIOVirtualAddr, 0); 865#endif 866 867 vFillASTModeInfo (pScrn); 868 869 ASTSave(pScrn); 870 if (!ASTModeInit(pScrn, pScrn->currentMode)) { 871 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n"); 872 return FALSE; 873 } 874 875 ASTSaveScreen(pScreen, FALSE); 876 ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 877 878 miClearVisualTypes(); 879 880 /* Re-implemented Direct Color support, -jens */ 881 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 882 pScrn->rgbBits, pScrn->defaultVisual)) 883 return FALSE; 884 885 if (!miSetPixmapDepths()) 886 { 887 ASTSaveScreen(pScreen, SCREEN_SAVER_OFF); 888 return FALSE; 889 } 890 891 /* allocate shadowFB */ 892#ifdef Support_ShadowFB 893 pAST->shadowFB_validation = FALSE; 894 if (pAST->shadowFB) { 895 pAST->shadow = calloc(1, pScrn->displayWidth * pScrn->virtualY * 896 ((pScrn->bitsPerPixel + 7) / 8)); 897 if (!pAST->shadow) { 898 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow buffer\n"); 899 } 900 else 901 pAST->shadowFB_validation = TRUE; 902 } 903#endif 904 905 switch(pScrn->bitsPerPixel) { 906 case 8: 907 case 16: 908 case 32: 909#ifdef Support_ShadowFB 910 if (!fbScreenInit(pScreen, pAST->shadowFB_validation ? pAST->shadow : (pAST->FBVirtualAddr + pScrn->fbOffset), 911 pScrn->virtualX, pScrn->virtualY, 912 pScrn->xDpi, pScrn->yDpi, 913 pScrn->displayWidth, pScrn->bitsPerPixel)) 914#else 915 if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset, 916 pScrn->virtualX, pScrn->virtualY, 917 pScrn->xDpi, pScrn->yDpi, 918 pScrn->displayWidth, pScrn->bitsPerPixel)) 919#endif 920 return FALSE; 921 break; 922 default: 923 return FALSE; 924 925 } 926 927 if (pScrn->bitsPerPixel > 8) { 928 /* Fixup RGB ordering */ 929 visual = pScreen->visuals + pScreen->numVisuals; 930 while (--visual >= pScreen->visuals) { 931 if ((visual->class | DynamicClass) == DirectColor) { 932 visual->offsetRed = pScrn->offset.red; 933 visual->offsetGreen = pScrn->offset.green; 934 visual->offsetBlue = pScrn->offset.blue; 935 visual->redMask = pScrn->mask.red; 936 visual->greenMask = pScrn->mask.green; 937 visual->blueMask = pScrn->mask.blue; 938 } 939 } 940 } 941 942 /* Must be after RGB order fixed */ 943 fbPictureInit(pScreen, 0, 0); 944 945 /* shadowFB setup */ 946#ifdef Support_ShadowFB 947 if (pAST->shadowFB_validation) { 948 pAST->update = ASTUpdatePacked; 949 pAST->window = ASTWindowLinear; 950 951 if (!shadowSetup(pScreen)) 952 { 953 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to setup shadow buffer\n"); 954 return FALSE; 955 } 956 957 pAST->CreateScreenResources = pScreen->CreateScreenResources; 958 pScreen->CreateScreenResources = ASTCreateScreenResources; 959 } 960#endif 961 962 xf86SetBlackWhitePixels(pScreen); 963 964#ifdef HAVE_XAA_H 965#ifdef Accel_2D 966 if (!pAST->noAccel) 967 { 968 if (!ASTAccelInit(pScreen)) { 969 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n"); 970 pAST->noAccel = TRUE; 971 } 972 } 973#endif /* end of Accel_2D */ 974#endif 975 976 xf86SetBackingStore(pScreen); 977 xf86SetSilkenMouse(pScreen); 978 979 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 980 981 if (!pAST->noHWC) 982 { 983 if (!ASTCursorInit(pScreen)) { 984 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n"); 985 pAST->noHWC = TRUE; 986 } 987 } 988 989 if (!miCreateDefColormap(pScreen)) 990 return FALSE; 991 992 if (pAST->jChipType != AST1180) 993 { 994 if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, 995 vASTLoadPalette, NULL, 996 CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { 997 return FALSE; 998 } 999 } 1000 1001 xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0); 1002 1003#ifdef AstVideo 1004 if ( (pAST->jChipType == AST1180) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) ) 1005 { 1006 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"AST Initial Video()\n"); 1007 ASTInitVideo(pScreen); 1008 } 1009#endif 1010 1011 pScreen->SaveScreen = ASTSaveScreen; 1012 pAST->CloseScreen = pScreen->CloseScreen; 1013 pScreen->CloseScreen = ASTCloseScreen; 1014 1015 if (serverGeneration == 1) 1016 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1017 1018 return TRUE; 1019 1020} /* ASTScreenInit */ 1021 1022 1023Bool 1024ASTSwitchMode(SWITCH_MODE_ARGS_DECL) 1025{ 1026 SCRN_INFO_PTR(arg); 1027 ASTRecPtr pAST = ASTPTR(pScrn); 1028 1029 /* VideoMode validate */ 1030 if (mode->CrtcHDisplay > pScrn->displayWidth) 1031 return FALSE; 1032 if ((pAST->VideoModeInfo.ScreenPitch * mode->CrtcVDisplay) > pAST->ulVRAMSize) 1033 return FALSE; 1034 1035 /* VideModeInfo Update */ 1036 pAST->VideoModeInfo.ScreenWidth = mode->CrtcHDisplay; 1037 pAST->VideoModeInfo.ScreenHeight = mode->CrtcVDisplay; 1038 pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ; 1039 1040#ifdef HWC 1041 if (pAST->pHWCPtr) { 1042 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 1043 pAST->pHWCPtr = NULL; 1044 } 1045 ASTDisableHWC(pScrn); 1046#endif 1047 1048#ifdef Accel_2D 1049 if (pAST->pCMDQPtr) { 1050 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 1051 pAST->pCMDQPtr = NULL; 1052 } 1053 vASTDisable2D(pScrn, pAST); 1054#endif 1055 1056 /* Fixed display abnormal on the of the screen if run xvidtune, ycchen@122909 */ 1057 /* ASTRestore(pScrn); */ 1058 1059 return ASTModeInit(pScrn, mode); 1060 1061} 1062 1063void 1064ASTAdjustFrame(ADJUST_FRAME_ARGS_DECL) 1065{ 1066 SCRN_INFO_PTR(arg); 1067 ASTRecPtr pAST = ASTPTR(pScrn); 1068 ULONG base; 1069 1070 base = y * pAST->VideoModeInfo.ScreenPitch + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8); 1071 /* base = base >> 2; */ /* DW unit */ 1072 1073 vASTSetStartAddressCRT1(pAST, base); 1074 1075} 1076 1077/* enter into X Server */ 1078static Bool 1079ASTEnterVT(VT_FUNC_ARGS_DECL) 1080{ 1081 SCRN_INFO_PTR(arg); 1082 ASTRecPtr pAST = ASTPTR(pScrn); 1083 1084 /* Fixed suspend can't resume issue */ 1085 if (!bASTIsVGAEnabled(pScrn)) 1086 { 1087 if (pAST->jChipType == AST1180) 1088 bASTInitAST1180(pScrn); 1089 else 1090 { 1091 vASTEnableVGAMMIO(pScrn); 1092 ASTInitVGA(pScrn, 1); 1093 } 1094 ASTRestore(pScrn); 1095 } 1096 1097 if (!ASTModeInit(pScrn, pScrn->currentMode)) 1098 return FALSE; 1099 ASTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 1100 1101 return TRUE; 1102 1103} 1104 1105/* leave X server */ 1106static void 1107ASTLeaveVT(VT_FUNC_ARGS_DECL) 1108{ 1109 1110 SCRN_INFO_PTR(arg); 1111 ASTRecPtr pAST = ASTPTR(pScrn); 1112#if !(defined(__sparc__)) && !(defined(__mips__)) 1113 vgaHWPtr hwp = VGAHWPTR(pScrn); 1114#endif 1115 1116#ifdef HWC 1117 if (pAST->pHWCPtr) { 1118 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 1119 pAST->pHWCPtr = NULL; 1120 } 1121 ASTDisableHWC(pScrn); 1122#endif 1123 1124#ifdef Accel_2D 1125 if (pAST->pCMDQPtr) { 1126 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 1127 pAST->pCMDQPtr = NULL; 1128 } 1129 vASTDisable2D(pScrn, pAST); 1130#endif 1131 1132 ASTRestore(pScrn); 1133 1134 if (pAST->jChipType == AST1180) 1135 ASTBlankScreen(pScrn, 0); 1136 1137#if !(defined(__sparc__)) && !(defined(__mips__)) 1138 vgaHWLock(hwp); 1139#endif 1140 1141} 1142 1143static void 1144ASTFreeScreen(FREE_SCREEN_ARGS_DECL) 1145{ 1146 SCRN_INFO_PTR(arg); 1147 ASTFreeRec(pScrn); 1148#if !(defined(__sparc__)) && !(defined(__mips__)) 1149 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 1150 vgaHWFreeHWRec(pScrn); 1151#endif 1152} 1153 1154static ModeStatus 1155ASTValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 1156{ 1157 SCRN_INFO_PTR(arg); 1158 ASTRecPtr pAST = ASTPTR(pScrn); 1159 ModeStatus Flags = MODE_NOMODE; 1160 UCHAR jReg; 1161 ULONG RequestBufferSize; 1162 1163 if (mode->Flags & V_INTERLACE) { 1164 if (verbose) { 1165 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1166 "Removing interlaced mode \"%s\"\n", mode->name); 1167 } 1168 return MODE_NO_INTERLACE; 1169 } 1170 1171 if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) { 1172 if (verbose) { 1173 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1174 "Removing the mode \"%s\"\n", mode->name); 1175 } 1176 return Flags; 1177 } 1178 1179 /* Valid Framebuffer size */ 1180 RequestBufferSize = mode->CrtcHDisplay * ((pScrn->bitsPerPixel + 1) / 8) * mode->CrtcVDisplay; 1181 if (RequestBufferSize > pAST->ulVRAMSize) 1182 return Flags; 1183 1184 /* Valid Wide Screen Mode */ 1185 if (pAST->SupportWideScreen) 1186 { 1187 if ( (mode->CrtcHDisplay == 1680) && (mode->CrtcVDisplay == 1050) ) 1188 return MODE_OK; 1189 if ( (mode->CrtcHDisplay == 1280) && (mode->CrtcVDisplay == 800) ) 1190 return MODE_OK; 1191 if ( (mode->CrtcHDisplay == 1440) && (mode->CrtcVDisplay == 900) ) 1192 return MODE_OK; 1193 if ( (mode->CrtcHDisplay == 1360) && (mode->CrtcVDisplay == 768) ) 1194 return MODE_OK; 1195 if ( (mode->CrtcHDisplay == 1600) && (mode->CrtcVDisplay == 900) ) 1196 return MODE_OK; 1197 1198 if ( (pAST->jChipType == AST2100) || (pAST->jChipType == AST2200) || (pAST->jChipType == AST2300) || (pAST->jChipType == AST2400) || (pAST->jChipType == AST1180) ) 1199 { 1200 if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1080) ) 1201 return MODE_OK; 1202 1203 if ( (mode->CrtcHDisplay == 1920) && (mode->CrtcVDisplay == 1200) ) 1204 { 1205 GetIndexRegMask(CRTC_PORT, 0xD1, 0xFF, jReg); 1206 if (jReg & 0x01) 1207 return MODE_NOMODE; 1208 else 1209 return MODE_OK; 1210 } 1211 } 1212 } 1213 1214 switch (mode->CrtcHDisplay) 1215 { 1216 case 640: 1217 if (mode->CrtcVDisplay == 480) Flags=MODE_OK; 1218 break; 1219 case 800: 1220 if (mode->CrtcVDisplay == 600) Flags=MODE_OK; 1221 break; 1222 case 1024: 1223 if (mode->CrtcVDisplay == 768) Flags=MODE_OK; 1224 break; 1225 case 1280: 1226 if (mode->CrtcVDisplay == 1024) Flags=MODE_OK; 1227 break; 1228 case 1600: 1229 if (mode->CrtcVDisplay == 1200) Flags=MODE_OK; 1230 break; 1231 default: 1232 return Flags; 1233 } 1234 1235 return Flags; 1236} 1237 1238/* Internal used modules */ 1239/* 1240 * ASTGetRec and ASTFreeRec -- 1241 * 1242 * Private data for the driver is stored in the screen structure. 1243 * These two functions create and destroy that private data. 1244 * 1245 */ 1246static Bool 1247ASTGetRec(ScrnInfoPtr pScrn) 1248{ 1249 if (pScrn->driverPrivate) 1250 return TRUE; 1251 1252 pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1); 1253 return TRUE; 1254} 1255 1256static void 1257ASTFreeRec(ScrnInfoPtr pScrn) 1258{ 1259 ASTRecPtr pAST = ASTPTR(pScrn); 1260 1261 if (!pScrn) 1262 return; 1263 if (!pScrn->driverPrivate) 1264 return; 1265 if (pAST->pDP501FWBufferVirtualAddress) 1266 free(pAST->pDP501FWBufferVirtualAddress); 1267 free(pScrn->driverPrivate); 1268 pScrn->driverPrivate = 0; 1269} 1270 1271static Bool 1272ASTSaveScreen(ScreenPtr pScreen, Bool unblack) 1273{ 1274#if !(defined(__sparc__)) && !(defined(__mips__)) 1275 /* replacement of vgaHWBlankScreen(pScrn, unblank) without seq reset */ 1276 /* return vgaHWSaveScreen(pScreen, unblack); */ 1277 ScrnInfoPtr pScrn = NULL; 1278 1279 if (pScreen != NULL) 1280 pScrn = xf86ScreenToScrn(pScreen); 1281 1282 if ((pScrn != NULL) && pScrn->vtSema) { 1283 ASTBlankScreen(pScrn, unblack); 1284 } 1285 return (TRUE); 1286#endif 1287} 1288 1289static Bool 1290ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL) 1291{ 1292 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1293 ASTRecPtr pAST = ASTPTR(pScrn); 1294#if !(defined(__sparc__)) && !(defined(__mips__)) 1295 vgaHWPtr hwp = VGAHWPTR(pScrn); 1296#endif 1297 1298 if (pScrn->vtSema == TRUE) 1299 { 1300#ifdef HWC 1301 if (pAST->pHWCPtr) { 1302 xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ 1303 pAST->pHWCPtr = NULL; 1304 } 1305 ASTDisableHWC(pScrn); 1306#endif 1307 1308#ifdef Accel_2D 1309 if (pAST->pCMDQPtr) { 1310 xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ 1311 pAST->pCMDQPtr = NULL; 1312 } 1313 vASTDisable2D(pScrn, pAST); 1314#endif 1315 1316 ASTRestore(pScrn); 1317 1318 if (pAST->jChipType == AST1180) 1319 ASTBlankScreen(pScrn, 0); 1320 1321#if !(defined(__sparc__)) && !(defined(__mips__)) 1322 vgaHWLock(hwp); 1323#endif 1324 } 1325 1326 ASTUnmapMem(pScrn); 1327#if !(defined(__sparc__)) && !(defined(__mips__)) 1328 vgaHWUnmapMem(pScrn); 1329#endif 1330 1331#ifdef HAVE_XAA_H 1332 if(pAST->AccelInfoPtr) { 1333 XAADestroyInfoRec(pAST->AccelInfoPtr); 1334 pAST->AccelInfoPtr = NULL; 1335 } 1336#endif 1337 if(pAST->HWCInfoPtr) { 1338 xf86DestroyCursorInfoRec(pAST->HWCInfoPtr); 1339 pAST->HWCInfoPtr = NULL; 1340 } 1341 1342#ifdef Support_ShadowFB 1343 if (pAST->shadowFB_validation) { 1344 shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); 1345 free(pAST->shadow); 1346 pScreen->CreateScreenResources = pAST->CreateScreenResources; 1347 } 1348#endif 1349 1350 pScrn->vtSema = FALSE; 1351 pScreen->CloseScreen = pAST->CloseScreen; 1352 return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS); 1353} 1354 1355static void 1356ASTSave(ScrnInfoPtr pScrn) 1357{ 1358 ASTRecPtr pAST; 1359 ASTRegPtr astReg; 1360 int i, icount=0; 1361 ULONG ulData; 1362 1363 pAST = ASTPTR(pScrn); 1364 astReg = &pAST->SavedReg; 1365 1366 if (pAST->jChipType == AST1180) 1367 { 1368 for (i=0; i<12; i++) 1369 { 1370 ReadAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData); 1371 astReg->GFX[i] = ulData; 1372 } 1373 } 1374 else 1375 { 1376#if defined(__sparc__) || defined(__mips__) 1377 UCHAR jReg; 1378 1379 /* Save Misc */ 1380 astReg->MISC = GetReg(MISC_PORT_READ); 1381 1382 /* Save SR */ 1383 for (i=0; i<4; i++) 1384 GetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]); 1385 1386 /* Save CR */ 1387 for (i=0; i<25; i++) 1388 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]); 1389 1390 /* Save GR */ 1391 for (i=0; i<9; i++) 1392 GetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]); 1393 1394 /* Save AR */ 1395 jReg = GetReg(INPUT_STATUS1_READ); 1396 for (i=0; i<20; i++) 1397 GetIndexReg(AR_PORT_WRITE, (UCHAR) (i), astReg->AR[i]); 1398 jReg = GetReg(INPUT_STATUS1_READ); 1399 SetReg (AR_PORT_WRITE, 0x20); /* set POS */ 1400#else 1401 vgaRegPtr vgaReg; 1402 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 1403 1404 /* do save */ 1405 if (xf86IsPrimaryPci(pAST->PciInfo)) { 1406 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS); 1407 } 1408 else { 1409 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE); 1410 } 1411#endif 1412 1413 /* Save Ext. */ 1414 vASTOpenKey(pScrn); 1415 1416 /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ 1417 for (i=0x81; i<=0xB6; i++) 1418 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1419 for (i=0xBC; i<=0xC1; i++) 1420 GetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1421 GetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); 1422 1423 /* Save DAC */ 1424 for (i=0; i<256; i++) 1425 VGA_GET_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]); 1426 1427 /* Save 2D */ 1428 astReg->ENG8044 = 0; 1429 GetIndexReg(CRTC_PORT, 0xA4, astReg->REGA4); 1430 if (astReg->REGA4 & 0x01) /* 2D enabled */ 1431 astReg->ENG8044 = *(ULONG *) (pAST->MMIOVirtualAddr + 0x8044); 1432 } 1433 1434} 1435 1436static void 1437ASTRestore(ScrnInfoPtr pScrn) 1438{ 1439 ASTRecPtr pAST; 1440 ASTRegPtr astReg; 1441 int i, icount=0; 1442 ULONG ulData; 1443 1444 pAST = ASTPTR(pScrn); 1445 astReg = &pAST->SavedReg; 1446 1447 ASTDisplayPowerManagementSet(pScrn, DPMSModeOff, 0); 1448 1449 if (pAST->jChipType == AST1180) 1450 { 1451 for (i=0; i<12; i++) 1452 { 1453 ulData = astReg->GFX[i]; 1454 WriteAST1180SOC(AST1180_GFX_BASE + AST1180_VGA1_CTRL+i*4, ulData); 1455 } 1456 } 1457 else 1458 { 1459#if defined(__sparc__) || defined(__mips__) 1460 UCHAR jReg; 1461 1462 /* Restore Misc */ 1463 SetReg(MISC_PORT_WRITE, astReg->MISC); 1464 1465 /* Restore SR */ 1466 for (i=0; i<4; i++) 1467 SetIndexReg(SEQ_PORT, (UCHAR) (i), astReg->SEQ[i]); 1468 1469 /* Restore CR */ 1470 SetIndexRegMask(CRTC_PORT,0x11, 0x7F, 0x00); 1471 for (i=0; i<25; i++) 1472 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->CRTC[i]); 1473 1474 /* Restore GR */ 1475 for (i=0; i<9; i++) 1476 SetIndexReg(GR_PORT, (UCHAR) (i), astReg->GR[i]); 1477 1478 /* Restore AR */ 1479 jReg = GetReg(INPUT_STATUS1_READ); 1480 for (i=0; i<20; i++) 1481 { 1482 SetReg(AR_PORT_WRITE, (UCHAR) i); 1483 SetReg(AR_PORT_WRITE, astReg->AR[i]); 1484 } 1485 SetReg(AR_PORT_WRITE, 0x14); 1486 SetReg(AR_PORT_WRITE, 0x00); 1487 1488 jReg = GetReg(INPUT_STATUS1_READ); 1489 SetReg (AR_PORT_WRITE, 0x20); /* set POS */ 1490#else 1491 vgaRegPtr vgaReg; 1492 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 1493 1494 /* do restore */ 1495 vgaHWProtect(pScrn, TRUE); 1496 if (xf86IsPrimaryPci(pAST->PciInfo)) 1497 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS); 1498 else 1499 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 1500 vgaHWProtect(pScrn, FALSE); 1501#endif 1502 1503 /* Ext. restore */ 1504 vASTOpenKey(pScrn); 1505 1506 /* Restore DAC */ 1507 for (i=0; i<256; i++) 1508 VGA_LOAD_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]); 1509 1510 /* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */ 1511 for (i=0x81; i<=0xB6; i++) 1512 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1513 for (i=0xBC; i<=0xC1; i++) 1514 SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]); 1515 SetIndexReg(CRTC_PORT, (UCHAR) (0xBB), astReg->ExtCRTC[icount]); 1516 } 1517 1518} 1519 1520static void 1521ASTProbeDDC(ScrnInfoPtr pScrn, int index) 1522{ 1523 ASTRecPtr pAST = ASTPTR(pScrn); 1524 unsigned char DDC_data[128]; 1525 Bool Flags; 1526 1527 if (xf86LoadSubModule(pScrn, "ddc")) 1528 { 1529 if (pAST->jChipType == AST1180) 1530 Flags = ASTGetVGA2EDID(pScrn, DDC_data); 1531 else if (pAST->jTxChipType == Tx_DP501) 1532 { 1533 Flags = ASTReadEDID_M68K(pScrn, DDC_data); 1534 if (Flags == FALSE) 1535 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1536 } 1537 else 1538 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1539 1540 if (Flags) 1541 { 1542 ConfiguredMonitor = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); 1543 } 1544 else 1545 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Get EDID Properly \n"); 1546 } 1547 else 1548 { 1549 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTProbeDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n"); 1550 } 1551 1552} 1553 1554#define SkipDT 0x00 1555#define DT1 0x01 1556#define DT2 0x02 1557 1558static xf86MonPtr 1559ASTDoDDC(ScrnInfoPtr pScrn, int index) 1560{ 1561 xf86MonPtr MonInfo = NULL; 1562 ASTRecPtr pAST = ASTPTR(pScrn); 1563 unsigned char DDC_data[128]; 1564 Bool Flags; 1565 1566 xf86MonPtr MonInfo1 = NULL, MonInfo2 = NULL; 1567 unsigned long i, j, k; 1568 struct monitor_ranges ranges, ranges1, ranges2; 1569 int DTSelect, dclock1=0, h_active1=0, v_active1=0, dclock2=0, h_active2=0, v_active2=0; 1570 struct std_timings stdtiming, *stdtiming1, *stdtiming2; 1571 1572 /* Honour Option "noDDC" */ 1573 if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) { 1574 return MonInfo; 1575 } 1576 1577 if (xf86LoadSubModule(pScrn, "ddc")) 1578 { 1579 if (pAST->jChipType == AST1180) 1580 Flags = ASTGetVGA2EDID(pScrn, DDC_data); 1581 else if (pAST->jTxChipType == Tx_DP501) 1582 { 1583 pAST->DP501_MaxVCLK = 0xFF; 1584 Flags = ASTReadEDID_M68K(pScrn, DDC_data); 1585 if (Flags) pAST->DP501_MaxVCLK = ASTGetLinkMaxCLK(pScrn); 1586 else 1587 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1588 } 1589 else 1590 Flags = ASTGetVGAEDID(pScrn, DDC_data); 1591 1592 if (Flags) 1593 { 1594 MonInfo = MonInfo1 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); 1595 1596 /* Valid Wide Screen Support */ 1597 if ( (MonInfo) && (MonInfo->det_mon[0].type == 0x00) ) 1598 { 1599 if ( (MonInfo->det_mon[0].section.d_timings.h_active * 10 / MonInfo->det_mon[0].section.d_timings.v_active) < 14 ) 1600 pAST->SupportWideScreen = FALSE; 1601 } 1602 } 1603 1604 /* For VGA2 CLONE Support, ycchen@012508 */ 1605 if ((xf86ReturnOptValBool(pAST->Options, OPTION_VGA2_CLONE, FALSE)) || pAST->VGA2Clone) { 1606 if (ASTGetVGA2EDID(pScrn, DDC_data) == TRUE) { 1607 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Get VGA2 EDID Correctly!! \n"); 1608 MonInfo2 = xf86InterpretEDID(pScrn->scrnIndex, DDC_data); 1609 if (MonInfo1 == NULL) /* No DDC1 EDID */ 1610 MonInfo = MonInfo2; 1611 else { /* Check with VGA1 & VGA2 EDID */ 1612 /* Update establishment timing */ 1613 MonInfo->timings1.t1 = MonInfo1->timings1.t1 & MonInfo2->timings1.t1; 1614 MonInfo->timings1.t2 = MonInfo1->timings1.t2 & MonInfo2->timings1.t2; 1615 MonInfo->timings1.t_manu = MonInfo1->timings1.t_manu & MonInfo2->timings1.t_manu; 1616 1617 /* Update Std. Timing */ 1618 for (i=0; i<8; i++) { 1619 stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; 1620 for (j=0; j<8; j++) { 1621 if ((MonInfo1->timings2[i].hsize == MonInfo2->timings2[j].hsize) && \ 1622 (MonInfo1->timings2[i].vsize == MonInfo2->timings2[j].vsize) && \ 1623 (MonInfo1->timings2[i].refresh == MonInfo2->timings2[j].refresh)) { 1624 stdtiming = MonInfo1->timings2[i]; 1625 break; 1626 } 1627 } 1628 1629 MonInfo->timings2[i] = stdtiming; 1630 } /* Std. Timing */ 1631 1632 /* Get Detailed Timing */ 1633 for (i=0;i<4;i++) { 1634 if (MonInfo1->det_mon[i].type == 0xFD) 1635 ranges1 = MonInfo1->det_mon[i].section.ranges; 1636 else if (MonInfo1->det_mon[i].type == 0xFA) 1637 stdtiming1 = MonInfo1->det_mon[i].section.std_t; 1638 else if (MonInfo1->det_mon[i].type == 0x00) { 1639 if (MonInfo1->det_mon[i].section.d_timings.clock > dclock1) 1640 dclock1 = MonInfo1->det_mon[i].section.d_timings.clock; 1641 if (MonInfo1->det_mon[i].section.d_timings.h_active > h_active1) 1642 h_active1 = MonInfo1->det_mon[i].section.d_timings.h_active; 1643 if (MonInfo1->det_mon[i].section.d_timings.v_active > v_active1) 1644 v_active1 = MonInfo1->det_mon[i].section.d_timings.v_active; 1645 } 1646 if (MonInfo2->det_mon[i].type == 0xFD) 1647 ranges2 = MonInfo2->det_mon[i].section.ranges; 1648 else if (MonInfo1->det_mon[i].type == 0xFA) 1649 stdtiming2 = MonInfo2->det_mon[i].section.std_t; 1650 else if (MonInfo2->det_mon[i].type == 0x00) { 1651 if (MonInfo2->det_mon[i].section.d_timings.clock > dclock2) 1652 dclock2 = MonInfo2->det_mon[i].section.d_timings.clock; 1653 if (MonInfo2->det_mon[i].section.d_timings.h_active > h_active2) 1654 h_active2 = MonInfo2->det_mon[i].section.d_timings.h_active; 1655 if (MonInfo2->det_mon[i].section.d_timings.v_active > v_active2) 1656 v_active2 = MonInfo2->det_mon[i].section.d_timings.v_active; 1657 } 1658 } /* Get Detailed Timing */ 1659 1660 /* Chk Detailed Timing */ 1661 if ((dclock1 >= dclock2) && (h_active1 >= h_active2) && (v_active1 >= v_active2)) 1662 DTSelect = DT2; 1663 else if ((dclock2 >= dclock1) && (h_active2 >= h_active1) && (v_active2 >= v_active1)) 1664 DTSelect = DT1; 1665 else 1666 DTSelect = SkipDT; 1667 1668 /* Chk Monitor Descriptor */ 1669 ranges = ranges1; 1670 ranges.min_h = ranges1.min_h > ranges2.min_h ? ranges1.min_h:ranges2.min_h; 1671 ranges.min_v = ranges1.min_v > ranges2.min_v ? ranges1.min_v:ranges2.min_v; 1672 ranges.max_h = ranges1.max_h < ranges2.max_h ? ranges1.max_h:ranges2.max_h; 1673 ranges.max_v = ranges1.max_v < ranges2.max_v ? ranges1.max_v:ranges2.max_v; 1674 ranges.max_clock = ranges1.max_clock < ranges2.max_clock ? ranges1.max_clock:ranges2.max_clock; 1675 1676 /* Update Detailed Timing */ 1677 for (i=0; i<4; i++) 1678 { 1679 if (MonInfo->det_mon[i].type == 0xFD) { 1680 MonInfo->det_mon[i].section.ranges = ranges; 1681 } 1682 else if (MonInfo->det_mon[i].type == 0xFA) { 1683 for (j=0; j<5; j++) { 1684 stdtiming.hsize = stdtiming.vsize = stdtiming.refresh = stdtiming.id = 0; 1685 for (k=0; k<5; k++) { 1686 if ((stdtiming1[j].hsize == stdtiming2[k].hsize) && \ 1687 (stdtiming1[j].vsize == stdtiming2[k].vsize) && \ 1688 (stdtiming1[j].refresh == stdtiming2[k].refresh)) { 1689 stdtiming = stdtiming1[j]; 1690 break; 1691 } 1692 } 1693 stdtiming1[j] = stdtiming; 1694 } /* Std. Timing */ 1695 } /* FA */ 1696 else if (MonInfo->det_mon[i].type == 0x00) { 1697 if (DTSelect == DT2) 1698 MonInfo->det_mon[i] = MonInfo2->det_mon[i]; 1699 else if (DTSelect == DT1) 1700 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1701 else /* SkipDT */ 1702 { /* use 1024x768 as default */ 1703 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1704 MonInfo->det_mon[i].section.d_timings.clock = 65000000; 1705 MonInfo->det_mon[i].section.d_timings.h_active = 1024; 1706 MonInfo->det_mon[i].section.d_timings.h_blanking = 320; 1707 MonInfo->det_mon[i].section.d_timings.v_active = 768; 1708 MonInfo->det_mon[i].section.d_timings.v_blanking = 38; 1709 MonInfo->det_mon[i].section.d_timings.h_sync_off = 24; 1710 MonInfo->det_mon[i].section.d_timings.h_sync_width = 136; 1711 MonInfo->det_mon[i].section.d_timings.v_sync_off = 3; 1712 MonInfo->det_mon[i].section.d_timings.v_sync_width = 6; 1713 } 1714 } /* 00 */ 1715 else { /* use Monitor 1 as default */ 1716 MonInfo->det_mon[i] = MonInfo1->det_mon[i]; 1717 } 1718 1719 } /* Update Detailed Timing */ 1720 1721 /* set feature size */ 1722 if (DTSelect == DT2) { 1723 MonInfo->features.hsize = MonInfo2->features.hsize; 1724 MonInfo->features.vsize = MonInfo2->features.vsize; 1725 } 1726 else if (DTSelect == DT1) { 1727 MonInfo->features.hsize = MonInfo1->features.hsize; 1728 MonInfo->features.vsize = MonInfo1->features.vsize; 1729 } 1730 else /* Skip DT */ 1731 { /* use 1024x768 as default */ 1732 MonInfo->features.hsize = 0x20; 1733 MonInfo->features.vsize = 0x18; 1734 } 1735 1736 } /* Check with VGA1 & VGA2 EDID */ 1737 1738 } /* ASTGetVGA2EDID */ 1739 else { 1740 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Can't Get VGA2 EDID Correctly!! \n"); 1741 } 1742 } /* VGA2Clone */ 1743 1744 xf86PrintEDID(MonInfo); 1745 xf86SetDDCproperties(pScrn, MonInfo); 1746 } 1747 else 1748 { 1749 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"[ASTDoDDC] Can't Load DDC Sub-Modules or Read EDID Failed \n"); 1750 } 1751 1752 /* Fill pAST Monitor Info */ 1753 if (MonInfo == NULL) 1754 { /* default for Non-EDID */ 1755 pAST->mon_h_active = 1024; 1756 pAST->mon_v_active = 768; 1757 } 1758 else 1759 { /* save MonInfo to Private */ 1760 pAST->mon_h_active = MonInfo->det_mon[0].section.d_timings.h_active; 1761 pAST->mon_v_active = MonInfo->det_mon[0].section.d_timings.v_active; 1762 } 1763 1764 return MonInfo; 1765} 1766 1767static void 1768vFillASTModeInfo (ScrnInfoPtr pScrn) 1769{ 1770 ASTRecPtr pAST; 1771 1772 pAST = ASTPTR(pScrn); 1773 1774 pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX; 1775 pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY; 1776 pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel; 1777 /* Fixed screen pitch incorrect in some specific monitor, ycchen@071707 */ 1778 pAST->VideoModeInfo.ScreenPitch = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8) ; 1779 1780} 1781 1782static Bool 1783ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1784{ 1785 ASTRecPtr pAST; 1786 1787 pAST = ASTPTR(pScrn); 1788 1789 pScrn->vtSema = TRUE; 1790 pAST->ModePtr = mode; 1791 1792#if defined(__sparc__) || defined(__mips__) 1793 if (!ASTSetMode(pScrn, mode)) 1794 return FALSE; 1795#else 1796 vgaHWPtr hwp; 1797 1798 hwp = VGAHWPTR(pScrn); 1799 1800 vgaHWUnlock(hwp); 1801 1802 if (!vgaHWInit(pScrn, mode)) 1803 return FALSE; 1804 1805 pScrn->vtSema = TRUE; 1806 pAST->ModePtr = mode; 1807 1808 if (!ASTSetMode(pScrn, mode)) 1809 return FALSE; 1810 1811 vgaHWProtect(pScrn, FALSE); 1812#endif 1813 1814 return TRUE; 1815} 1816 1817#ifdef AstVideo 1818/* 1819 * Video Part by ic_yang 1820 */ 1821#include "fourcc.h" 1822 1823#define NUM_ATTRIBUTES 8 1824#define NUM_IMAGES 8 1825#define NUM_FORMATS 3 1826 1827#define IMAGE_MIN_WIDTH 32 1828#define IMAGE_MIN_HEIGHT 24 1829#define IMAGE_MAX_WIDTH 1920 1830#define IMAGE_MAX_HEIGHT 1080 1831 1832#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 1833 1834static XF86ImageRec ASTImages[NUM_IMAGES] = 1835{ 1836 XVIMAGE_YUY2, /* If order is changed, ASTOffscreenImages must be adapted */ 1837}; 1838 1839static XF86VideoFormatRec ASTFormats[NUM_FORMATS] = 1840{ 1841 { 8, PseudoColor}, 1842 {16, TrueColor}, 1843 {24, TrueColor} 1844}; 1845 1846/* client libraries expect an encoding */ 1847static XF86VideoEncodingRec DummyEncoding = 1848{ 1849 0, 1850 "XV_IMAGE", 1851 0, 0, /* Will be filled in */ 1852 {1, 1} 1853}; 1854 1855static char astxvcolorkey[] = "XV_COLORKEY"; 1856static char astxvbrightness[] = "XV_BRIGHTNESS"; 1857static char astxvcontrast[] = "XV_CONTRAST"; 1858static char astxvsaturation[] = "XV_SATURATION"; 1859static char astxvhue[] = "XV_HUE"; 1860static char astxvgammared[] = "XV_GAMMA_RED"; 1861static char astxvgammagreen[] = "XV_GAMMA_GREEN"; 1862static char astxvgammablue[] = "XV_GAMMA_BLUE"; 1863 1864static XF86AttributeRec ASTAttributes[NUM_ATTRIBUTES] = 1865{ 1866 {XvSettable | XvGettable, 0, (1 << 24) - 1, astxvcolorkey}, 1867 {XvSettable | XvGettable, -128, 127, astxvbrightness}, 1868 {XvSettable | XvGettable, 0, 255, astxvcontrast}, 1869 {XvSettable | XvGettable, -180, 180, astxvsaturation}, 1870 {XvSettable | XvGettable, -180, 180, astxvhue}, 1871 {XvSettable | XvGettable, 100, 10000, astxvgammared}, 1872 {XvSettable | XvGettable, 100, 10000, astxvgammagreen}, 1873 {XvSettable | XvGettable, 100, 10000, astxvgammablue}, 1874}; 1875 1876static void ASTStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) 1877{ 1878 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 1879 ASTPtr pAST = ASTPTR(pScrn); 1880 1881 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1882 1883 if(exit) 1884 { 1885 if(pPriv->fbAreaPtr) 1886 { 1887 xf86FreeOffscreenArea(pPriv->fbAreaPtr); 1888 pPriv->fbAreaPtr = NULL; 1889 pPriv->fbSize = 0; 1890 } 1891 /* clear all flag */ 1892 pPriv->videoStatus = 0; 1893 } 1894 else 1895 { 1896#if 0 1897 if(pPriv->videoStatus & CLIENT_VIDEO_ON) 1898 { 1899 pPriv->videoStatus |= OFF_TIMER; 1900 1901 } 1902#endif 1903 } 1904} 1905 1906static int ASTSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data) 1907{ 1908 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 1909 ASTPtr pAST = ASTPTR(pScrn); 1910 1911 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTSetPortAttribute(),attribute=%x\n", attribute); 1912 1913 if (attribute == pAST->xvBrightness) 1914 { 1915 if((value < -128) || (value > 127)) 1916 return BadValue; 1917 1918 pPriv->brightness = value; 1919 } 1920 else if (attribute == pAST->xvContrast) 1921 { 1922 if ((value < 0) || (value > 255)) 1923 return BadValue; 1924 1925 pPriv->contrast = value; 1926 } 1927 else if (attribute == pAST->xvSaturation) 1928 { 1929 if ((value < -180) || (value > 180)) 1930 return BadValue; 1931 1932 pPriv->saturation = value; 1933 } 1934 else if (attribute == pAST->xvHue) 1935 { 1936 if ((value < -180) || (value > 180)) 1937 return BadValue; 1938 1939 pPriv->hue = value; 1940 } 1941 else if (attribute == pAST->xvColorKey) 1942 { 1943 pPriv->colorKey = value; 1944 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1945 } 1946 else if(attribute == pAST->xvGammaRed) 1947 { 1948 if((value < 100) || (value > 10000)) 1949 return BadValue; 1950 pPriv->gammaR = value; 1951 } 1952 else if(attribute == pAST->xvGammaGreen) 1953 { 1954 if((value < 100) || (value > 10000)) 1955 return BadValue; 1956 pPriv->gammaG = value; 1957 } 1958 else if(attribute == pAST->xvGammaBlue) 1959 { 1960 if((value < 100) || (value > 10000)) 1961 return BadValue; 1962 pPriv->gammaB = value; 1963 } 1964 else 1965 { 1966 return BadMatch; 1967 } 1968 1969 return Success; 1970} 1971 1972static int ASTGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data) 1973{ 1974 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 1975 ASTPtr pAST = ASTPTR(pScrn); 1976 1977 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTGetPortAttribute(),attribute=%x\n", attribute); 1978 1979 if (attribute == pAST->xvBrightness) 1980 { 1981 *value = pPriv->brightness; 1982 } 1983 else if (attribute == pAST->xvContrast) 1984 { 1985 *value = pPriv->contrast; 1986 } 1987 else if (attribute == pAST->xvSaturation) 1988 { 1989 *value = pPriv->saturation; 1990 } 1991 else if (attribute == pAST->xvHue) 1992 { 1993 *value = pPriv->hue; 1994 } 1995 else if(attribute == pAST->xvGammaRed) 1996 { 1997 *value = pPriv->gammaR; 1998 1999 } 2000 else if(attribute == pAST->xvGammaGreen) 2001 { 2002 *value = pPriv->gammaG; 2003 } 2004 else if(attribute == pAST->xvGammaBlue) 2005 { 2006 *value = pPriv->gammaB; 2007 } 2008 else if (attribute == pAST->xvColorKey) 2009 { 2010 *value = pPriv->colorKey; 2011 } 2012 else 2013 return BadMatch; 2014 2015 return Success; 2016} 2017 2018static void ASTQueryBestSize(ScrnInfoPtr pScrn, Bool motion, 2019 short vid_w, short vid_h, 2020 short drw_w, short drw_h, 2021 unsigned int *p_w, unsigned int *p_h, 2022 pointer data) 2023{ 2024 *p_w = drw_w; 2025 *p_h = drw_h; 2026 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryBestSize()\n"); 2027 /* TODO: report the HW limitation */ 2028} 2029 2030static int ASTQueryImageAttributes(ScrnInfoPtr pScrn, int id, 2031 unsigned short *w, unsigned short *h, 2032 int *pitches, int *offsets) 2033{ 2034 int pitchY, pitchUV; 2035 int size, sizeY, sizeUV; 2036 2037 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTQueryImageAttributes()\n"); 2038 2039 if(*w < IMAGE_MIN_WIDTH) *w = IMAGE_MIN_WIDTH; 2040 if(*h < IMAGE_MIN_HEIGHT) *h = IMAGE_MIN_HEIGHT; 2041 2042 switch(id) { 2043 case PIXEL_FMT_YV12: 2044 *w = (*w + 7) & ~7; 2045 *h = (*h + 1) & ~1; 2046 pitchY = *w; 2047 pitchUV = *w >> 1; 2048 if(pitches) { 2049 pitches[0] = pitchY; 2050 pitches[1] = pitches[2] = pitchUV; 2051 } 2052 sizeY = pitchY * (*h); 2053 sizeUV = pitchUV * ((*h) >> 1); 2054 if(offsets) { 2055 offsets[0] = 0; 2056 offsets[1] = sizeY; 2057 offsets[2] = sizeY + sizeUV; 2058 } 2059 size = sizeY + (sizeUV << 1); 2060 break; 2061 case PIXEL_FMT_NV12: 2062 case PIXEL_FMT_NV21: 2063 *w = (*w + 7) & ~7; 2064 *h = (*h + 1) & ~1; 2065 pitchY = *w; 2066 pitchUV = *w; 2067 if(pitches) { 2068 pitches[0] = pitchY; 2069 pitches[1] = pitchUV; 2070 } 2071 sizeY = pitchY * (*h); 2072 sizeUV = pitchUV * ((*h) >> 1); 2073 if(offsets) { 2074 offsets[0] = 0; 2075 offsets[1] = sizeY; 2076 } 2077 size = sizeY + (sizeUV << 1); 2078 break; 2079 case PIXEL_FMT_YUY2: 2080 case PIXEL_FMT_UYVY: 2081 case PIXEL_FMT_YVYU: 2082 case PIXEL_FMT_RGB6: 2083 case PIXEL_FMT_RGB5: 2084 default: 2085 *w = (*w + 1) & ~1; 2086 pitchY = *w << 1; 2087 if(pitches) pitches[0] = pitchY; 2088 if(offsets) offsets[0] = 0; 2089 size = pitchY * (*h); 2090 break; 2091 } 2092 2093 return size; 2094} 2095 2096static int ASTPutImage(ScrnInfoPtr pScrn, 2097 short src_x, short src_y, 2098 short drw_x, short drw_y, 2099 short src_w, short src_h, 2100 short drw_w, short drw_h, 2101 int id, unsigned char* buf, 2102 short width, short height, 2103 Bool sync, 2104 RegionPtr clipBoxes, pointer data 2105#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1 2106 , DrawablePtr pDraw 2107#endif 2108) 2109{ 2110 ASTPtr pAST = ASTPTR(pScrn); 2111 ASTPortPrivPtr pPriv = (ASTPortPrivPtr)data; 2112 int i; 2113 int totalSize=0; 2114 2115 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImage()\n"); 2116 /* int depth = pAST->CurrentLayout.bitsPerPixel >> 3; */ 2117 2118 pPriv->drw_x = drw_x; 2119 pPriv->drw_y = drw_y; 2120 pPriv->drw_w = drw_w; 2121 pPriv->drw_h = drw_h; 2122 pPriv->src_x = src_x; 2123 pPriv->src_y = src_y; 2124 pPriv->src_w = src_w; 2125 pPriv->src_h = src_h; 2126 pPriv->id = id; 2127 pPriv->height = height; 2128 2129 switch(id) 2130 { 2131 case PIXEL_FMT_YV12: 2132 case PIXEL_FMT_NV12: 2133 case PIXEL_FMT_NV21: 2134 pPriv->srcPitch = (width + 7) & ~7; 2135 totalSize = (pPriv->srcPitch * height * 3) >> 1; /* Verified */ 2136 break; 2137 case PIXEL_FMT_YUY2: 2138 case PIXEL_FMT_UYVY: 2139 case PIXEL_FMT_YVYU: 2140 case PIXEL_FMT_RGB6: 2141 case PIXEL_FMT_RGB5: 2142 default: 2143 pPriv->srcPitch = ((width << 1) + 3) & ~3; /* Verified */ 2144 totalSize = pPriv->srcPitch * height; 2145 } 2146 2147 totalSize += 15; 2148 totalSize &= ~15; 2149 /* allocate memory */ 2150 2151 if(totalSize == pPriv->fbSize) 2152 { 2153 ; 2154 } 2155 else 2156 { 2157 int lines, pitch, depth; 2158 BoxPtr pBox = NULL; 2159 2160 pPriv->fbSize = totalSize; 2161 2162 if(pPriv->fbAreaPtr) 2163 { 2164 xf86FreeOffscreenArea(pPriv->fbAreaPtr); 2165 } 2166 2167 depth = (pScrn->bitsPerPixel + 7 ) / 8; 2168 pitch = pScrn->displayWidth * depth; 2169 lines = ((totalSize * 2) / pitch) + 1; 2170 xf86DrvMsg(pScrn->scrnIndex, X_INFO,"ASTPutImagelines=%x, pitch=%x, displayWidth=%x\n", lines, pitch, pScrn->displayWidth); 2171 2172 2173 pPriv->fbAreaPtr = xf86AllocateOffscreenArea(pScrn->pScreen, 2174 pScrn->displayWidth, 2175 lines, 0, NULL, NULL, NULL); 2176 2177 if(!pPriv->fbAreaPtr) 2178 { 2179 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Allocate video memory fails\n"); 2180 return BadAlloc; 2181 } 2182 2183 pBox = &(pPriv->fbAreaPtr->box); 2184 pPriv->bufAddr[0] = (pBox->y1 * pitch) + (pBox->x1 * depth); 2185 pPriv->bufAddr[1] = pPriv->bufAddr[0] + totalSize; 2186 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, pPriv->bufAddr[0]=0x%08X\n", pPriv->bufAddr[0]); 2187 2188 } 2189 2190 /* copy data */ 2191 if(totalSize < 16) 2192 { 2193 #ifdef NewPath 2194 memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); 2195 #else /* NewPath */ 2196 switch(id) 2197 { 2198 case PIXEL_FMT_YUY2: 2199 case PIXEL_FMT_UYVY: 2200 case PIXEL_FMT_YVYU: 2201 { 2202 BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); 2203 for(i=0; i<height; i++) 2204 memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2); 2205 break; 2206 } 2207 default: 2208 memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); 2209 break; 2210 } /* switch */ 2211 #endif /* NewPath */ 2212 } 2213 else 2214 { 2215 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Put Image, copy buf\n"); 2216 2217 #ifdef NewPath 2218 memcpy(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf], buf, totalSize); 2219 #else /* NewPath */ 2220 switch(id) 2221 { 2222 case PIXEL_FMT_YUY2: 2223 case PIXEL_FMT_UYVY: 2224 case PIXEL_FMT_YVYU: 2225 { 2226 BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); 2227 for(i=0; i<height; i++) 2228 memcpy( Base + i * pPriv->srcPitch, buf + i*width*2, width*2); 2229 2230 /*for(i=0; i<height; i++) 2231 for(j=0; j<width*2; j++) 2232 *(Base+i*pPriv->srcPitch+j) = *(buf + width*i + j);*/ 2233 break; 2234 } 2235 default: 2236 { BYTE *Base = (BYTE *)(pAST->FBVirtualAddr + pPriv->bufAddr[pPriv->currentBuf]); 2237 int j; 2238 for(i=0; i<height; i++) 2239 for(j=0; j<width; j++) 2240 *(Base + width*i + j) = *(buf + width * i + j); 2241 break; 2242 } 2243 } /* end of switch */ 2244 #endif /* NewPath */ 2245 } 2246 2247 ASTDisplayVideo(pScrn, pPriv, clipBoxes, id); 2248 2249 /* update cliplist 2250 if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) 2251 { 2252 REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 2253 } 2254 else 2255 { 2256 xf86XVFillKeyHelper(pScrn->pScreen, 0xFFFFFFFF, clipBoxes); 2257 } 2258 */ 2259 pPriv->currentBuf ^= 1; 2260 2261 return Success; 2262} 2263 2264static XF86VideoAdaptorPtr ASTSetupImageVideo(ScreenPtr pScreen) 2265{ 2266 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2267 ASTPtr pAST = ASTPTR(pScrn); 2268 XF86VideoAdaptorPtr adapt; 2269 ASTPortPrivPtr pPriv; 2270 2271 2272 if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 2273 sizeof(DevUnion) + 2274 sizeof(ASTPortPrivRec)))) 2275 return NULL; 2276 2277 adapt->type = XvWindowMask | XvInputMask | XvImageMask | XvVideoMask; 2278 adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 2279 adapt->name = "AST Video"; 2280 2281 adapt->nEncodings = 1; 2282 adapt->pEncodings = &DummyEncoding; 2283 2284 adapt->nFormats = NUM_FORMATS; 2285 adapt->pFormats = ASTFormats; 2286 adapt->nPorts = 1; 2287 adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 2288 2289 pPriv = (ASTPortPrivPtr)(&adapt->pPortPrivates[1]); 2290 2291 adapt->pPortPrivates->ptr = (pointer)(pPriv); 2292 adapt->pAttributes = ASTAttributes; 2293 adapt->nAttributes = NUM_ATTRIBUTES; 2294 adapt->nImages = NUM_IMAGES; 2295 adapt->pImages = ASTImages; 2296 2297 adapt->PutVideo = NULL; 2298 2299 adapt->PutStill = NULL; 2300 adapt->GetVideo = NULL; 2301 adapt->GetStill = NULL; 2302 adapt->StopVideo = ASTStopVideo; 2303 adapt->SetPortAttribute = ASTSetPortAttribute; 2304 adapt->GetPortAttribute = ASTGetPortAttribute; 2305 adapt->QueryBestSize = ASTQueryBestSize; 2306 adapt->PutImage = ASTPutImage; 2307 adapt->QueryImageAttributes = ASTQueryImageAttributes; 2308 2309 2310 pPriv->currentBuf = 0; 2311 pPriv->linear = NULL; 2312 pPriv->fbAreaPtr = NULL; 2313 pPriv->fbSize = 0; 2314 pPriv->videoStatus = 0; 2315 2316 pPriv->colorKey = 0x000101fe; 2317 pPriv->brightness = 0; 2318 pPriv->contrast = 128; 2319 pPriv->saturation = 0; 2320 pPriv->hue = 0; 2321 2322 /* gotta uninit this someplace */ 2323#if defined(REGION_NULL) 2324 REGION_NULL(pScreen, &pPriv->clip); 2325#else 2326 REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); 2327#endif 2328 2329 pAST->adaptor = adapt; 2330 2331 pAST->xvBrightness = MAKE_ATOM(astxvbrightness); 2332 pAST->xvContrast = MAKE_ATOM(astxvcontrast); 2333 pAST->xvColorKey = MAKE_ATOM(astxvcolorkey); 2334 pAST->xvSaturation = MAKE_ATOM(astxvsaturation); 2335 pAST->xvHue = MAKE_ATOM(astxvhue); 2336 pAST->xvGammaRed = MAKE_ATOM(astxvgammared); 2337 pAST->xvGammaGreen = MAKE_ATOM(astxvgammagreen); 2338 pAST->xvGammaBlue = MAKE_ATOM(astxvgammablue); 2339 2340 return adapt; 2341} 2342 2343void ASTInitVideo(ScreenPtr pScreen) 2344{ 2345 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2346 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 2347 XF86VideoAdaptorPtr ASTAdaptor = NULL; 2348 int num_adaptors; 2349 2350 ASTAdaptor = ASTSetupImageVideo(pScreen); 2351 2352 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 2353 2354 if(ASTAdaptor) 2355 { 2356 if(!num_adaptors) 2357 { 2358 num_adaptors = 1; 2359 adaptors = &ASTAdaptor; 2360 } 2361 else 2362 { 2363 newAdaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); 2364 if(newAdaptors) 2365 { 2366 memcpy(newAdaptors, adaptors, num_adaptors * 2367 sizeof(XF86VideoAdaptorPtr)); 2368 newAdaptors[num_adaptors] = ASTAdaptor; 2369 adaptors = newAdaptors; 2370 num_adaptors++; 2371 } 2372 } 2373 } 2374 2375 if(num_adaptors) 2376 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 2377 2378 if(newAdaptors) 2379 free(newAdaptors); 2380 2381} 2382#endif /* AstVideo */ 2383