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