summaryrefslogtreecommitdiff
path: root/src/ast_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast_driver.c')
-rw-r--r--src/ast_driver.c1220
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;
+}