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