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