diff options
Diffstat (limited to 'src/ast_driver.c')
-rw-r--r-- | src/ast_driver.c | 1220 |
1 files changed, 1220 insertions, 0 deletions
diff --git a/src/ast_driver.c b/src/ast_driver.c new file mode 100644 index 0000000..44a57d3 --- /dev/null +++ b/src/ast_driver.c @@ -0,0 +1,1220 @@ +/* + * Copyright (c) 2005 ASPEED Technology Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the authors not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "compiler.h" +#include "mibstore.h" +#include "vgaHW.h" +#include "mipointer.h" +#include "micmap.h" + +#include "fb.h" +#include "regionstr.h" +#include "xf86xv.h" +#include "Xv.h" +#include "vbe.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +/* framebuffer offscreen manager */ +#include "xf86fbman.h" + +/* include xaa includes */ +#include "xaa.h" +#include "xaarop.h" + +/* H/W cursor support */ +#include "xf86Cursor.h" + +/* Driver specific headers */ +#include "ast.h" + +/* external reference fucntion */ +extern Bool ASTMapMem(ScrnInfoPtr pScrn); +extern Bool ASTUnmapMem(ScrnInfoPtr pScrn); +extern Bool ASTMapMMIO(ScrnInfoPtr pScrn); +extern void ASTUnmapMMIO(ScrnInfoPtr pScrn); + +extern void vASTOpenKey(ScrnInfoPtr pScrn); +extern Bool bASTRegInit(ScrnInfoPtr pScrn); +extern ULONG GetVRAMInfo(ScrnInfoPtr pScrn); +extern void vASTLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual); +extern void ASTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); +extern void vSetStartAddressCRT1(ASTRecPtr pAST, ULONG base); +extern Bool ASTSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode); + +extern Bool bInitCMDQInfo(ScrnInfoPtr pScrn, ASTRecPtr pAST); +extern Bool bEnableCMDQ(ScrnInfoPtr pScrn, ASTRecPtr pAST); +extern void vDisable2D(ScrnInfoPtr pScrn, ASTRecPtr pAST); + +extern Bool ASTAccelInit(ScreenPtr pScreen); + +extern Bool ASTCursorInit(ScreenPtr pScreen); + +/* Mandatory functions */ +static void ASTIdentify(int flags); +const OptionInfoRec *ASTAvailableOptions(int chipid, int busid); +static Bool ASTProbe(DriverPtr drv, int flags); +static Bool ASTPreInit(ScrnInfoPtr pScrn, int flags); +static Bool ASTScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); +Bool ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +void ASTAdjustFrame(int scrnIndex, int x, int y, int flags); +static Bool ASTEnterVT(int scrnIndex, int flags); +static void ASTLeaveVT(int scrnIndex, int flags); +static void ASTFreeScreen(int scrnIndex, int flags); +static ModeStatus ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); + +/* Internally used functions */ +static Bool ASTGetRec(ScrnInfoPtr pScrn); +static void ASTFreeRec(ScrnInfoPtr pScrn); +static Bool ASTSaveScreen(ScreenPtr pScreen, Bool unblack); +static Bool ASTCloseScreen(int scrnIndex, ScreenPtr pScreen); +static void ASTSave(ScrnInfoPtr pScrn); +static void ASTRestore(ScrnInfoPtr pScrn); +static void ASTProbeDDC(ScrnInfoPtr pScrn, int index); +static xf86MonPtr ASTDoDDC(ScrnInfoPtr pScrn, int index); +static void vFillASTModeInfo (ScrnInfoPtr pScrn); +static Bool ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); + +/* + * This is intentionally screen-independent. It indicates the binding + * choice made in the first PreInit. + */ +DriverRec AST = { + AST_VERSION, + AST_DRIVER_NAME, + ASTIdentify, + ASTProbe, + ASTAvailableOptions, + NULL, + 0 +}; + +/* Chipsets */ +static SymTabRec ASTChipsets[] = { + {PCI_CHIP_AST2000, "AST2000"}, + {-1, NULL} +}; + +static PciChipsets ASTPciChipsets[] = { + {PCI_CHIP_AST2000, PCI_CHIP_AST2000, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED } +}; + +typedef enum { + OPTION_NOACCEL, + OPTION_MMIO2D, + OPTION_SW_CURSOR, + OPTION_HWC_NUM, + OPTION_ENG_CAPS, + OPTION_DBG_SELECT, + OPTION_NO_DDC, +} ASTOpts; + +static const OptionInfoRec ASTOptions[] = { + {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_MMIO2D, "MMIO2D", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_HWC_NUM, "HWCNumber", OPTV_INTEGER, {0}, FALSE}, + {OPTION_ENG_CAPS, "ENGCaps", OPTV_INTEGER, {0}, FALSE}, + {OPTION_DBG_SELECT, "DBGSelect", OPTV_INTEGER, {0}, FALSE}, + {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +const char *vgahwSymbols[] = { + "vgaHWFreeHWRec", + "vgaHWGetHWRec", + "vgaHWGetIOBase", + "vgaHWGetIndex", + "vgaHWInit", + "vgaHWLock", + "vgaHWMapMem", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWSave", + "vgaHWSaveScreen", + "vgaHWSetMmioFuncs", + "vgaHWUnlock", + "vgaHWUnmapMem", + NULL +}; + +const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", + NULL +}; + +const char *vbeSymbols[] = { + "VBEInit", + "VBEFreeModeInfo", + "VBEFreeVBEInfo", + "VBEGetModeInfo", + "VBEGetModePool", + "VBEGetVBEInfo", + "VBEGetVBEMode", + "VBEPrintModes", + "VBESaveRestore", + "VBESetDisplayStart", + "VBESetGetDACPaletteFormat", + "VBESetGetLogicalScanlineLength", + "VBESetGetPaletteData", + "VBESetModeNames", + "VBESetModeParameters", + "VBESetVBEMode", + "VBEValidateModes", + "vbeDoEDID", + "vbeFree", + NULL +}; + +#ifdef XFree86LOADER +static const char *vbeOptionalSymbols[] = { + "VBEDPMSSet", + "VBEGetPixelClock", + NULL +}; +#endif + +const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86SetDDCproperties", + NULL +}; + +const char *int10Symbols[] = { + "xf86ExecX86int10", + "xf86InitInt10", + "xf86Int10AllocPages", + "xf86int10Addr", + NULL +}; + +const char *xaaSymbols[] = { + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAInit", + "XAACopyROP", + "XAAPatternROP", + NULL +}; + +const char *ramdacSymbols[] = { + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + "xf86InitCursor", + NULL +}; + + +#ifdef XFree86LOADER + +static MODULESETUPPROTO(astSetup); + +static XF86ModuleVersionInfo astVersRec = { + AST_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + AST_MAJOR_VERSION, AST_MINOR_VERSION, AST_PATCH_VERSION, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +XF86ModuleData astModuleData = { &astVersRec, astSetup, NULL }; + +static pointer +astSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + /* This module should be loaded only once, but check to be sure. + */ + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&AST, module, 0); + + /* + * Tell the loader about symbols from other modules that this module + * might refer to. + */ + LoaderRefSymLists(vgahwSymbols, + fbSymbols, xaaSymbols, ramdacSymbols, + vbeSymbols, vbeOptionalSymbols, + ddcSymbols, int10Symbols, NULL); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer) TRUE; + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#endif /* XFree86LOADER */ + +/* + * ASTIdentify -- + * + * Returns the string name for the driver based on the chipset. In this + * case it will always be an AST, so we can return a static string. + * + */ +static void +ASTIdentify(int flags) +{ + xf86PrintChipsets(AST_NAME, "Driver for AST Graphics Chipsets", + ASTChipsets); +} + +const OptionInfoRec * +ASTAvailableOptions(int chipid, int busid) +{ + + return ASTOptions; + +} + +/* + * ASTProbe -- + * + * Look through the PCI bus to find cards that are AST boards. + * Setup the dispatch table for the rest of the driver functions. + * + */ +static Bool +ASTProbe(DriverPtr drv, int flags) +{ + int i, numUsed, numDevSections, *usedChips; + Bool foundScreen = FALSE; + GDevPtr *devSections; + + /* + * Find the config file Device sections that match this + * driver, and return if there are none. + */ + if ((numDevSections = + xf86MatchDevice(AST_DRIVER_NAME, &devSections)) <= 0) { + return FALSE; + } + + /* + * This probing is just checking the PCI data the server already + * collected. + */ + if (xf86GetPciVideoInfo() == NULL) { + return FALSE; + } + + numUsed = xf86MatchPciInstances(AST_NAME, PCI_VENDOR_AST, + ASTChipsets, ASTPciChipsets, + devSections, numDevSections, + drv, &usedChips); + + xfree(devSections); + + if (flags & PROBE_DETECT) { + if (numUsed > 0) + foundScreen = TRUE; + } else { + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + + /* Allocate new ScrnInfoRec and claim the slot */ + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + ASTPciChipsets, 0, 0, 0, 0, 0))) + { + EntityInfoPtr pEnt; + + pEnt = xf86GetEntityInfo(usedChips[i]); + + pScrn->driverVersion = AST_VERSION; + pScrn->driverName = AST_DRIVER_NAME; + pScrn->name = AST_NAME; + + pScrn->Probe = ASTProbe; + pScrn->PreInit = ASTPreInit; + pScrn->ScreenInit = ASTScreenInit; + pScrn->SwitchMode = ASTSwitchMode; + pScrn->AdjustFrame = ASTAdjustFrame; + pScrn->EnterVT = ASTEnterVT; + pScrn->LeaveVT = ASTLeaveVT; + pScrn->FreeScreen = ASTFreeScreen; + pScrn->ValidMode = ASTValidMode; + + foundScreen = TRUE; + + } /* end of if */ + } /* end of for-loop */ + } /* end of if flags */ + + xfree(usedChips); + + return foundScreen; +} + +/* + * ASTPreInit -- + * + * Do initial setup of the board before we know what resolution we will + * be running at. + * + */ +static Bool +ASTPreInit(ScrnInfoPtr pScrn, int flags) +{ + EntityInfoPtr pEnt; + vgaHWPtr hwp; + int flags24; + rgb defaultWeight = { 0, 0, 0 }; + + ASTRecPtr pAST; + + ClockRangePtr clockRanges; + int i; + MessageType from; + + /* Suport one adapter only now */ + if (pScrn->numEntities != 1) + return FALSE; + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + + if (flags & PROBE_DETECT) { + ASTProbeDDC(pScrn, pEnt->index); + return TRUE; + } + + if (pEnt->location.type != BUS_PCI) + return FALSE; + + if (xf86RegisterResources(pEnt->index, 0, ResExclusive)) + return FALSE; + + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + xf86LoaderReqSymLists(vgahwSymbols, NULL); + + /* The fb module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "fb")) + return FALSE; + xf86LoaderReqSymLists(fbSymbols, NULL); + + /* Allocate a vgaHWRec */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + hwp = VGAHWPTR(pScrn); + + /* Color Depth Check */ + flags24 = Support32bppFb; + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) { + return FALSE; + } else { + switch (pScrn->depth) { + case 8: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by ast driver\n", + pScrn->depth); + return FALSE; + } + } + xf86PrintDepthBpp(pScrn); + + switch (pScrn->bitsPerPixel) { + case 8: + case 16: + case 32: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given bpp (%d) is not supported by ast driver\n", + pScrn->bitsPerPixel); + return FALSE; + } + + /* fill pScrn misc. */ + pScrn->progClock = TRUE; + pScrn->rgbBits = 6; + pScrn->monitor = pScrn->confScreen->monitor; /* should be initialized before set gamma */ + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + + /* + * If the driver can do gamma correction, it should call xf86SetGamma() + * here. + */ + { + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call xf86SetGamma failed \n"); + return FALSE; + } + } + + + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) { + return FALSE; + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } + + /* Allocate driverPrivate */ + if (!ASTGetRec(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "call ASTGetRec failed \n"); + return FALSE; + } + + /* Fill AST Info */ + pAST = ASTPTR(pScrn); + pAST->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + pAST->PciInfo = xf86GetPciInfoForEntity(pAST->pEnt->index); + pAST->PciTag = pciTag(pAST->PciInfo->bus, pAST->PciInfo->device, + pAST->PciInfo->func); + + /* Process the options + * pScrn->confScreen, pScrn->display, pScrn->monitor, pScrn->numEntities, + * and pScrn->entityList should be initialized before + */ + xf86CollectOptions(pScrn, NULL); + if (!(pAST->Options = xalloc(sizeof(ASTOptions)))) + { + ASTFreeRec(pScrn); + return FALSE; + } + memcpy(pAST->Options, ASTOptions, sizeof(ASTOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pAST->Options); + + /* + * Set the Chipset and ChipRev, allowing config file entries to + * override. + */ + if (pAST->pEnt->device->chipset && *pAST->pEnt->device->chipset) { + pScrn->chipset = pAST->pEnt->device->chipset; + from = X_CONFIG; + } else if (pAST->pEnt->device->chipID >= 0) { + pScrn->chipset = (char *)xf86TokenToString(ASTChipsets, + pAST->pEnt->device->chipID); + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + pAST->pEnt->device->chipID); + } else { + from = X_PROBED; + pScrn->chipset = (char *)xf86TokenToString(ASTChipsets, + pAST->PciInfo->chipType); + } + if (pAST->pEnt->device->chipRev >= 0) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pAST->pEnt->device->chipRev); + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", + (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown ast"); + + /* Resource Allocation */ +#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) + pAST->IODBase = 0; +#else + pAST->IODBase = pScrn->domainIOBase; +#endif + /* "Patch" the PIOOffset inside vgaHW in order to force + * the vgaHW module to use our relocated i/o ports. + */ + VGAHWPTR(pScrn)->PIOOffset = pAST->PIOOffset = pAST->IODBase + pAST->PciInfo->ioBase[2] - 0x380; + + pAST->RelocateIO = (IOADDRESS)(pAST->PciInfo->ioBase[2] + pAST->IODBase); + + if (pAST->pEnt->device->MemBase != 0) { + pAST->FBPhysAddr = pAST->pEnt->device->MemBase; + from = X_CONFIG; + } else { + if (pAST->PciInfo->memBase[0] != 0) { + pAST->FBPhysAddr = pAST->PciInfo->memBase[0] & 0xFFF00000; + from = X_PROBED; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid FB address in PCI config space\n"); + ASTFreeRec(pScrn); + return FALSE; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Linear framebuffer at 0x%lX\n", + (unsigned long) pAST->FBPhysAddr); + + if (pAST->pEnt->device->IOBase != 0) { + pAST->MMIOPhysAddr = pAST->pEnt->device->IOBase; + from = X_CONFIG; + } else { + if (pAST->PciInfo->memBase[1]) { + pAST->MMIOPhysAddr = pAST->PciInfo->memBase[1] & 0xFFFF0000; + from = X_PROBED; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "No valid MMIO address in PCI config space\n"); + ASTFreeRec(pScrn); + return FALSE; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IO registers at addr 0x%lX\n", + (unsigned long) pAST->MMIOPhysAddr); + + pScrn->videoRam = GetVRAMInfo(pScrn) / 1024; + from = X_DEFAULT; + + + if (pAST->pEnt->device->videoRam) { + pScrn->videoRam = pAST->pEnt->device->videoRam; + from = X_CONFIG; + } + + pAST->FbMapSize = pScrn->videoRam * 1024; + pAST->MMIOMapSize = DEFAULT_MMIO_SIZE; + + /* Do DDC + * should be done after xf86CollectOptions + */ + pScrn->monitor->DDC = ASTDoDDC(pScrn, pAST->pEnt->index); + + /* Mode Valid */ + clockRanges = xnfcalloc(sizeof(ClockRange), 1); + clockRanges->next = NULL; + clockRanges->minClock = 9500; + clockRanges->maxClock = 165000; + clockRanges->clockIndex = -1; + clockRanges->interlaceAllowed = FALSE; + clockRanges->doubleScanAllowed = FALSE; + + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + 0, 320, 1600, 8 * pScrn->bitsPerPixel, + 200, 1200, + pScrn->display->virtualX, pScrn->display->virtualY, + pAST->FbMapSize, LOOKUP_BEST_REFRESH); + + if (i == -1) { + ASTFreeRec(pScrn); + return FALSE; + } + + xf86PruneDriverModes(pScrn); + + if (!i || !pScrn->modes) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + ASTFreeRec(pScrn); + return FALSE; + } + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + + pScrn->currentMode = pScrn->modes; + + xf86PrintModes(pScrn); + + xf86SetDpi(pScrn, 0, 0); + + /* Accelaration Check */ + pAST->noAccel = TRUE; + pAST->AccelInfoPtr = NULL; + pAST->pCMDQPtr = NULL; + pAST->CMDQInfo.ulCMDQSize = 0; +#ifdef Accel_2D + if (!xf86ReturnOptValBool(pAST->Options, OPTION_NOACCEL, FALSE)) + { + if (!xf86LoadSubModule(pScrn, "xaa")) { + ASTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(xaaSymbols, NULL); + + pAST->noAccel = FALSE; + + pAST->MMIO2D = TRUE; +#ifndef MMIO_2D + if (!xf86ReturnOptValBool(pAST->Options, OPTION_MMIO2D, FALSE)) { + pAST->CMDQInfo.ulCMDQSize = DEFAULT_CMDQ_SIZE; + pAST->MMIO2D = FALSE; + } +#endif + + pAST->ENGCaps = ENG_CAP_ALL; + if (!xf86GetOptValInteger(pAST->Options, OPTION_ENG_CAPS, &pAST->ENGCaps)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No ENG Capability options found\n"); + } + + pAST->DBGSelect = 0; + if (!xf86GetOptValInteger(pAST->Options, OPTION_DBG_SELECT, &pAST->DBGSelect)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DBG Seleclt options found\n"); + } + } +#endif + + /* HW Cursor Check */ + pAST->noHWC = TRUE; + pAST->HWCInfoPtr = NULL; + pAST->pHWCPtr = NULL; +#ifdef HWC + if (!xf86ReturnOptValBool(pAST->Options, OPTION_SW_CURSOR, FALSE)) { + if (!xf86LoadSubModule(pScrn, "ramdac")) { + ASTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ramdacSymbols, NULL); + + pAST->noHWC = FALSE; + pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; + if (!xf86GetOptValInteger(pAST->Options, OPTION_HWC_NUM, &pAST->HWCInfo.HWC_NUM)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No HWC_NUM options found\n"); + } + + } +#endif + + /* We won't be using the VGA access after the probe */ + xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMem, pAST->pEnt->index, ResDisableOpr); + + return TRUE; +} + + +static Bool +ASTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn; + ASTRecPtr pAST; + vgaHWPtr hwp; + VisualPtr visual; + + /* for FB Manager */ + BoxRec FBMemBox; + int AvailFBSize; + + pScrn = xf86Screens[pScreen->myNum]; + pAST = ASTPTR(pScrn); + hwp = VGAHWPTR(pScrn); + + + if (!ASTMapMem(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map FB Memory Failed \n"); + return FALSE; + } + + if (!ASTMapMMIO(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Map Memory Map IO Failed \n"); + return FALSE; + } + + pScrn->memPhysBase = (ULONG)pAST->FBPhysAddr; + pScrn->fbOffset = 0; + +/* if (!pAST->noAccel) */ + { + /* AvailFBSize = pAST->FbMapSize - pAST->CMDQInfo.ulCMDQSize; */ + AvailFBSize = pAST->FbMapSize; + + FBMemBox.x1 = 0; + FBMemBox.y1 = 0; + FBMemBox.x2 = pScrn->displayWidth; + FBMemBox.y2 = (AvailFBSize / (pScrn->displayWidth * ((pScrn->bitsPerPixel+1)/8))) - 1; + + if (!xf86InitFBManager(pScreen, &FBMemBox)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); + return FALSE; + } + + } + + vgaHWGetIOBase(hwp); + + vFillASTModeInfo (pScrn); + + ASTSave(pScrn); + if (!ASTModeInit(pScrn, pScrn->currentMode)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Mode Init Failed \n"); + return FALSE; + } + + ASTSaveScreen(pScreen, FALSE); + ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + miClearVisualTypes(); + + /* Re-implemented Direct Color support, -jens */ + if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + + if (!miSetPixmapDepths()) + { + ASTSaveScreen(pScreen, SCREEN_SAVER_OFF); + return FALSE; + } + + switch(pScrn->bitsPerPixel) { + case 8: + case 16: + case 32: + if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel)) + return FALSE; + break; + default: + return FALSE; + + } + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + fbPictureInit(pScreen, 0, 0); + + xf86SetBlackWhitePixels(pScreen); + +#ifdef Accel_2D + if (!pAST->noAccel) + { + if (!ASTAccelInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware acceleration initialization failed\n"); + pAST->noAccel = TRUE; + } + } +#endif /* end of Accel_2D */ + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + if (!pAST->noHWC) + { + if (!ASTCursorInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Hardware cursor initialization failed\n"); + pAST->noHWC = TRUE; + } + } + + if (!miCreateDefColormap(pScreen)) + return FALSE; + + if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits, + vASTLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { + return FALSE; + } + + xf86DPMSInit(pScreen, ASTDisplayPowerManagementSet, 0); + + pScreen->SaveScreen = ASTSaveScreen; + pAST->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = ASTCloseScreen; + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + + return TRUE; + +} /* ASTScreenInit */ + + +Bool +ASTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + ASTRecPtr pAST = ASTPTR(pScrn); + +#ifdef HWC + if (pAST->pHWCPtr) { + xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ + pAST->pHWCPtr = NULL; + } +#endif + +#ifdef Accel_2D + if (pAST->pCMDQPtr) { + xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ + pAST->pCMDQPtr = NULL; + } + vDisable2D(pScrn, pAST); +#endif + + ASTRestore(pScrn); + + return ASTModeInit(pScrn, mode); + +} + +void +ASTAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + ASTRecPtr pAST = ASTPTR(pScrn); + ULONG base; + + base = y * pAST->VideoModeInfo.ScreenWidth + x * ((pAST->VideoModeInfo.bitsPerPixel + 1) / 8); + base = base >> 2; /* DW unit */ + + vSetStartAddressCRT1(pAST, base); + +} + +/* enter into X Server */ +static Bool +ASTEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + if (!ASTModeInit(pScrn, pScrn->currentMode)) + return FALSE; + ASTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; + +} + +/* leave X server */ +static void +ASTLeaveVT(int scrnIndex, int flags) +{ + + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + ASTRecPtr pAST = ASTPTR(pScrn); + +#ifdef HWC + if (pAST->pHWCPtr) { + xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ + pAST->pHWCPtr = NULL; + } +#endif + +#ifdef Accel_2D + if (pAST->pCMDQPtr) { + xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ + pAST->pCMDQPtr = NULL; + } + vDisable2D(pScrn, pAST); +#endif + + ASTRestore(pScrn); + vgaHWLock(hwp); + +} + +static void +ASTFreeScreen(int scrnIndex, int flags) +{ + ASTFreeRec(xf86Screens[scrnIndex]); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); +} + + +static ModeStatus +ASTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + + Bool Flags = MODE_NOMODE; + + if (mode->Flags & V_INTERLACE) { + if (verbose) { + xf86DrvMsg(scrnIndex, X_PROBED, + "Removing interlaced mode \"%s\"\n", mode->name); + } + return MODE_NO_INTERLACE; + } + + if ((mode->CrtcHDisplay > MAX_HResolution) || (mode->CrtcVDisplay > MAX_VResolution)) { + if (verbose) { + xf86DrvMsg(scrnIndex, X_PROBED, + "Removing the mode \"%s\"\n", mode->name); + } + return Flags; + } + + switch (mode->CrtcHDisplay) + { + case 640: + if (mode->CrtcVDisplay == 480) Flags=MODE_OK; + break; + case 800: + if (mode->CrtcVDisplay == 600) Flags=MODE_OK; + break; + case 1024: + if (mode->CrtcVDisplay == 768) Flags=MODE_OK; + break; + case 1280: + if (mode->CrtcVDisplay == 1024) Flags=MODE_OK; + break; + case 1600: + if (mode->CrtcVDisplay == 1200) Flags=MODE_OK; + break; + default: + return Flags; + } + + return Flags; + +} + + +/* Internal used modules */ +/* + * ASTGetRec and ASTFreeRec -- + * + * Private data for the driver is stored in the screen structure. + * These two functions create and destroy that private data. + * + */ +static Bool +ASTGetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(ASTRec), 1); + return TRUE; +} + +static void +ASTFreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn) + return; + if (!pScrn->driverPrivate) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = 0; +} + +static Bool +ASTSaveScreen(ScreenPtr pScreen, Bool unblack) +{ + /* more ref. SiS */ + return vgaHWSaveScreen(pScreen, unblack); +} + +static Bool +ASTCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + ASTRecPtr pAST = ASTPTR(pScrn); + + if (pScrn->vtSema == TRUE) + { +#ifdef HWC + if (pAST->pHWCPtr) { + xf86FreeOffscreenLinear(pAST->pHWCPtr); /* free HWC Cache */ + pAST->pHWCPtr = NULL; + } +#endif + +#ifdef Accel_2D + if (pAST->pCMDQPtr) { + xf86FreeOffscreenLinear(pAST->pCMDQPtr); /* free CMDQ */ + pAST->pCMDQPtr = NULL; + } + vDisable2D(pScrn, pAST); +#endif + + ASTRestore(pScrn); + vgaHWLock(hwp); + } + + ASTUnmapMem(pScrn); + vgaHWUnmapMem(pScrn); + + if(pAST->AccelInfoPtr) { + XAADestroyInfoRec(pAST->AccelInfoPtr); + pAST->AccelInfoPtr = NULL; + } + + if(pAST->HWCInfoPtr) { + xf86DestroyCursorInfoRec(pAST->HWCInfoPtr); + pAST->HWCInfoPtr = NULL; + } + + pScrn->vtSema = FALSE; + pScreen->CloseScreen = pAST->CloseScreen; + return (*pScreen->CloseScreen) (scrnIndex, pScreen); +} + +static void +ASTSave(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST; + vgaRegPtr vgaReg; + ASTRegPtr astReg; + int i; + + pAST = ASTPTR(pScrn); + vgaReg = &VGAHWPTR(pScrn)->SavedReg; + astReg = &pAST->SavedReg; + + /* do save */ + vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); + + /* Ext. Save */ + vASTOpenKey(pScrn); + + for (i=0; i<0x50; i++) + GetIndexReg(CRTC_PORT, (UCHAR) (i+0x80), astReg->ExtCRTC[i]); + +} + +static void +ASTRestore(ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST; + vgaRegPtr vgaReg; + ASTRegPtr astReg; + int i; + + pAST = ASTPTR(pScrn); + vgaReg = &VGAHWPTR(pScrn)->SavedReg; + astReg = &pAST->SavedReg; + + /* do restore */ + vgaHWProtect(pScrn, TRUE); + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + vgaHWProtect(pScrn, FALSE); + + /* Ext. restore */ + vASTOpenKey(pScrn); + + for (i=0; i<0x50; i++) + SetIndexReg(CRTC_PORT, (UCHAR) (i+0x80), astReg->ExtCRTC[i]); + +} + +static void +ASTProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } +} + +static xf86MonPtr +ASTDoDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + xf86MonPtr MonInfo = NULL; + ASTRecPtr pAST = ASTPTR(pScrn); + + /* Honour Option "noDDC" */ + if (xf86ReturnOptValBool(pAST->Options, OPTION_NO_DDC, FALSE)) { + return MonInfo; + } + + if (xf86LoadSubModule(pScrn, "vbe") && (pVbe = VBEInit(NULL, index))) { + xf86LoaderReqSymLists(vbeSymbols, NULL); + MonInfo = vbeDoEDID(pVbe, NULL); + xf86PrintEDID(MonInfo); + xf86SetDDCproperties(pScrn, MonInfo); + vbeFree(pVbe); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "this driver cannot do DDC without VBE\n"); + } + + return MonInfo; +} + +static void +vFillASTModeInfo (ScrnInfoPtr pScrn) +{ + ASTRecPtr pAST; + + pAST = ASTPTR(pScrn); + + pAST->VideoModeInfo.ScreenWidth = pScrn->virtualX; + pAST->VideoModeInfo.ScreenHeight = pScrn->virtualY; + pAST->VideoModeInfo.bitsPerPixel = pScrn->bitsPerPixel; + pAST->VideoModeInfo.ScreenPitch = pScrn->virtualX * ((pScrn->bitsPerPixel + 1) / 8) ; + +} + +static Bool +ASTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp; + ASTRecPtr pAST; + + hwp = VGAHWPTR(pScrn); + pAST = ASTPTR(pScrn); + + vgaHWUnlock(hwp); + + if (!vgaHWInit(pScrn, mode)) + return FALSE; + + pScrn->vtSema = TRUE; + pAST->ModePtr = mode; + + if (!ASTSetMode(pScrn, mode)) + return FALSE; + + vgaHWProtect(pScrn, FALSE); + + return TRUE; +} |