diff options
Diffstat (limited to 'src/via_driver.c')
-rw-r--r-- | src/via_driver.c | 3276 |
1 files changed, 3276 insertions, 0 deletions
diff --git a/src/via_driver.c b/src/via_driver.c new file mode 100644 index 0000000..c442134 --- /dev/null +++ b/src/via_driver.c @@ -0,0 +1,3276 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_driver.c,v 1.16 2003/10/31 17:19:35 tsi Exp $ */ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/************************************************************************* + * + * File: via_driver.c + * Content: XFree86 4.0 for VIA/S3G UniChrom + * + ************************************************************************/ + +#include "xf86RAC.h" +#include "shadowfb.h" + +#include "globals.h" +#define DPMS_SERVER +#include "extensions/dpms.h" + + +#include "via_driver.h" +#include "via_video.h" +#include "videodev.h" +#include "via_swov.h" + +#include "ddmpeg.h" +#include "via_capture.h" +#include "via.h" +#ifdef XF86DRI +#include "dri.h" +#endif + +/* + * prototypes + */ + +static void VIAIdentify(int flags); +static Bool VIAProbe(DriverPtr drv, int flags); +static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags); +static Bool VIAEnterVT(int scrnIndex, int flags); +static void VIALeaveVT(int scrnIndex, int flags); +static void VIASave(ScrnInfoPtr pScrn); +static void VIAWriteMode(ScrnInfoPtr pScrn, vgaRegPtr, VIARegPtr); +static Bool VIAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool VIASaveScreen(ScreenPtr pScreen, int mode); +static void VIALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, + LOCO *colors, VisualPtr pVisual); +static Bool VIAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, + char **argv); +static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen); +static void VIAFreeScreen(int scrnIndex, int flags); +static ModeStatus VIAValidMode(int index, DisplayModePtr mode, + Bool verbose, int flags); +static void VIADPMS(ScrnInfoPtr pScrn, int mode, int flags); +static const OptionInfoRec * VIAAvailableOptions(int chipid, int busid); + + +static void VIAEnableMMIO(ScrnInfoPtr pScrn); +static void VIADisableMMIO(ScrnInfoPtr pScrn); +static Bool VIAMapMMIO(ScrnInfoPtr pScrn); +static Bool VIAMapFB(ScrnInfoPtr pScrn); +static void VIAUnmapMem(ScrnInfoPtr pScrn); +static int VIAGetMemSize(void); +Bool VIADeviceSelection(ScrnInfoPtr pScrn); +Bool VIADeviceDispatch(ScrnInfoPtr pScrn); + +#ifdef XF86DRI +void VIAInitialize3DEngine(ScrnInfoPtr pScrn); +#endif + +DriverRec VIA = +{ + VIA_VERSION, + DRIVER_NAME, + VIAIdentify, + VIAProbe, + VIAAvailableOptions, + NULL, + 0 +}; + + +/* Supported chipsets */ + +static SymTabRec VIAChipsets[] = { + {VIA_CLE266, "CLE266"}, + {VIA_KM400, "KM400"}, + {VIA_K8M800, "K8M800"}, + {-1, NULL } +}; + + +/* This table maps a PCI device ID to a chipset family identifier. */ + +static PciChipsets VIAPciChipsets[] = { + {VIA_CLE266, PCI_CHIP_CLE3122, RES_SHARED_VGA}, + {VIA_CLE266, PCI_CHIP_CLE3022, RES_SHARED_VGA}, + {VIA_KM400, PCI_CHIP_VT7205, RES_SHARED_VGA}, + {VIA_KM400, PCI_CHIP_VT3205, RES_SHARED_VGA}, + {VIA_K8M800, PCI_CHIP_VT7204, RES_SHARED_VGA}, + {VIA_K8M800, PCI_CHIP_VT3204, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED} +}; + +int gVIAEntityIndex = -1; + +typedef enum { + OPTION_A2, + OPTION_PCI_BURST, + OPTION_PCI_RETRY, + OPTION_NOACCEL, + OPTION_SWCURSOR, + OPTION_HWCURSOR, + OPTION_SHADOW_FB, + OPTION_ROTATE, + OPTION_USEBIOS, + OPTION_VIDEORAM, + OPTION_ACTIVEDEVICE, + OPTION_LCDDUALEDGE, + OPTION_BUSWIDTH, + OPTION_CENTER, + OPTION_PANELSIZE, + OPTION_TVDOTCRAWL, + OPTION_TVTYPE, + OPTION_TVOUTPUT, + OPTION_TVVSCAN, + OPTION_TVHSCALE, + OPTION_TVENCODER, + OPTION_REFRESH, + OPTION_DISABLEVQ, + OPTION_NODDCVALUE, + OPTION_CAP0_DEINTERLACE, + OPTION_CAP1_DEINTERLACE, + OPTION_CAP0_FIELDSWAP, + OPTION_DRIXINERAMA +} VIAOpts; + + +static OptionInfoRec VIAOptions[] = +{ + {OPTION_A2, "A2", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_VIDEORAM, "VideoRAM", OPTV_INTEGER, {0}, FALSE}, + {OPTION_ACTIVEDEVICE, "ActiveDevice", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_LCDDUALEDGE, "LCDDualEdge", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_BUSWIDTH, "BusWidth", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_CENTER, "Center", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_PANELSIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TVDOTCRAWL, "TVDotCrawl", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_TVTYPE, "TVType", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TVOUTPUT, "TVOutput", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TVVSCAN, "TVVScan", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TVHSCALE, "TVHScale", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_TVENCODER, "TVEncoder", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_REFRESH, "Refresh", OPTV_INTEGER, {0}, FALSE}, + {OPTION_DISABLEVQ, "DisableVQ", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_NODDCVALUE, "NoDDCValue", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_CAP0_DEINTERLACE, "Cap0Deinterlace", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_CAP1_DEINTERLACE, "Cap1Deinterlace", OPTV_ANYSTR, {0}, FALSE}, + {OPTION_CAP0_FIELDSWAP, "Cap0FieldSwap", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_DRIXINERAMA, "DRIXINERAMA", OPTV_BOOLEAN, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + + +static const char *vgaHWSymbols[] = { + "vgaHWGetHWRec", + "vgaHWSetMmioFuncs", + "vgaHWSetStdFuncs", + "vgaHWGetIOBase", + "vgaHWSave", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWMapMem", + "vgaHWUnmapMem", + "vgaHWInit", + "vgaHWSaveScreen", + "vgaHWLock", + "vgaHWUnlock", + "vgaHWFreeHWRec", + NULL +}; + + +static const char *ramdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + "vbeFree", + NULL +}; + +static const char *ddcSymbols[] = { + "xf86InterpretEDID", + "xf86PrintEDID", + "xf86DoEDID_DDC1", + "xf86DoEDID_DDC2", + "xf86SetDDCproperties", + NULL +}; + + +static const char *i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + "xf86CreateI2CDevRec", + "xf86I2CDevInit", + "xf86I2CWriteRead", + "xf86DestroyI2CDevRec", + NULL +}; + +static const char *xaaSymbols[] = { + "XAACopyROP", + "XAACopyROP_PM", + "XAAPatternROP", + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAInit", + "XAAFillSolidRects", + NULL +}; + +static const char *int10Symbols[] = { + "xf86FreeInt10", + "xf86InitInt10", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +#ifdef USE_FB +static const char *fbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; +#else +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb24_32ScreenInit", + "cfb32ScreenInit", + "cfb16BresS", + "cfb24BresS", + NULL +}; +#endif + +#ifdef XFree86LOADER +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAddBufs", + "drmAddMap", + "drmAgpAcquire", + "drmAgpAlloc", + "drmAgpBase", + "drmAgpBind", + "drmAgpDeviceId", + "drmAgpEnable", + "drmAgpFree", + "drmAgpGetMode", + "drmAgpRelease", + "drmAgpVendorId", + "drmCtlInstHandler", + "drmCtlUninstHandler", + "drmCommandNone", + "drmCommandWrite", + "drmFreeVersion", + "drmGetInterruptFromBusID", + "drmGetLibVersion", + "drmGetVersion", + "drmMap", + "drmMapBufs", + "drmUnmap", + "drmUnmapBufs", + NULL +}; + +static const char *driSymbols[] = { + "DRICloseScreen", + "DRICreateInfoRec", + "DRIDestroyInfoRec", + "DRIFinishScreenInit", + "DRIGetSAREAPrivate", + "DRILock", + "DRIQueryVersion", + "DRIScreenInit", + "DRIUnlock", + "GlxSetVisualConfigs", + NULL +}; +#endif + +static MODULESETUPPROTO(VIASetup); + +static XF86ModuleVersionInfo VIAVersRec = { + "via", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +XF86ModuleData viaModuleData = {&VIAVersRec, VIASetup, NULL}; + + +static pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&VIA, module, 0); + LoaderRefSymLists(vgaHWSymbols, +#ifdef USE_FB + fbSymbols, +#else + cfbSymbols, +#endif + ramdacSymbols, + xaaSymbols, + shadowSymbols, + vbeSymbols, + i2cSymbols, + ddcSymbols, + /* + mpegSymbols, + */ +#ifdef XF86DRI + drmSymbols, + driSymbols, +#endif + NULL); + + return (pointer) 1; + } + else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + + return NULL; + } +} /* VIASetup */ + +#endif /* XFree86LOADER */ + +static void viaFillGraphicInfo(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + pVia->graphicInfo.TotalVRAM = pVia->videoRambytes; + pVia->graphicInfo.VideoHeapBase = (unsigned long) pVia->FBFreeStart; + pVia->graphicInfo.VideoHeapEnd = (unsigned long) (pVia->FBFreeEnd - 1); + pVia->graphicInfo.dwWidth = pBIOSInfo->CrtcHDisplay; + pVia->graphicInfo.dwHeight = pBIOSInfo->CrtcVDisplay; + pVia->graphicInfo.dwBPP = pScrn->bitsPerPixel; + pVia->graphicInfo.dwPitch = (((pScrn->virtualX) + 15) & ~15) * (pScrn->bitsPerPixel) / 8; + pVia->graphicInfo.dwRefreshRate = (unsigned long)pBIOSInfo->FoundRefresh; + pVia->graphicInfo.dwDVIOn = pBIOSInfo->DVIAttach; + pVia->graphicInfo.dwExpand = pBIOSInfo->scaleY; + pVia->graphicInfo.dwPanelWidth = pBIOSInfo->panelX; + pVia->graphicInfo.dwPanelHeight = pBIOSInfo->panelY; + pVia->graphicInfo.Cap0_Deinterlace = pVia->Cap0_Deinterlace; + pVia->graphicInfo.Cap1_Deinterlace = pVia->Cap1_Deinterlace; + pVia->graphicInfo.Cap0_FieldSwap = pVia->Cap0_FieldSwap; + pVia->graphicInfo.RevisionID = pVia->ChipRev; + + /* for SAMM mode passing screen info */ + pVia->graphicInfo.HasSecondary = pBIOSInfo->HasSecondary; + pVia->graphicInfo.IsSecondary = pBIOSInfo->IsSecondary; + + /* Added to pass DRM info to V4L */ +#ifdef XF86DRI + pVia->graphicInfo.DRMEnabled = pVia->directRenderingEnabled; +#endif +} + +static int +WaitIdleCLE266(VIAPtr pVia) +{ + int loop = 0; + + mem_barrier(); + + while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)) + ; + + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && + (loop++ < MAXLOOP)) + ; + + return loop >= MAXLOOP; +} + + +static Bool VIAGetRec(ScrnInfoPtr pScrn) +{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAGetRec\n")); + if (pScrn->driverPrivate) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(VIARec), 1); + ((VIARec *)(pScrn->driverPrivate))->pBIOSInfo = + xnfcalloc(sizeof(VIABIOSInfoRec), 1); + ((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->pModeTable = + xnfcalloc(sizeof(VIAModeTableRec), 1); + + /* initial value in VIARec */ + ((VIARec *)(pScrn->driverPrivate))->SavedReg.mode = 0xFF; + ((VIARec *)(pScrn->driverPrivate))->ModeReg.mode = 0xFF; + + ((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->FirstInit = TRUE; + + return TRUE; + +} /* VIAGetRec */ + + +static void VIAFreeRec(ScrnInfoPtr pScrn) +{ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAFreeRec\n")); + if (!pScrn->driverPrivate) + return; + + xfree(((VIARec *)(pScrn->driverPrivate))->pBIOSInfo->pModeTable); + xfree(((VIARec *)(pScrn->driverPrivate))->pBIOSInfo); + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; + + VIAUnmapMem(pScrn); + +} /* VIAFreeRec */ + + +static const OptionInfoRec * VIAAvailableOptions(int chipid, int busid) +{ + + return VIAOptions; + +} /* VIAAvailableOptions */ + + +static void VIAIdentify(int flags) +{ + xf86PrintChipsets(DRIVER_NAME, + "driver for VIA chipsets", + VIAChipsets); +} /* VIAIdentify */ + + +static Bool VIAProbe(DriverPtr drv, int flags) +{ + GDevPtr *devSections; + int *usedChips; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + int i; + + /* sanity checks */ + if ((numDevSections = xf86MatchDevice(DRIVER_NAME, &devSections)) <= 0) + return FALSE; + + if (xf86GetPciVideoInfo() == NULL) + return FALSE; + + numUsed = xf86MatchPciInstances(DRIVER_NAME, + PCI_VIA_VENDOR_ID, + VIAChipsets, + VIAPciChipsets, + devSections, + numDevSections, + drv, + &usedChips); + xfree(devSections); + + if (numUsed <= 0) + return FALSE; + + if (flags & PROBE_DETECT) { + foundScreen = TRUE; + } + else { + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + EntityInfoPtr pEnt; + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + VIAPciChipsets, 0, 0, 0, 0, 0))) + { + pScrn->driverVersion = VIA_VERSION; + pScrn->driverName = DRIVER_NAME; + pScrn->name = DRIVER_NAME; + pScrn->Probe = VIAProbe; + pScrn->PreInit = VIAPreInit; + pScrn->ScreenInit = VIAScreenInit; + pScrn->SwitchMode = VIASwitchMode; + pScrn->AdjustFrame = VIAAdjustFrame; + pScrn->EnterVT = VIAEnterVT; + pScrn->LeaveVT = VIALeaveVT; + pScrn->FreeScreen = VIAFreeScreen; + pScrn->ValidMode = VIAValidMode; + foundScreen = TRUE; + } + /* + xf86ConfigActivePciEntity(pScrn, + usedChips[i], + VIAPciChipsets, + NULL, + NULL, + NULL, + NULL, + NULL); + */ + + pEnt = xf86GetEntityInfo(usedChips[i]); + + /* CLE266 card support Dual-Head, mark the entity as sharable*/ + if(pEnt->chipset == VIA_CLE266 || pEnt->chipset == VIA_KM400) + { + static int instance = 0; + DevUnion* pPriv; + + xf86SetEntitySharable(usedChips[i]); + xf86SetEntityInstanceForScreen(pScrn, + pScrn->entityList[0], instance); + + if(gVIAEntityIndex < 0) + { + gVIAEntityIndex = xf86AllocateEntityPrivateIndex(); + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + + if (!pPriv->ptr) + { + VIAEntPtr pVIAEnt; + pPriv->ptr = xnfcalloc(sizeof(VIAEntRec), 1); + pVIAEnt = pPriv->ptr; + pVIAEnt->IsDRIEnabled = FALSE; + pVIAEnt->BypassSecondary = FALSE; + pVIAEnt->HasSecondary = FALSE; + pVIAEnt->IsSecondaryRestored = FALSE; + } + } + instance++; + } + xfree(pEnt); + } + } + + xfree(usedChips); + + return foundScreen; + +} /* VIAProbe */ + + +static int LookupChipID(PciChipsets* pset, int ChipID) +{ + /* Is there a function to do this for me? */ + while (pset->numChipset >= 0) + { + if (pset->PCIid == ChipID) + return pset->numChipset; + + pset++; + } + + return -1; + +} /* LookupChipID */ + + +static unsigned int +VIAddc1Read(ScrnInfoPtr pScrn) +{ + register vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + register CARD8 tmp; + + while (hwp->readST01(hwp)&0x8) {}; + while (!(hwp->readST01(hwp)&0x8)) {}; + + VGAOUT8(0x3c4, 0x26); + tmp = VGAIN8(0x3c5); + return ((unsigned int) ((tmp & 0x08) >> 3)); +} + +static Bool +VIAddc1(int scrnIndex) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + VIAPtr pVia = VIAPTR(pScrn); + xf86MonPtr pMon; + CARD8 tmp; + Bool success = FALSE; + + /* initialize chipset */ + VGAOUT8(0x3c4, 0x26); + tmp = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x26); + VGAOUT8(0x3c5, (tmp | 0x11)); + + if ((pMon = xf86PrintEDID( + xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,VIAddc1Read))) != NULL) + success = TRUE; + xf86SetDDCproperties(pScrn,pMon); + + /* undo initialization */ + VGAOUT8(0x3c4, 0x26); + VGAOUT8(0x3c5, tmp); + return success; +} + +static Bool +VIAddc2(int scrnIndex) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + VIAPtr pVia = VIAPTR(pScrn); + xf86MonPtr pMon; + CARD8 tmp; + Bool success = FALSE; + + VGAOUT8(0x3c4, 0x26); + tmp = VGAIN8(0x3c5); + pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pVia->I2C_Port1); + if (pMon) + success = TRUE; + pVia->DDC1 = pMon; + xf86PrintEDID(pMon); + xf86SetDDCproperties(pScrn, pMon); + VGAOUT8(0x3c4, 0x26); + VGAOUT8(0x3c5, tmp); + + return success; +} + +static void +VIAProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + } +} + + +static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags) +{ + EntityInfoPtr pEnt; + VIAPtr pVia; + VIABIOSInfoPtr pBIOSInfo; + MessageType from = X_DEFAULT; + ClockRangePtr clockRanges; + char *s = NULL; +#ifndef USE_FB + char *mod = NULL; + const char *reqSym = NULL; +#endif + vgaHWPtr hwp; + int i, bMemSize = 0, tmp; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAPreInit\n")); + + if (pScrn->numEntities > 1) + return FALSE; + + if (flags & PROBE_DETECT) + return FALSE; + + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + + xf86LoaderReqSymLists(vgaHWSymbols, NULL); + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + +#if 0 + /* Here we can alter the number of registers saved and restored by the + * standard vgaHWSave and Restore routines. + */ + vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, VGA_NUM_ATTR); +#endif + + if (!VIAGetRec(pScrn)) { + return FALSE; + } + + pVia = VIAPTR(pScrn); + pBIOSInfo = pVia->pBIOSInfo; + + pVia->IsSecondary = FALSE; + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (pEnt->resources) { + xfree(pEnt); + VIAFreeRec(pScrn); + return FALSE; + } + + pVia->EntityIndex = pEnt->index; + + if(xf86IsEntityShared(pScrn->entityList[0])) + { + if(xf86IsPrimInitDone(pScrn->entityList[0])) + { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + VIAPtr pVia1; + + pVia->IsSecondary = TRUE; + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVIAEnt = pPriv->ptr; + if(pVIAEnt->BypassSecondary) return FALSE; + pVIAEnt->pSecondaryScrn = pScrn; + pVIAEnt->HasSecondary = TRUE; + pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); + pVia1->HasSecondary = TRUE; + pVia->sharedData = pVia1->sharedData; + } + else + { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + + xf86SetPrimInitDone(pScrn->entityList[0]); + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec),1); + pVIAEnt = pPriv->ptr; + pVIAEnt->pPrimaryScrn = pScrn; + pVIAEnt->IsDRIEnabled = FALSE; + pVIAEnt->BypassSecondary = FALSE; + pVIAEnt->HasSecondary = FALSE; + pVIAEnt->RestorePrimary = FALSE; + pVIAEnt->IsSecondaryRestored = FALSE; + } + } else { + pVia->sharedData = xnfcalloc(sizeof(ViaSharedRec),1); + } + + if (flags & PROBE_DETECT) { + VIAProbeDDC(pScrn, pVia->EntityIndex); + return TRUE; + } + + pScrn->monitor = pScrn->confScreen->monitor; + + /* + * We support depths of 8, 16 and 24. + * We support bpp of 8, 16, and 32. + */ + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { + return FALSE; + } + else { + switch (pScrn->depth) { + case 8: + case 16: + case 24: + case 32: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + + xf86PrintDepthBpp(pScrn); + + if (pScrn->depth == 32) { + pScrn->depth = 24; + } + + if (pScrn->depth > 8) { + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) + return FALSE; + else { + /* TODO check weight returned is supported */ + ; + } + } + + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } + else { + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + } + + /* We use a programmable clock */ + pScrn->progClock = TRUE; + + xf86CollectOptions(pScrn, NULL); + + /* Set the bits per RGB for 8bpp mode */ + if (pScrn->depth == 8) + pScrn->rgbBits = 6; + + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, VIAOptions); + +#ifdef XF86DRI + pVia->drixinerama = FALSE; + if (xf86IsOptionSet(VIAOptions, OPTION_DRIXINERAMA)) + pVia->drixinerama = TRUE; +#else + if (xf86IsOptionSet(VIAOptions, OPTION_DRIXINERAMA)) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: drixinerama ignored, no DRI support compiled into driver.\n"); +#endif + if (xf86ReturnOptValBool(VIAOptions, OPTION_PCI_BURST, FALSE)) { + pVia->pci_burst = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: pci_burst - PCI burst read enabled\n"); + } + else { + pVia->pci_burst = FALSE; + } + + pVia->NoPCIRetry = 1; /* default */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_PCI_RETRY, FALSE)) { + if (xf86ReturnOptValBool(VIAOptions, OPTION_PCI_BURST, FALSE)) { + pVia->NoPCIRetry = 0; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_retry\n"); + } + else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\"pci_retry\" option requires \"pci_burst\"\n"); + } + } + + if (xf86IsOptionSet(VIAOptions, OPTION_SHADOW_FB)) { + pVia->shadowFB = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ShadowFB %s.\n", + pVia->shadowFB ? "enabled" : "disabled"); + } + else { + pVia->shadowFB = FALSE; + } + + if ((s = xf86GetOptValString(VIAOptions, OPTION_ROTATE))) { + if (!xf86NameCmp(s, "CW")) { + /* accel is disabled below for shadowFB */ + pVia->shadowFB = TRUE; + pVia->rotate = 1; + pVia->hwcursor = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } + else if(!xf86NameCmp(s, "CCW")) { + pVia->shadowFB = TRUE; + pVia->rotate = -1; + pVia->hwcursor = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" + "counter clockwise - acceleration disabled\n"); + } + else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" + "value for Option \"Rotate\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n"); + } + } + + if (xf86ReturnOptValBool(VIAOptions, OPTION_NOACCEL, FALSE)) { + pVia->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: NoAccel -Acceleration Disabled\n"); + } + else { + pVia->NoAccel = FALSE; + } + + if (pVia->shadowFB && !pVia->NoAccel) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "HW acceleration not supported with \"shadowFB\".\n"); + pVia->NoAccel = TRUE; + } + + /* + * The SWCursor setting takes priority over HWCursor. The default + * if neither is specified is HW. + */ + + from = X_DEFAULT; + pVia->hwcursor = pVia->shadowFB ? FALSE : TRUE; + if (xf86GetOptValBool(VIAOptions, OPTION_HWCURSOR, &pVia->hwcursor)) + from = X_CONFIG; + + if (xf86ReturnOptValBool(VIAOptions, OPTION_SWCURSOR, FALSE)) { + pVia->hwcursor = FALSE; + from = X_CONFIG; + } + + if (pVia->IsSecondary) pVia->hwcursor = FALSE; + + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pVia->hwcursor ? "HW" : "SW"); + + if (xf86ReturnOptValBool(VIAOptions, OPTION_A2, FALSE)) { + pBIOSInfo->A2 = TRUE; + } + else { + pBIOSInfo->A2 = FALSE; + } + + from = X_DEFAULT; + if (xf86ReturnOptValBool(VIAOptions, OPTION_USEBIOS, FALSE)) { + from = X_CONFIG; + pBIOSInfo->UseBIOS = TRUE; + } + else { + pBIOSInfo->UseBIOS = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, "%ssing video BIOS to set modes\n", + pBIOSInfo->UseBIOS ? "U" : "Not u" ); + + pScrn->videoRam = 0; + if(xf86GetOptValInteger(VIAOptions, OPTION_VIDEORAM, &pScrn->videoRam)) { + xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, + "Option: VideoRAM %dkB\n", pScrn->videoRam ); + } + + if (xf86ReturnOptValBool(VIAOptions, OPTION_DISABLEVQ, FALSE)) { + pVia->VQEnable = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: DisableVQ -VQ Disabled\n"); + } + else { + pVia->VQEnable = TRUE; + } + + /* ActiveDevice Option for device selection */ + pBIOSInfo->ActiveDevice = 0x00; + if ((s = xf86GetOptValString(VIAOptions, OPTION_ACTIVEDEVICE))) { + if (!xf86NameCmp(s, "CRT,TV") || !xf86NameCmp(s, "TV,CRT")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_TV; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and TV.\n"); + } + else if(!xf86NameCmp(s, "CRT,LCD") || !xf86NameCmp(s, "LCD,CRT")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_LCD; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and LCD.\n"); + } + else if(!xf86NameCmp(s, "CRT,DFP") || !xf86NameCmp(s, "DFP,CRT") + || !xf86NameCmp(s, "CRT,DVI") || !xf86NameCmp(s, "DVI,CRT")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_DFP; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and DFP.\n"); + } + else if(!xf86NameCmp(s, "TV,DFP") || !xf86NameCmp(s, "DFP,TV") + || !xf86NameCmp(s, "TV,DVI") || !xf86NameCmp(s, "DVI,TV")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_TV | VIA_DEVICE_DFP; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is TV and DFP.\n"); + } +#if 0 + else if(!xf86NameCmp(s, "DFP,LCD") || !xf86NameCmp(s, "LCD,DFP") + || !xf86NameCmp(s, "LCD,DVI") || !xf86NameCmp(s, "DVI,LCD")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_DFP | VIA_DEVICE_LCD; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is DFP and LCD.\n"); + } +#endif + else if(!xf86NameCmp(s, "CRT") || !xf86NameCmp(s, "CRT ONLY")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT Only.\n"); + } + else if(!xf86NameCmp(s, "LCD") || !xf86NameCmp(s, "LCD ONLY")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_LCD; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is LCD Only.\n"); + } + else if(!xf86NameCmp(s, "TV") || !xf86NameCmp(s, "TV ONLY")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_TV; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is TV Only.\n"); + } + else if(!xf86NameCmp(s, "DFP") || !xf86NameCmp(s, "DFP ONLY") + || !xf86NameCmp(s, "DVI") || !xf86NameCmp(s, "DVI ONLY")) { + pBIOSInfo->ActiveDevice = VIA_DEVICE_DFP; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is DFP Only.\n"); + } + else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option \"%s\" can't recognize!, Active Device by default.\n", s); + } + } + + /* NoDDCValue Option */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_NODDCVALUE, FALSE)) { + pVia->NoDDCValue = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: Not using DDC probed value to set HorizSync & VertRefresh\n"); + } + else { + pVia->NoDDCValue = FALSE; + } + + /* LCDDualEdge Option */ + pBIOSInfo->LCDDualEdge = FALSE; + if (xf86ReturnOptValBool(VIAOptions, OPTION_LCDDUALEDGE, FALSE)) { + pBIOSInfo->LCDDualEdge = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: Using Dual Edge mode to set LCD\n"); + } + else { + pBIOSInfo->LCDDualEdge = FALSE; + } + + /* Digital Output Bus Width Option */ + pBIOSInfo->BusWidth = VIA_DI_12BIT; + if ((s = xf86GetOptValString(VIAOptions, OPTION_BUSWIDTH))) { + if (!xf86NameCmp(s, "12BIT")) { + pBIOSInfo->BusWidth = VIA_DI_12BIT; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Digital Output Bus Width is 12BIT\n"); + } + else if (!xf86NameCmp(s, "24BIT")) { + pBIOSInfo->BusWidth = VIA_DI_24BIT; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Digital Output Bus Width is 24BIT\n"); + } + } + + /* LCD Center/Expend Option */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_CENTER, FALSE)) { + pBIOSInfo->Center = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DVI Center is On\n"); + } + else { + pBIOSInfo->Center = FALSE; + } + + /* Panel Size Option */ + pBIOSInfo->PanelSize = VIA_PANEL_INVALID; + if ((s = xf86GetOptValString(VIAOptions, OPTION_PANELSIZE))) { + if (!xf86NameCmp(s, "640x480")) { + pBIOSInfo->PanelSize = VIA_PANEL6X4; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 640x480\n"); + } + else if (!xf86NameCmp(s, "800x600")) { + pBIOSInfo->PanelSize = VIA_PANEL8X6; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 800x600\n"); + } + else if(!xf86NameCmp(s, "1024x768")) { + pBIOSInfo->PanelSize = VIA_PANEL10X7; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1024x768\n"); + } + else if (!xf86NameCmp(s, "1280x768")) { + pBIOSInfo->PanelSize = VIA_PANEL12X7; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1280x768\n"); + } + else if (!xf86NameCmp(s, "1280x1024")) { + pBIOSInfo->PanelSize = VIA_PANEL12X10; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1280x1024\n"); + } + else if (!xf86NameCmp(s, "1400x1050")) { + pBIOSInfo->PanelSize = VIA_PANEL14X10; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Selected Panel Size is 1400x1050\n"); + } + } + + /* TV DotCrawl Enable Option */ + if (xf86ReturnOptValBool(VIAOptions, OPTION_TVDOTCRAWL, FALSE)) { + pBIOSInfo->TVDotCrawl = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DotCrawl is Enable\n"); + } + else { + pBIOSInfo->TVDotCrawl = FALSE; + } + + pBIOSInfo->TVType = TVTYPE_NONE; + if ((s = xf86GetOptValString(VIAOptions, OPTION_TVTYPE))) { + if (!xf86NameCmp(s, "NTSC")) { + pBIOSInfo->TVType = TVTYPE_NTSC; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is NTSC\n"); + } + else if(!xf86NameCmp(s, "PAL")) { + pBIOSInfo->TVType = TVTYPE_PAL; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Type is PAL\n"); + } + } + + /* TV out put signal Option */ + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + if ((s = xf86GetOptValString(VIAOptions, OPTION_TVOUTPUT))) { + if (!xf86NameCmp(s, "S-Video")) { + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is S-Video\n"); + } + else if(!xf86NameCmp(s, "Composite")) { + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is Composite\n"); + } + else if(!xf86NameCmp(s, "SC")) { + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is SC\n"); + } + else if(!xf86NameCmp(s, "RGB")) { + pBIOSInfo->TVOutput = TVOUTPUT_RGB; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is RGB\n"); + } + else if(!xf86NameCmp(s, "YCbCr")) { + pBIOSInfo->TVOutput = TVOUTPUT_YCBCR; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Output Signal is YCbCr\n"); + } + } + + /* TV Standard Option */ + pBIOSInfo->TVVScan = VIA_TVNORMAL; + if ((s = xf86GetOptValString(VIAOptions, OPTION_TVVSCAN))) { + if (!xf86NameCmp(s, "under")) { + pBIOSInfo->TVVScan = VIA_TVNORMAL; + } + else if (!xf86NameCmp(s, "over")) { + pBIOSInfo->TVVScan = VIA_TVOVER; + } + } + + pBIOSInfo->TVHScale = VIA_NO_TVHSCALE; + if ((s = xf86GetOptValString(VIAOptions, OPTION_TVHSCALE))) { +#if 0 + if (!xf86NameCmp(s, "0")) { + pBIOSInfo->TVHScale = VIA_TVHSCALE0; + } + else if (!xf86NameCmp(s, "1")) { + pBIOSInfo->TVHScale = VIA_TVHSCALE1; + } + else if(!xf86NameCmp(s, "2")) { + pBIOSInfo->TVHScale = VIA_TVHSCALE2; + } + else if (!xf86NameCmp(s, "3")) { + pBIOSInfo->TVHScale = VIA_TVHSCALE3; + } + else if (!xf86NameCmp(s, "4")) { + pBIOSInfo->TVHScale = VIA_TVHSCALE4; + } +#endif + } + + /* TV Encoder Type Option */ + pBIOSInfo->TVEncoder = VIA_NONETV; + if ((s = xf86GetOptValString(VIAOptions, OPTION_TVENCODER))) { + if (!xf86NameCmp(s, "VT1621")) { + pBIOSInfo->TVEncoder = VIA_TV2PLUS; + pBIOSInfo->TVI2CAdd = 0x40; + } + else if(!xf86NameCmp(s, "VT1622")) { + pBIOSInfo->TVEncoder = VIA_TV3; + pBIOSInfo->TVI2CAdd = 0x40; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Encoder is VT1622!\n"); + } + else if(!xf86NameCmp(s, "VT1622A")) { + pBIOSInfo->TVEncoder = VIA_VT1622A; + pBIOSInfo->TVI2CAdd = 0x40; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Encoder is VT1622!\n"); + } + else if(!xf86NameCmp(s, "CH7019")) { + pBIOSInfo->TVEncoder = VIA_CH7019; + pBIOSInfo->TVI2CAdd = 0xEA; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Encoder is CH7019!\n"); + } + else if(!xf86NameCmp(s, "SAA7108")) { + pBIOSInfo->TVEncoder = VIA_SAA7108; + pBIOSInfo->TVI2CAdd = 0x88; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Encoder is SAA7108!\n"); + } + else if(!xf86NameCmp(s, "FS454")) { + pBIOSInfo->TVEncoder = VIA_FS454; + pBIOSInfo->TVI2CAdd = 0xD4; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TV Encoder is FS453/FS454!\n"); + } + } + + if (xf86GetOptValInteger(VIAOptions, OPTION_REFRESH, &(pBIOSInfo->OptRefresh))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Refresh is %d\n", pBIOSInfo->OptRefresh); + } + + if (xf86LoadSubModule(pScrn, "int10")) { + xf86LoaderReqSymLists(int10Symbols, NULL); + pVia->pInt10 = xf86InitInt10(pEnt->index); + } + + if (pVia->pInt10 && xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); + pVia->pVbe = VBEInit(pVia->pInt10, pVia->EntityIndex); + } + + pVia->PciInfo = xf86GetPciInfoForEntity(pEnt->index); + xf86RegisterResources(pEnt->index, NULL, ResNone); + /* + xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr); + */ + + if (pEnt->device->chipset && *pEnt->device->chipset) { + pScrn->chipset = pEnt->device->chipset; + pVia->ChipId = pEnt->device->chipID; + pVia->Chipset = xf86StringToToken(VIAChipsets, pScrn->chipset); + from = X_CONFIG; + } else if (pEnt->device->chipID >= 0) { + pVia->ChipId = pEnt->device->chipID; + pVia->Chipset = LookupChipID(VIAPciChipsets, pVia->ChipId); + pScrn->chipset = (char *)xf86TokenToString(VIAChipsets, + pVia->Chipset); + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + pEnt->device->chipID); + } else { + from = X_PROBED; + pVia->ChipId = pVia->PciInfo->chipType; + pVia->Chipset = LookupChipID(VIAPciChipsets, pVia->ChipId); + pScrn->chipset = (char *)xf86TokenToString(VIAChipsets, + pVia->Chipset); + } + + if (pEnt->device->chipRev >= 0) { + pVia->ChipRev = pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pVia->ChipRev); + } + else { + /*pVia->ChipRev = pVia->PciInfo->chipRev;*/ + /* Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip rev. */ + pVia->ChipRev = pciReadByte(pciTag(0, 0, 0), 0xF6); + } + + if (pEnt->device->videoRam != 0) { + if (!pScrn->videoRam) + pScrn->videoRam = pEnt->device->videoRam; + else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video Memory Size in Option is %d KB, Detect is %d KB!", + pScrn->videoRam, pEnt->device->videoRam); + } + } + pBIOSInfo->Chipset = pVia->Chipset; + pBIOSInfo->ChipRev = pVia->ChipRev; + + xfree(pEnt); + + VIAvfInitHWDiff(pVia); + + /* maybe throw in some more sanity checks here */ + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); + + pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device, + pVia->PciInfo->func); + + switch (pVia->ChipRev) { + case 2: + pBIOSInfo->A2 = TRUE; + break; + default: + pBIOSInfo->A2 = FALSE; + break; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset Rev.: %d\n", pVia->ChipRev); + + hwp = VGAHWPTR(pScrn); + vgaHWGetIOBase(hwp); + + if (!VIAMapMMIO(pScrn)) { + vbeFree(pVia->pVbe); + return FALSE; + } + + /* Get BIOS ver. From BIOS Call Function */ + tmp = VIABIOS_GetBIOSVersion(pScrn); + pBIOSInfo->BIOSMajorVersion = tmp >> 8; + pBIOSInfo->BIOSMinorVersion = tmp & 0xFF; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS Version is = %d.%d\n", pBIOSInfo->BIOSMajorVersion, pBIOSInfo->BIOSMinorVersion)); + VIABIOS_GetBIOSDate(pScrn); + + if (pBIOSInfo->TVType == TVTYPE_NONE) { + /* use jumper to determine TV Type */ + VGAOUT8(0x3D4, 0x3B); + if (VGAIN8(0x3D5) & 0x02) { + pBIOSInfo->TVType = TVTYPE_PAL; + } + else { + pBIOSInfo->TVType = TVTYPE_NTSC; + } + } + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) { + vbeFree(pVia->pVbe); + return FALSE; + } + } + + /* Next go on to detect amount of installed ram */ + if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { + bMemSize = VIABIOS_GetVideoMemSize(pScrn); + if (bMemSize) { + pScrn->videoRam = bMemSize << 6; + } + else { + VGAOUT8(0x3C4, 0x34); /* Was 0x39 */ + bMemSize = VGAIN8(0x3c5); + if (bMemSize > 16 && bMemSize <= 128) { + pScrn->videoRam = (bMemSize + 1) << 9; + } + else if (bMemSize > 0 && bMemSize < 31){ + pScrn->videoRam = bMemSize << 12; + } + else { + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "bMemSize = %d\nGet Video Memory Size by default.\n", bMemSize)); + pScrn->videoRam = VIAGetMemSize(); + } + } + } + + /* Split FB for SAMM */ + /* FIXME: For now, split FB into two equal sections. This should + * be able to be adjusted by user with a config option. */ + if (pVia->IsSecondary) { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + VIAPtr pVia1; + + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVIAEnt = pPriv->ptr; + pScrn->videoRam = pScrn->videoRam >> 1; + pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam; + pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); + pVia1->videoRambytes = pScrn->videoRam << 10; + pVia->FrameBufferBase += (pScrn->videoRam << 10); + } + + pVia->videoRambytes = pScrn->videoRam << 10; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED,"videoram = %dk\n", + pScrn->videoRam); + + /* Set status word positions based on chip type. */ + + switch (pVia->Chipset) { + case VIA_CLE266: + pVia->myWaitIdle = WaitIdleCLE266; + break; + default: + pVia->myWaitIdle = WaitIdleCLE266; + break; + } + + if (!xf86LoadSubModule(pScrn, "i2c")) { + VIAFreeRec(pScrn); + return FALSE; + } + else { + xf86LoaderReqSymLists(i2cSymbols,NULL); + VIAI2CInit(pScrn); + } + + if (!xf86LoadSubModule(pScrn, "ddc")) { + VIAFreeRec(pScrn); + return FALSE; + } + else { + xf86MonPtr pMon = NULL; + + xf86LoaderReqSymLists(ddcSymbols, NULL); + if ((pVia->pVbe) + && ((pMon = xf86PrintEDID(vbeDoEDID(pVia->pVbe, NULL))) != NULL)) { + pVia->DDC1 = pMon; + xf86SetDDCproperties(pScrn,pMon); + } + else if (!VIAddc2(pScrn->scrnIndex)) { + VIAddc1(pScrn->scrnIndex); + } + } + + /* Reset HorizSync & VertRefresh Rang Using DDC Value */ + if (pVia->DDC1 && !pVia->NoDDCValue) { + int i; + int h = 0; + int v = 0; + + for (i = 0; i < DET_TIMINGS; i++) { + if (pVia->DDC1->det_mon[i].type == DS_RANGES) { + pScrn->monitor->hsync[h].lo + = pVia->DDC1->det_mon[i].section.ranges.min_h; + pScrn->monitor->hsync[h++].hi + = pVia->DDC1->det_mon[i].section.ranges.max_h; + pScrn->monitor->vrefresh[v].lo + = pVia->DDC1->det_mon[i].section.ranges.min_v; + pScrn->monitor->vrefresh[v++].hi + = pVia->DDC1->det_mon[i].section.ranges.max_v; + break; + } + } + pScrn->monitor->nHsync = h; + pScrn->monitor->nVrefresh = v; + } + + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ + + clockRanges = xnfalloc(sizeof(ClockRange)); + clockRanges->next = NULL; + clockRanges->minClock = 20000; + clockRanges->maxClock = 230000; + + clockRanges->clockIndex = -1; + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = FALSE; + + + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our VIAValidMode() already takes + * care of this, we don't worry about setting them here. + */ + + /* Select valid modes from those available */ + i = xf86ValidateModes(pScrn, + pScrn->monitor->Modes, /* availModes */ + pScrn->display->modes, /* modeNames */ + clockRanges, /* list of clock ranges */ + NULL, /* list of line pitches */ + 256, /* mini line pitch */ + 2048, /* max line pitch */ + 16 * pScrn->bitsPerPixel, /* pitch inc (bits) */ + 128, /* min height */ + 2048, /* max height */ + pScrn->display->virtualX, /* virtual width */ + pScrn->display->virtualY, /* virutal height */ + pVia->videoRambytes, /* size of video memory */ + LOOKUP_BEST_REFRESH); /* lookup mode flags */ + + if (i == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86ValidateModes failure\n"); + VIAFreeRec(pScrn); + return FALSE; + } + + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + VIAFreeRec(pScrn); + return FALSE; + } + + /* Set up screen parameters. */ + pVia->Bpp = pScrn->bitsPerPixel >> 3; + pVia->Bpl = pScrn->displayWidth * pVia->Bpp; + + if (!VIAGetBIOSTable(pBIOSInfo)) { + VIAFreeRec(pScrn); + return FALSE; + } + + pBIOSInfo->I2C_Port1 = pVia->I2C_Port1; + pBIOSInfo->I2C_Port2 = pVia->I2C_Port2; + pBIOSInfo->DDC1 = pVia->DDC1; + pBIOSInfo->DDC2 = pVia->DDC2; + + /* Detect TV Encoder */ + if (!pBIOSInfo->TVEncoder) { + pBIOSInfo->TVEncoder = VIACheckTVExist(pBIOSInfo); + } + /* Detect TMDS/LVDS Encoder */ + VIAPostDVI(pBIOSInfo); + /*VIAGetPanelInfo(pBIOSInfo);*/ + pBIOSInfo->ConnectedDevice = VIAGetDeviceDetect(pBIOSInfo); + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + pScrn->currentMode = pScrn->modes; + xf86PrintModes(pScrn); + xf86SetDpi(pScrn, 0, 0); + +#ifdef USE_FB + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + VIAFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(fbSymbols, NULL); + +#else + /* load bpp-specific modules */ + switch (pScrn->bitsPerPixel) { + case 8: + mod = "cfb"; + reqSym = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + reqSym = "cfb16ScreenInit"; + break; + case 32: + mod = "cfb32"; + reqSym = "cfb32ScreenInit"; + break; + } + + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + VIAFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymbols(reqSym, NULL); +#endif + + if (!pVia->NoAccel) { + if(!xf86LoadSubModule(pScrn, "xaa")) { + VIAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(xaaSymbols, NULL); + } + + if (pVia->hwcursor) { + if (!xf86LoadSubModule(pScrn, "ramdac")) { + VIAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ramdacSymbols, NULL); + } + + if (pVia->shadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + VIAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + /* Capture option parameter */ + pVia->Cap0_Deinterlace = CAP_BOB; + if ((s = xf86GetOptValString(VIAOptions, OPTION_CAP0_DEINTERLACE))) { + if (!xf86NameCmp(s, "Bob")) { + pVia->Cap0_Deinterlace = CAP_BOB; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Capture 0 de-interlace mode is Bob\n"); + } + else if(!xf86NameCmp(s, "Weave")) { + pVia->Cap0_Deinterlace = CAP_WEAVE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Capture 0 de-interlace mode is Weave\n"); + } + } + + pVia->Cap1_Deinterlace = CAP_BOB; + if ((s = xf86GetOptValString(VIAOptions, OPTION_CAP1_DEINTERLACE))) { + if (!xf86NameCmp(s, "Bob")) { + pVia->Cap1_Deinterlace = CAP_BOB; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Capture 1 de-interlace mode is Bob\n"); + } + else if(!xf86NameCmp(s, "Weave")) { + pVia->Cap1_Deinterlace = CAP_WEAVE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Capture 1 de-interlace mode is Weave\n"); + } + } + + if (xf86ReturnOptValBool(VIAOptions, OPTION_CAP0_FIELDSWAP, FALSE)) { + pVia->Cap0_FieldSwap = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: Cap0_FieldSwap Enabled\n"); + } + else { + pVia->Cap0_FieldSwap = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Option: Cap0_FieldSwap Disabled\n"); + } + + /* xf86LoaderReqSymLists(mpegSymbols, NULL); */ + + VIADeviceSelection(pScrn); + if (pVia->IsSecondary) { + if (pBIOSInfo->SAMM) + VIADeviceDispatch(pScrn); + else + return FALSE; + } + + VIAUnmapMem(pScrn); + + return TRUE; +} + + +static Bool VIAEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + VIAPtr pVia = VIAPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + Bool ret; + + /* FIXME: Rebind AGP memory here */ + /* FIXME: Unlock DRI here */ + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAEnterVT\n")); + VIASave(pScrn); + vgaHWUnlock(hwp); + + ret = VIAModeInit(pScrn, pScrn->currentMode); + + /* Patch for APM suspend resume, HWCursor has garbage */ + if (pVia->hwcursor && pVia->CursorImage) { + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "Restore Cursor Image!\n")); + memcpy(pVia->FBBase + pVia->CursorStart, pVia->CursorImage, 0x1000); + VIASETREG(VIA_REG_CURSOR_FG, pVia->CursorFG); + VIASETREG(VIA_REG_CURSOR_BG, pVia->CursorBG); + VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorMC); + xfree(pVia->CursorImage); + /*VIALoadCursorImage(pScrn, *pVia->CursorImage);*/ + } + + /* retore video status */ + if (!pVia->IsSecondary) + viaRestoreVideo(pScrn); + + VIAAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return ret; +} + + +static void VIALeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + vgaRegPtr vgaSavePtr = &hwp->SavedReg; + VIARegPtr viaSavePtr = &pVia->SavedReg; + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIALeaveVT\n")); + + /* FIXME: take the DRI lock here to avoid accidents */ + /* FIXME: unbind the AGP memory ? */ + + /* Wait Hardware Engine idle to exit graphicd mode */ + WaitIdle(); + + if (pVia->VQEnable) { + /* if we use VQ, disable it before we exit */ + VIASETREG(0x43c, 0x00fe0000); + VIASETREG(0x440, 0x00000004); + } + + /* Save video status and turn off all video activities */ + if (!pVia->IsSecondary) + viaSaveVideo(pScrn); + + if (pVia->hwcursor) { + pVia->CursorImage = xcalloc(1, 0x1000); + memcpy(pVia->CursorImage, pVia->FBBase + pVia->CursorStart, 0x1000); + pVia->CursorFG = (CARD32)VIAGETREG(VIA_REG_CURSOR_FG); + pVia->CursorBG = (CARD32)VIAGETREG(VIA_REG_CURSOR_BG); + pVia->CursorMC = (CARD32)VIAGETREG(VIA_REG_CURSOR_MODE); + } + + VIAWriteMode(pScrn, vgaSavePtr, viaSavePtr); + vgaHWLock(hwp); +} + + +static void VIASave(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + vgaRegPtr vgaSavePtr = &hwp->SavedReg; + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + VIARegPtr save = &pVia->SavedReg; + int vgaCRIndex, vgaCRReg, vgaIOBase; + int i; + I2CDevPtr dev; + unsigned char W_Buffer[1]; + unsigned char TVRegs[0xFF]; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIASave\n")); + + if(pVia->IsSecondary) + { + DevUnion* pPriv; + VIAEntPtr pVIAEnt; + VIAPtr pVia1; + vgaHWPtr hwp1; + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gVIAEntityIndex); + pVIAEnt = pPriv->ptr; + hwp1 = VGAHWPTR(pVIAEnt->pPrimaryScrn); + pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); + hwp->SavedReg = hwp1->SavedReg; + pVia->SavedReg = pVia1->SavedReg; + } + else { + vgaHWProtect(pScrn, TRUE); + + if (xf86IsPrimaryPci(pVia->PciInfo)) { + vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL); + } + else { + vgaHWSave(pScrn, vgaSavePtr, VGA_SR_MODE); + } + + vgaIOBase = hwp->IOBase; + vgaCRReg = vgaIOBase + 5; + vgaCRIndex = vgaIOBase + 4; + + /* Unlock Extended Regs */ + outb(0x3c4, 0x10); + outb(0x3c5, 0x01); + + VGAOUT8(0x3c4, 0x14); + save->SR14 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x15); + save->SR15 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x16); + save->SR16 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x17); + save->SR17 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x18); + save->SR18 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x19); + save->SR19 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x1a); + save->SR1A = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x1b); + save->SR1B = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x1c); + save->SR1C = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x1d); + save->SR1D = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x1e); + save->SR1E = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x1f); + save->SR1F = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x22); + save->SR22 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x23); + save->SR23 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x24); + save->SR24 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x25); + save->SR25 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x26); + save->SR26 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x27); + save->SR27 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x28); + save->SR28 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x29); + save->SR29 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x2a); + save->SR2A = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x2b); + save->SR2B = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x2e); + save->SR2E = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x44); + save->SR44 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x45); + save->SR45 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x46); + save->SR46 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x47); + save->SR47 = VGAIN8(0x3c5); + + VGAOUT8(vgaCRIndex, 0x13); + save->CR13 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x32); + save->CR32 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x33); + save->CR33 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x34); + save->CR34 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x35); + save->CR35 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x36); + save->CR36 = VGAIN8(vgaCRReg); + + /* Saving TV register status before set mode */ + switch (pBIOSInfo->TVEncoder) { + case VIA_NONETV: + break; + case VIA_VT1623: + VIAGPIOI2C_Initial(pBIOSInfo, 0x40); + for (i = 0; i < 0x6C; i++) { + VIAGPIOI2C_ReadByte(pBIOSInfo, i, (TVRegs + i)); + save->TVRegs[i] = TVRegs[i]; + /*DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Save TV Register[%d]0x%X\n", i, save->TVRegs[i]));*/ + } + break; + default: + if (xf86I2CProbeAddress(pVia->I2C_Port2, pBIOSInfo->TVI2CAdd)) { + dev = xf86CreateI2CDevRec(); + dev->DevName = "TV"; + dev->SlaveAddr = pBIOSInfo->TVI2CAdd; + dev->pI2CBus = pVia->I2C_Port2; + + if (xf86I2CDevInit(dev)) { + W_Buffer[0] = 0; + xf86I2CWriteRead(dev, W_Buffer,1, TVRegs, 0xFF); + for (i = 0; i < 0xFF; i++) { + save->TVRegs[i] = TVRegs[i]; + } + xf86DestroyI2CDevRec(dev,TRUE); + } + else + xf86DestroyI2CDevRec(dev,TRUE); + } + break; + } + + /* Saving LVDS register status before set mode + if (pBIOSInfo->LVDS == VIA_CH7019LVDS) { + dev = xf86CreateI2CDevRec(); + dev->DevName = "LVDS"; + dev->SlaveAddr = 0xEA; + dev->pI2CBus = pVia->I2C_Port2; + + if (xf86I2CDevInit(dev)) { + for (i = 0; i < 0x40; i++) { + W_Buffer[0] = i + 0x40; + xf86I2CWriteRead(dev, W_Buffer, 1, save->LCDRegs + i, 1); + } + xf86DestroyI2CDevRec(dev,TRUE); + } + else + xf86DestroyI2CDevRec(dev,TRUE); + }*/ + + /* Save LCD control regs */ + for (i = 0; i < 68; i++) { + VGAOUT8(vgaCRIndex, i + 0x50); + save->CRTCRegs[i] = VGAIN8(vgaCRReg); + } + + if (!pVia->ModeStructInit) { + vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); + memcpy(&pVia->ModeReg, save, sizeof(VIARegRec)); + pVia->ModeStructInit = TRUE; + } + vgaHWProtect(pScrn, FALSE); + } + return; +} + + +static void VIAWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, + VIARegPtr restore) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + int vgaCRIndex, vgaCRReg, vgaIOBase; +/* Bool graphicsMode = FALSE;*/ + int i; + unsigned char W_Buffer[3]; + I2CDevPtr dev = NULL; + CARD8 tmp + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAWriteMode\n")); + vgaIOBase = hwp->IOBase; + vgaCRIndex = vgaIOBase + 4; + vgaCRReg = vgaIOBase + 5; + + /* + * If we figured out a VESA mode number for this timing, just use + * the VGA BIOS to do the switching, with a few additional tweaks. + */ + if (restore->mode != 0xFF) + { + /* Set up the mode. Don't clear video RAM. */ + if (!pVia->IsSecondary) + VIASetModeUseBIOSTable(pBIOSInfo); + else + VIASetModeForMHS(pBIOSInfo); + + /* Restore the DAC.*/ + if (pBIOSInfo->FirstInit ) { + vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_CMAP); + } + /*else { + vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_MODE); + } + vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_CMAP);*/ + pBIOSInfo->FirstInit = FALSE; + /* Enable the graphics engine. */ + if (!pVia->NoAccel) + VIAInitialize2DEngine(pScrn); + +#ifdef XF86DRI + VIAInitialize3DEngine(pScrn); +#endif + return; + } + vgaHWProtect(pScrn, TRUE); + /* Unlock Extended Regs */ + outb(0x3c4, 0x10); + outb(0x3c5, 0x01); + + /* How can we know the mode is graphical mode or not ? */ + /* graphicsMode = (restore->mode == 0xFF) ? FALSE : TRUE; */ + + VGAOUT8(vgaCRIndex, 0x6a); + VGAOUT8(vgaCRReg, 0); + VGAOUT8(vgaCRIndex, 0x6b); + VGAOUT8(vgaCRReg, 0); + VGAOUT8(vgaCRIndex, 0x6c); + VGAOUT8(vgaCRReg, 0); + + switch (pBIOSInfo->TVEncoder) { + case VIA_TV2PLUS: + case VIA_TV3: + case VIA_CH7009: + case VIA_CH7019: + case VIA_SAA7108: + case VIA_CH7005: + case VIA_VT1622A: + dev = xf86CreateI2CDevRec(); + dev->DevName = "TV"; + dev->SlaveAddr = pBIOSInfo->TVI2CAdd; + dev->pI2CBus = pVia->I2C_Port2; + if (xf86I2CDevInit(dev)) { + for (i = 0; i < 0xFF; i++) { + W_Buffer[0] = (unsigned char)(i); + W_Buffer[1] = (unsigned char)(restore->TVRegs[i]); + xf86I2CWriteRead(dev, W_Buffer, 2, NULL,0); + } + xf86DestroyI2CDevRec(dev,TRUE); + } + else + xf86DestroyI2CDevRec(dev,TRUE); + break; + case VIA_FS454: + dev = xf86CreateI2CDevRec(); + dev->DevName = "TV"; + dev->SlaveAddr = pBIOSInfo->TVI2CAdd; + dev->pI2CBus = pVia->I2C_Port2; + if (xf86I2CDevInit(dev)) { + + /* QPR programming */ + W_Buffer[0] = 0xC4; + W_Buffer[1] = (unsigned char)(restore->TVRegs[0xC4]); + W_Buffer[2] = (unsigned char)(restore->TVRegs[0xC5]); + xf86I2CWriteRead(dev, W_Buffer,3, NULL,0); + + /* Restore TV Regs */ + for (i = 0; i < 0xFF; i++) { + W_Buffer[0] = (unsigned char)(i); + W_Buffer[1] = (unsigned char)(restore->TVRegs[i]); + if (i == 0xC4) + i++; + else + xf86I2CWriteRead(dev, W_Buffer, 2, NULL,0); + } + xf86DestroyI2CDevRec(dev,TRUE); + } + else + xf86DestroyI2CDevRec(dev,TRUE); + break; + case VIA_VT1623: + VIAGPIOI2C_Initial(pBIOSInfo, 0x40); + for (i = 0; i < 0x6C; i++) { + VIAGPIOI2C_Write(pBIOSInfo, i, restore->TVRegs[i]); + /*DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Write Back Register[%d]:0x%X\n", i, restore->TVRegs[i]));*/ + } + break; + default: + break; + } + + /* restore the standard vga regs */ + if (xf86IsPrimaryPci(pVia->PciInfo)) + vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); + else + vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_MODE); + + /* restore extended regs */ + VGAOUT8(0x3c4, 0x14); + VGAOUT8(0x3c5, restore->SR14); + VGAOUT8(0x3c4, 0x15); + VGAOUT8(0x3c5, restore->SR15); + VGAOUT8(0x3c4, 0x16); + VGAOUT8(0x3c5, restore->SR16); + VGAOUT8(0x3c4, 0x17); + VGAOUT8(0x3c5, restore->SR17); + VGAOUT8(0x3c4, 0x18); + VGAOUT8(0x3c5, restore->SR18); + VGAOUT8(0x3c4, 0x19); + VGAOUT8(0x3c5, restore->SR19); + VGAOUT8(0x3c4, 0x1a); + VGAOUT8(0x3c5, restore->SR1A); + VGAOUT8(0x3c4, 0x1b); + VGAOUT8(0x3c5, restore->SR1B); + VGAOUT8(0x3c4, 0x1c); + VGAOUT8(0x3c5, restore->SR1C); + VGAOUT8(0x3c4, 0x1d); + VGAOUT8(0x3c5, restore->SR1D); + VGAOUT8(0x3c4, 0x1e); + VGAOUT8(0x3c5, restore->SR1E); + VGAOUT8(0x3c4, 0x1f); + VGAOUT8(0x3c5, restore->SR1F); + VGAOUT8(0x3c4, 0x22); + VGAOUT8(0x3c5, restore->SR22); + VGAOUT8(0x3c4, 0x23); + VGAOUT8(0x3c5, restore->SR23); + VGAOUT8(0x3c4, 0x24); + VGAOUT8(0x3c5, restore->SR24); + VGAOUT8(0x3c4, 0x25); + VGAOUT8(0x3c5, restore->SR25); + VGAOUT8(0x3c4, 0x26); + VGAOUT8(0x3c5, restore->SR26); + VGAOUT8(0x3c4, 0x27); + VGAOUT8(0x3c5, restore->SR27); + VGAOUT8(0x3c4, 0x28); + VGAOUT8(0x3c5, restore->SR28); + VGAOUT8(0x3c4, 0x29); + VGAOUT8(0x3c5, restore->SR29); + VGAOUT8(0x3c4, 0x2a); + VGAOUT8(0x3c5, restore->SR2A); + VGAOUT8(0x3c4, 0x2b); + VGAOUT8(0x3c5, restore->SR2B); + VGAOUT8(0x3c4, 0x2e); + VGAOUT8(0x3c5, restore->SR2E); + VGAOUT8(0x3c4, 0x44); + VGAOUT8(0x3c5, restore->SR44); + VGAOUT8(0x3c4, 0x45); + VGAOUT8(0x3c5, restore->SR45); + VGAOUT8(0x3c4, 0x46); + VGAOUT8(0x3c5, restore->SR46); + VGAOUT8(0x3c4, 0x47); + VGAOUT8(0x3c5, restore->SR47); + + VGAOUT8(vgaCRIndex, 0x13); + VGAOUT8(vgaCRReg, restore->CR13); + VGAOUT8(vgaCRIndex, 0x32); + VGAOUT8(vgaCRReg, restore->CR32); + VGAOUT8(vgaCRIndex, 0x33); + VGAOUT8(vgaCRReg, restore->CR33); + VGAOUT8(vgaCRIndex, 0x34); + VGAOUT8(vgaCRReg, restore->CR34); + VGAOUT8(vgaCRIndex, 0x35); + VGAOUT8(vgaCRReg, restore->CR35); + VGAOUT8(vgaCRIndex, 0x36); + VGAOUT8(vgaCRReg, restore->CR36); + + /* Restore LCD control regs */ + for (i = 0; i < 68; i++) { + VGAOUT8(vgaCRIndex, i + 0x50); + VGAOUT8(vgaCRReg, restore->CRTCRegs[i]); + } + + /*if (pBIOSInfo->LVDS == VIA_CH7019LVDS) { + dev = xf86CreateI2CDevRec(); + dev->DevName = "LVDS"; + dev->SlaveAddr = 0xEA; + dev->pI2CBus = pVia->I2C_Port2; + + if (xf86I2CDevInit(dev)) { + for (i = 0; i < 0x40; i++) { + W_Buffer[0] = (unsigned char)(i + 0x40); + W_Buffer[1] = (unsigned char)(restore->LCDRegs[i]); + xf86I2CWriteRead(dev, W_Buffer, 2, NULL,0); + } + + xf86DestroyI2CDevRec(dev,TRUE); + } + else + xf86DestroyI2CDevRec(dev,TRUE); + + ActiveDevice = VIABIOS_GetActiveDevice(pScrn); + }*/ + if (pBIOSInfo->DefaultActiveDevice & VIA_DEVICE_LCD) + VIAEnableLCD(pBIOSInfo); + + VIADisabledExtendedFIFO(pBIOSInfo); + /* Reset clock */ + tmp = VGAIN8(0x3cc); + VGAOUT8(0x3c2, tmp); + + /* If we're going into graphics mode and acceleration was enabled, */ +/* + if (graphicsMode && (!pVia->NoAccel)) { + VIAInitialize2DEngine(pScrn); + } +*/ + vgaHWProtect(pScrn, FALSE); + return; +} + + +static Bool VIAMapMMIO(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + vgaHWPtr hwp; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n")); + + pVia->FrameBufferBase = pVia->PciInfo->memBase[0]; + pVia->MmioBase = pVia->PciInfo->memBase[1]; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "mapping MMIO @ 0x%lx with size 0x%x\n", + pVia->MmioBase, VIA_MMIO_REGSIZE); + + pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, + pVia->MmioBase, + VIA_MMIO_REGSIZE); + pBIOSInfo->MapBase = pVia->MapBase; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "mapping BitBlt MMIO @ 0x%lx with size 0x%x\n", + pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE); + + pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, + pVia->MmioBase + VIA_MMIO_BLTBASE, + VIA_MMIO_BLTSIZE); +/* + pVia->FBFreeStart += 0x300000; + ErrorF("After 3M FBFreeStart = 0x%x\n",pVia->FBFreeStart); +*/ + if (!pVia->MapBase || !pVia->BltBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: cound not map registers\n"); + return FALSE; + } + + /* Memory mapped IO for Video Engine */ + pVia->VidMapBase = pVia->MapBase + 0x200; + + VIAEnableMMIO(pScrn); + hwp = VGAHWPTR(pScrn); + vgaHWGetIOBase(hwp); + + return TRUE; +} + + +static Bool VIAMapFB(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n")); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "mapping framebuffer @ 0x%lx with size 0x%lx\n", + pVia->FrameBufferBase, pVia->videoRambytes); + + if (pVia->videoRambytes) { + pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pVia->PciTag, pVia->FrameBufferBase, + pVia->videoRambytes); + pBIOSInfo->FBBase = pVia->FBBase; + pBIOSInfo->videoRambytes = pVia->videoRambytes; + + if (!pVia->FBBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: could not map framebuffer\n"); + return FALSE; + } + + pVia->FBStart = pVia->FBBase; + pVia->FBFreeStart = (pScrn->displayWidth * pScrn->bitsPerPixel >> 3) * + pScrn->virtualY; + pVia->FBFreeEnd = pVia->videoRambytes; + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Frame buffer start: %p, free start: 0x%x end: 0x%x\n", + pVia->FBStart, pVia->FBFreeStart, pVia->FBFreeEnd); + } + + pScrn->memPhysBase = pVia->PciInfo->memBase[0]; + pScrn->fbOffset = 0; + if(pVia->IsSecondary) pScrn->fbOffset = pScrn->videoRam << 10; + + return TRUE; +} + + +static void VIAUnmapMem(ScrnInfoPtr pScrn) +{ + VIAPtr pVia; + + pVia = VIAPTR(pScrn); + + VIADisableMMIO(pScrn); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAUnmapMem\n")); + + if (pVia->MapBase) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->MapBase, + VIA_MMIO_REGSIZE); + } + + if (pVia->BltBase) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->BltBase, + VIA_MMIO_BLTSIZE); + } + + if (pVia->FBBase) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pVia->FBBase, + pVia->videoRambytes); + } + + return; +} + + +static Bool VIAScreenInit(int scrnIndex, ScreenPtr pScreen, + int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + int ret; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit\n")); + vgaHWUnlock(hwp); + + if (!VIAMapFB(pScrn)) + return FALSE; + + if (!VIAMapMMIO(pScrn)) + return FALSE; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Mem Mapped\n")); + + VIASave(pScrn); + + vgaHWBlankScreen(pScrn, FALSE); + + if (!VIAModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- State saved\n")); + + /* Darken the screen for aesthetic reasons and set the viewport */ + VIASaveScreen(pScreen, SCREEN_SAVER_ON); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Blanked\n")); + + miClearVisualTypes(); + + if (pScrn->bitsPerPixel > 8 && !pVia->IsSecondary) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + if (!miSetPixmapDepths()) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + if (!miSetPixmapDepths()) + return FALSE; + } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Visuals set up\n")); + + ret = VIAInternalScreenInit(scrnIndex, pScreen); + + if (!ret) + return FALSE; + + xf86SetBlackWhitePixels(pScreen); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- B & W\n")); + + if (pScrn->bitsPerPixel > 8) { + VisualPtr visual; + + 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; + } + } + } + +#ifdef USE_FB + /* must be after RGB ordering fixed */ + fbPictureInit(pScreen, 0, 0); +#endif + + if (!pVia->NoAccel) + VIAInitAccel(pScreen); + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + /*xf86SetSilkenMouse(pScreen);*/ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Backing store set up\n")); + + if(!pVia->shadowFB) /* hardware cursor needs to wrap this layer */ + VIADGAInit(pScreen); + + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- SW cursor set up\n")); + + if (pVia->hwcursor) { + if (!VIAHWCursorInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + } + } + + if (pVia->shadowFB) { + RefreshAreaFuncPtr refreshArea = VIARefreshArea; + + if(pVia->rotate) { + if (!pVia->PointerMoved) { + pVia->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = VIAPointerMoved; + } + + switch(pScrn->bitsPerPixel) { + case 8: + refreshArea = VIARefreshArea8; + break; + case 16: + refreshArea = VIARefreshArea16; + break; + case 32: + refreshArea = VIARefreshArea32; + break; + } + } + + ShadowFBInit(pScreen, refreshArea); + } + + if (!miCreateDefColormap(pScreen)) + return FALSE; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Def Color map set up\n")); + + if (!xf86HandleColormaps(pScreen, 256, 6, VIALoadPalette, NULL, + CMAP_RELOAD_ON_MODE_SWITCH + | CMAP_PALETTED_TRUECOLOR)) + return FALSE; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Palette loaded\n")); + + vgaHWBlankScreen(pScrn, TRUE); + + pVia->CloseScreen = pScreen->CloseScreen; + pScreen->SaveScreen = VIASaveScreen; + pScreen->CloseScreen = VIACloseScreen; + + xf86DPMSInit(pScreen, VIADPMS, 0); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- DPMS set up\n")); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Color maps etc. set up\n")); + +#ifdef XF86DRI + pVia->directRenderingEnabled = VIADRIScreenInit(pScreen); + + if (pVia->directRenderingEnabled) { + pVia->directRenderingEnabled = VIADRIFinishScreenInit(pScreen); + } + if (pVia->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n"); + } + else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n"); + } +#endif + + if (VIA_SERIES(pVia->Chipset) && !pVia->IsSecondary) { + viaFillGraphicInfo(pScrn); + /* There is alas not enough bandwidth to do 1600x1200x16 with video overlay */ +/* if(pScrn->bitsPerPixel * pScrn->virtualX *pScrn->virtualY <= 1400 * 1050 * 16) */ + viaInitVideo(pScreen); +/* else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video overlay disabled (%dx%d@%d exceeds bandwidth)\n", + pScrn->virtualX, pScrn->virtualY, pScrn->bitsPerPixel);*/ + } + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Done\n")); + return TRUE; +} + + +static int VIAInternalScreenInit(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn; + VIAPtr pVia; + int width, height, displayWidth; + unsigned char *FBStart; + int ret = TRUE; + + xf86DrvMsg(scrnIndex, X_INFO, "VIAInternalScreenInit\n"); + + pScrn = xf86Screens[pScreen->myNum]; + pVia = VIAPTR(pScrn); + + displayWidth = pScrn->displayWidth; + + if (pVia->rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } else { + width = pScrn->virtualX; + height = pScrn->virtualY; + } + + if (pVia->shadowFB) { + pVia->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); + pVia->ShadowPtr = xalloc(pVia->ShadowPitch * height); + displayWidth = pVia->ShadowPitch / (pScrn->bitsPerPixel >> 3); + FBStart = pVia->ShadowPtr; + } + else { + pVia->ShadowPtr = NULL; + FBStart = pVia->FBStart; + } + +#ifdef USE_FB + ret = fbScreenInit(pScreen, FBStart, width, height, + pScrn->xDpi, pScrn->yDpi, displayWidth, + pScrn->bitsPerPixel); +#else + switch (pScrn->bitsPerPixel) { + case 8: + ret = cfbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, + pScrn->yDpi, displayWidth); + break; + + case 16: + ret = cfb16ScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, + pScrn->yDpi, displayWidth); + break; + + case 32: + ret = cfb32ScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, + pScrn->yDpi, displayWidth); + break; + + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in SavageScreenInit\n", + pScrn->bitsPerPixel); + ret = FALSE; + break; + } +#endif + + return ret; +} + + +static ModeStatus VIAValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flags) +{ + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAValidMode\n")); + /* TODO check modes */ + return MODE_OK; +} + + +static void VIABIOSInit(VIAPtr pVia, ScrnInfoPtr pScrn, DisplayModePtr pMode) +{ + int i; + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + pBIOSInfo->bitsPerPixel = pScrn->bitsPerPixel; + pBIOSInfo->displayWidth = pScrn->displayWidth; + pBIOSInfo->frameX1 = pScrn->frameX1; + pBIOSInfo->frameY1 = pScrn->frameY1; + pBIOSInfo->scrnIndex = pScrn->scrnIndex; + + pBIOSInfo->Clock = pMode->Clock; + pBIOSInfo->HTotal = pMode->HTotal; + pBIOSInfo->VTotal = pMode->VTotal; + pBIOSInfo->HDisplay = pMode->HDisplay; + pBIOSInfo->VDisplay = pMode->VDisplay; + pBIOSInfo->CrtcHDisplay = pMode->CrtcHDisplay; + pBIOSInfo->CrtcVDisplay = pMode->CrtcVDisplay; + if (pBIOSInfo->FirstInit) { + pBIOSInfo->SaveframeX1 = pScrn->frameX1; + pBIOSInfo->SaveframeY1 = pScrn->frameY1; + pBIOSInfo->SaveHDisplay = pMode->HDisplay; + pBIOSInfo->SaveVDisplay = pMode->VDisplay; + pBIOSInfo->SaveCrtcHDisplay = pMode->CrtcHDisplay; + pBIOSInfo->SaveCrtcVDisplay = pMode->CrtcVDisplay; + } + + pBIOSInfo->IsSecondary = pVia->IsSecondary; + pBIOSInfo->HasSecondary = pVia->HasSecondary; + + for (i = 0; i < 0xFF; i++) { + pBIOSInfo->TVRegs[i] = pVia->SavedReg.TVRegs[i]; + } +} + + +static void VIAPostFindMode(VIAPtr pVia, ScrnInfoPtr pScrn, DisplayModePtr pMode) +{ + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + + pVia->ModeReg.mode = pBIOSInfo->mode; + pVia->ModeReg.resMode = pBIOSInfo->resMode; + pVia->ModeReg.refresh = pBIOSInfo->refresh; + pVia->ModeReg.offsetWidthByQWord = pBIOSInfo->offsetWidthByQWord; + pVia->ModeReg.countWidthByQWord = pBIOSInfo->countWidthByQWord; + + pScrn->frameX1 = pBIOSInfo->frameX1; + pScrn->frameY1 = pBIOSInfo->frameY1; + pMode->HDisplay = pBIOSInfo->HDisplay; + pMode->VDisplay = pBIOSInfo->VDisplay; + +} + + +static Bool VIAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + VIARegPtr new = &pVia->ModeReg; + vgaRegPtr vganew = &hwp->ModeReg; + /* DDUPDATEOVERLAY UpdateOverlay; */ + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAModeInit\n")); + + + if (!vgaHWInit(pScrn, mode)) { + vgaHWBlankScreen(pScrn, TRUE); + return FALSE; + } + + pScrn->vtSema = TRUE; + + VIABIOSInit(pVia, pScrn, mode); + + if (!VIAFindModeUseBIOSTable(pBIOSInfo)) { + vgaHWBlankScreen(pScrn, TRUE); + VIAFreeRec(pScrn); + return FALSE; + } + + VIAPostFindMode(pVia, pScrn, mode); + + /* FIXME - need DRI lock for this bit - see i810 */ + /* do it! */ + VIAWriteMode(pScrn, vganew, new); + + /* pass graphic info to via_v4l kernel module */ + /* Coz mode changes, some member in pVia->graphicInfo need to modify */ + if (VIA_SERIES(pVia->Chipset) && !pVia->IsSecondary) + { + viaFillGraphicInfo(pScrn); + + DBG_DD(ErrorF("SWOV: VIAVidSet2DInfo\n")); + + /* Save MCLK value*/ + VGAOUT8(0x3C4, 0x16); pVia->swov.Save_3C4_16 = VGAIN8(0x3C5); + DBG_DD(ErrorF(" 3c4.16 : %08x \n",VGAIN8(0x3C5))); + VGAOUT8(0x3C4, 0x17); pVia->swov.Save_3C4_17 = VGAIN8(0x3C5); + DBG_DD(ErrorF(" 3c4.17 : %08x \n",VGAIN8(0x3C5))); + VGAOUT8(0x3C4, 0x18); pVia->swov.Save_3C4_18 = VGAIN8(0x3C5); + DBG_DD(ErrorF(" 3c4.18 : %08x \n",VGAIN8(0x3C5))); + } + VIAAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + + +static Bool VIACloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + vgaRegPtr vgaSavePtr = &hwp->SavedReg; + VIARegPtr viaSavePtr = &pVia->SavedReg; + CARD32 dwCursorMode; + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIACloseScreen\n")); + + /* Is the display currently visible ? */ + if(pScrn->vtSema) + { + /* Wait Hardware Engine idle to exit graphical mode */ + WaitIdle(); + + /* Patch for normal log out and restart X, 3D application will hang */ + VIAWriteMode(pScrn, vgaSavePtr, viaSavePtr); + + if (!pVia->IsSecondary) { + /* Turn off all video activities */ + viaExitVideo(pScrn); + /* Diable Hardware Cursor */ + dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE); + VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE); + } + + if (pVia->VQEnable) { + /* if we use VQ, disable it before we exit */ + VIASETREG(0x43c, 0x00fe0000); + VIASETREG(0x440, 0x00000004); + } + } + if (pVia->AccelInfoRec) { + XAADestroyInfoRec(pVia->AccelInfoRec); + pVia->AccelInfoRec = NULL; + } + if (pVia->CursorInfoRec) { + xf86DestroyCursorInfoRec(pVia->CursorInfoRec); + pVia->CursorInfoRec = NULL; + } + if (pVia->ShadowPtr) { + xfree(pVia->ShadowPtr); + pVia->ShadowPtr = NULL; + } + if (pVia->DGAModes) { + xfree(pVia->DGAModes); + pVia->DGAModes = NULL; + } + if(pVia->pInt10) { + xf86FreeInt10(pVia->pInt10); + pVia->pInt10 = NULL; + } + + if (pScrn->vtSema) { + VIAWriteMode(pScrn, vgaSavePtr, viaSavePtr); + vgaHWLock(hwp); + VIAUnmapMem(pScrn); + } + pScrn->vtSema = FALSE; + pScreen->CloseScreen = pVia->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + +/* + * This only gets called when a screen is being deleted. It does not + * get called routinely at the end of a server generation. + */ +static void VIAFreeScreen(int scrnIndex, int flags) +{ + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAFreeScreen\n")); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + VIAFreeRec(xf86Screens[scrnIndex]); +} + +static Bool VIASaveScreen(ScreenPtr pScreen, int mode) +{ + return vgaHWSaveScreen(pScreen, mode); +} + + +void VIAAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + int Base, tmp; + int vgaCRIndex, vgaCRReg, vgaIOBase; + DDLOCK ddLock; + LPDDLOCK lpddLock = &ddLock; + DDUPDATEOVERLAY UpdateOverlay; + ADJUSTFRAME AdjustFrame; + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIAAdjustFrame\n")); + vgaIOBase = hwp->IOBase; + vgaCRIndex = vgaIOBase + 4; + vgaCRReg = vgaIOBase + 5; + + Base = (y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8); + + /* now program the start address registers */ + if (pVia->IsSecondary) { + Base = (Base + pScrn->fbOffset) >> 3; + VGAOUT8(vgaCRIndex, 0x62); + tmp = VGAIN8(vgaCRReg) & 0x01; + tmp |= (Base & 0x7F) << 1; + VGAOUT8(vgaCRReg, tmp); + VGAOUT8(vgaCRIndex, 0x63); + VGAOUT8(vgaCRReg, ((Base & 0x7F80) >> 7)); + VGAOUT8(vgaCRIndex, 0x64); + VGAOUT8(vgaCRReg, ((Base & 0x7F8000) >> 15)); + } + else { + Base = Base >> 1; + VGAOUT16(vgaCRIndex, (Base & 0x00ff00) | 0x0c); + VGAOUT16(vgaCRIndex, ((Base & 0x00ff) << 8) | 0x0d); + VGAOUT16(vgaCRIndex, ((Base & 0xff0000) >> 8) | 0x34); + } + + /* Pass Panning (x, y) info to V4L */ + AdjustFrame.x = x; + AdjustFrame.y = y; + + VIAVidAdjustFrame(pScrn,&AdjustFrame); + + /* Check if HW mpeg engine active */ + if (pVia->Video.VideoStatus & SW_VIDEO_ON) /* SW video case */ + { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + " Call SW MPEG UpdateOverlay at panning mode.\n"); + + ddLock.dwFourCC = FOURCC_YUY2; + + VIAVidLockSurface(pScrn, &ddLock); + + UpdateOverlay.dwFlags = DDOVER_SHOW | DDOVER_KEYDEST; + UpdateOverlay.dwColorSpaceLowValue = VIAGETREG(0x220); + UpdateOverlay.rSrc.left = 0; + UpdateOverlay.rSrc.top = 0; + UpdateOverlay.rSrc.right = 720; + UpdateOverlay.rSrc.bottom = 480; + + UpdateOverlay.rDest.left = (int) lpddLock->SWDevice.gdwSWDstLeft; + UpdateOverlay.rDest.top = (int) lpddLock->SWDevice.gdwSWDstTop; + UpdateOverlay.rDest.right = UpdateOverlay.rDest.left + lpddLock->SWDevice.gdwSWDstWidth; + UpdateOverlay.rDest.bottom = UpdateOverlay.rDest.top + lpddLock->SWDevice.gdwSWDstHeight; + + VIAVidUpdateOverlay(pScrn, &UpdateOverlay); + } + else if (VIAGETREG(0x310) & 0x1) /* capture 0 (TV0) case */ + { + ddLock.dwFourCC = FOURCC_TV0; + + VIAVidLockSurface(pScrn, &ddLock); + } + + if (VIAGETREG(0x354) & 0x1) /* capture 1 (TV1) case */ + { + ddLock.dwFourCC = FOURCC_TV1; + + VIAVidLockSurface(pScrn, &ddLock); + } + + return; +} + + +Bool VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + VIAPtr pVia = VIAPTR(pScrn); + + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "VIASwitchMode\n")); + /* Wait Hardware Engine idle to switch graphicd mode */ + WaitIdle(); + + if (pVia->VQEnable) { + /* if we use VQ, disable it before we exit */ + VIASETREG(0x43c, 0x00fe0000); + VIASETREG(0x440, 0x00000004); + } + + return VIAModeInit(xf86Screens[scrnIndex], mode); +} + + +void VIAEnableMMIO(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + unsigned char val; + + if (xf86IsPrimaryPci(pVia->PciInfo)) { + /* If we are primary card, we still use std vga port. If we use + * MMIO, system will hang in vgaHWSave when our card used in + * PLE and KLE (integrated Trident MVP4) + */ + vgaHWSetStdFuncs(hwp); + } + else { + vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); + } + + val = VGAIN8(0x3c3); + VGAOUT8(0x3c3, val | 0x01); + val = VGAIN8(VGA_MISC_OUT_R); + VGAOUT8(VGA_MISC_OUT_W, val | 0x01); + + /* Unlock Extended IO Space */ + VGAOUT8(0x3c4, 0x10); + VGAOUT8(0x3c5, 0x01); + + /* Enable MMIO */ + if(!pVia->IsSecondary) { + VGAOUT8(0x3c4, 0x1a); + val = VGAIN8(0x3c5); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "primary val = %x\n", val)); + VGAOUT8(0x3c5, val | 0x68); + } + else { + VGAOUT8(0x3c4, 0x1a); + val = VGAIN8(0x3c5); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "secondary val = %x\n", val)); + VGAOUT8(0x3c5, val | 0x38); + } + + return; +} + + +void VIADisableMMIO(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + unsigned char val; + + VGAOUT8(0x3c4, 0x1a); + val = VGAIN8(0x3c5); + VGAOUT8(0x3c5, val & 0x97); + + return; +} + + +void VIALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, + LOCO *colors, VisualPtr pVisual) +{ + VIAPtr pVia = VIAPTR(pScrn); + int i, index; + int sr1a, sr1b, cr67, cr6a; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIALoadPalette\n")); + + if (pScrn->bitsPerPixel != 8) + return; + VGAOUT8(0x3C4, 0x1A); + sr1a = VGAIN8(0x3C5); + VGAOUT8(0x3C4, 0x1B); + sr1b = VGAIN8(0x3C5); + VGAOUT8(0x3D4, 0x67); + cr67 = VGAIN8(0x3D5); + VGAOUT8(0x3D4, 0x6A); + cr6a = VGAIN8(0x3D5); + + if (pVia->IsSecondary) { + VGAOUT8(0x3C4, 0x1A); + VGAOUT8(0x3C5, sr1a | 0x01); + VGAOUT8(0x3C4, 0x1B); + VGAOUT8(0x3C5, sr1b | 0x80); + VGAOUT8(0x3D4, 0x67); + VGAOUT8(0x3D5, cr67 & 0x3F); + VGAOUT8(0x3D4, 0x6A); + VGAOUT8(0x3D5, cr6a | 0xC0); + } + + for (i = 0; i < numColors; i++) { + index = indicies[i]; + VGAOUT8(0x3c8, index); + VGAOUT8(0x3c9, colors[index].red); + VGAOUT8(0x3c9, colors[index].green); + VGAOUT8(0x3c9, colors[index].blue); + } + + if (pVia->IsSecondary) { + VGAOUT8(0x3C4, 0x1A); + VGAOUT8(0x3C5, sr1a); + VGAOUT8(0x3C4, 0x1B); + VGAOUT8(0x3C5, sr1b); + VGAOUT8(0x3D4, 0x67); + VGAOUT8(0x3D5, cr67); + VGAOUT8(0x3D4, 0x6A); + VGAOUT8(0x3D5, cr6a); + + /* Screen 0 palette was changed by mode setting of Screen 1, + * so load again */ + for (i = 0; i < numColors; i++) { + index = indicies[i]; + VGAOUT8(0x3c8, index); + VGAOUT8(0x3c9, colors[index].red); + VGAOUT8(0x3c9, colors[index].green); + VGAOUT8(0x3c9, colors[index].blue); + } + + } + +} + + +static void VIADPMS(ScrnInfoPtr pScrn, int mode, int flags) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + int vgaCRIndex, vgaCRReg; + CARD8 val; + + I2CDevPtr dev; + unsigned char W_Buffer[2]; + + vgaCRIndex = hwp->IOBase + 4; + vgaCRReg = hwp->IOBase + 5; + + /* Clear DPMS setting */ + VGAOUT8(vgaCRIndex, 0x36); + val = VGAIN8(vgaCRReg); + val &= 0xCF; + /* Turn Off CRT, if user doesn't want crt on */ + if (!pVia->IsSecondary && !(pBIOSInfo->ActiveDevice & VIA_DEVICE_CRT1)) { + val |= 0x30; + } + + switch (mode) { + case DPMSModeOn: + if (pBIOSInfo->ActiveDevice & (VIA_DEVICE_DFP | VIA_DEVICE_LCD)) { + /* Enable LCD */ + VIAEnableLCD(pBIOSInfo); + } + + if (pBIOSInfo->ActiveDevice & VIA_DEVICE_TV) { + dev = xf86CreateI2CDevRec(); + dev->DevName = "TV"; + dev->SlaveAddr = pBIOSInfo->TVI2CAdd; + dev->pI2CBus = pBIOSInfo->I2C_Port2; + if (xf86I2CDevInit(dev)) { + switch (pBIOSInfo->TVEncoder) { + case VIA_TV2PLUS: + case VIA_TV3: + case VIA_VT1622A: + W_Buffer[0] = 0x0E; + W_Buffer[1] = 0x0; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + break; + case VIA_VT1623: + VIAGPIOI2C_Initial(pBIOSInfo, 0x40); + VIAGPIOI2C_Write(pBIOSInfo, 0x0E, 0); + break; + case VIA_CH7019: + W_Buffer[0] = 0x49; + W_Buffer[1] = 0x20; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + /*W_Buffer[0] = 0x1E; + W_Buffer[1] = 0xD0; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0);*/ + break; + case VIA_SAA7108: + W_Buffer[0] = 0x2D; + switch (pBIOSInfo->TVOutput) { + case TVOUTPUT_COMPOSITE: + case TVOUTPUT_SVIDEO: + W_Buffer[1] = 0xB4; + break; + case TVOUTPUT_RGB: + W_Buffer[1] = 0; + break; + case TVOUTPUT_YCBCR: + W_Buffer[1] = 0x84; + break; + default: + W_Buffer[1] = 0x08; + break; + } + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + break; + default: + break; + } + xf86DestroyI2CDevRec(dev,TRUE); + } + else + xf86DestroyI2CDevRec(dev,TRUE); + } + VGAOUT8(vgaCRIndex, 0x36); + VGAOUT8(vgaCRReg, val); + break; + case DPMSModeStandby: + case DPMSModeSuspend: + case DPMSModeOff: + if (pBIOSInfo->ActiveDevice & (VIA_DEVICE_DFP | VIA_DEVICE_LCD)) { + VIADisableLCD(pBIOSInfo); + } + if (pBIOSInfo->ActiveDevice & VIA_DEVICE_TV) { + dev = xf86CreateI2CDevRec(); + dev->DevName = "TV"; + dev->SlaveAddr = pBIOSInfo->TVI2CAdd; + dev->pI2CBus = pBIOSInfo->I2C_Port2; + if (xf86I2CDevInit(dev)) { + switch (pBIOSInfo->TVEncoder) { + case VIA_TV2PLUS: + W_Buffer[0] = 0x0E; + W_Buffer[1] = 0x03; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + break; + case VIA_TV3: + case VIA_VT1622A: + W_Buffer[0] = 0x0E; + W_Buffer[1] = 0x0F; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + break; + case VIA_VT1623: + VIAGPIOI2C_Initial(pBIOSInfo, 0x40); + VIAGPIOI2C_Write(pBIOSInfo, 0x0E, 0x0F); + break; + case VIA_CH7019: + W_Buffer[0] = 0x49; + W_Buffer[1] = 0x3E; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + W_Buffer[0] = 0x1E; + W_Buffer[1] = 0xD0; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + break; + case VIA_SAA7108: + W_Buffer[0] = 0x2D; + W_Buffer[1] = 0x08; + xf86I2CWriteRead(dev, W_Buffer,2, NULL,0); + break; + default: + break; + } + xf86DestroyI2CDevRec(dev,TRUE); + } + else + xf86DestroyI2CDevRec(dev,TRUE); + } + + val |= 0x30; + VGAOUT8(vgaCRIndex, 0x36); + VGAOUT8(vgaCRReg, val); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode); + break; + } + return; +} + + +int VIAGetMemSize() +{ + /* TODO: Do memory sizing */ + + /* Default 16MB */ + return (16 << 10); +} + +/* Active Device according connected status */ +Bool VIADeviceSelection(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + /*unsigned int i; + unsigned char numDevice;*/ + pBIOSInfo->SAMM = FALSE; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIADeviceSelection\n")); + pBIOSInfo->DefaultActiveDevice = VIABIOS_GetActiveDevice(pScrn); + /* if XF86Config Option "ActiveDevice" hasn't set, active device according CMOS */ + if (!pBIOSInfo->ActiveDevice) { + pBIOSInfo->ActiveDevice = pBIOSInfo->DefaultActiveDevice; + } + /* if XF86Config-4 set SAMM, and only active one device, active device according CMOS */ + else if (pVia->IsSecondary && (pBIOSInfo->ActiveDevice == VIA_DEVICE_CRT1 || + pBIOSInfo->ActiveDevice == VIA_DEVICE_LCD || + pBIOSInfo->ActiveDevice == VIA_DEVICE_TV || + pBIOSInfo->ActiveDevice == VIA_DEVICE_DFP || + pBIOSInfo->ActiveDevice == VIA_DEVICE_CRT2)){ + pBIOSInfo->ActiveDevice = VIABIOS_GetActiveDevice(pScrn); + } + if (((pBIOSInfo->ActiveDevice & pBIOSInfo->ConnectedDevice) == pBIOSInfo->ActiveDevice) + && (pVia->IsSecondary)) { + pBIOSInfo->SAMM = TRUE; + } + pBIOSInfo->ActiveDevice &= pBIOSInfo->ConnectedDevice; + pVia->ActiveDevice = pBIOSInfo->ActiveDevice; + + /*if (pBIOSInfo->ActiveDevice & VIA_DEVICE_LCD) { + pBIOSInfo->DVIEncoder = VIA_VT3191; + numDevice = 0x02; + i = VIABIOS_GetDisplayDeviceInfo(pScrn, &numDevice); + if (i != 0xFFFF) { + if (pBIOSInfo->PanelSize == VIA_PANEL_INVALID) + pBIOSInfo->PanelSize = numDevice; + }*/ + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Connected Device is %d\n", pBIOSInfo->ConnectedDevice)); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Active Device is %d\n", pBIOSInfo->ActiveDevice)); + + return TRUE; +} + +/* SAMM device dispatch */ +Bool VIADeviceDispatch(ScrnInfoPtr pScrn) +{ + DevUnion* pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex); + VIAEntPtr pVIAEnt = pPriv->ptr; + VIAPtr pVia1 = VIAPTR(pScrn), pVia0 = VIAPTR(pVIAEnt->pPrimaryScrn); + VIABIOSInfoPtr pBIOSInfo1 = pVia1->pBIOSInfo, pBIOSInfo0 = pVia0->pBIOSInfo; + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIADeviceDispatch\n")); + pBIOSInfo0->SAMM = TRUE; + switch (pBIOSInfo1->ActiveDevice) { + case (VIA_DEVICE_CRT1 | VIA_DEVICE_LCD) : /* If CRT + LCD, CRT is IGA1 */ + pBIOSInfo0->ActiveDevice = VIA_DEVICE_CRT1; + pBIOSInfo1->ActiveDevice = VIA_DEVICE_LCD; + break; + case (VIA_DEVICE_CRT1 | VIA_DEVICE_TV) : /* If CRT + TV, CRT is IGA1 */ + pBIOSInfo0->ActiveDevice = VIA_DEVICE_CRT1; + pBIOSInfo1->ActiveDevice = VIA_DEVICE_TV; + break; + case (VIA_DEVICE_CRT1 | VIA_DEVICE_DFP) : /* If CRT + DFP, CRT is IGA1 */ + pBIOSInfo0->ActiveDevice = VIA_DEVICE_CRT1; + pBIOSInfo1->ActiveDevice = VIA_DEVICE_DFP; + break; + case (VIA_DEVICE_LCD | VIA_DEVICE_TV) : /* If LCD + TV, TV is IGA1 */ + pBIOSInfo0->ActiveDevice = VIA_DEVICE_TV; + pBIOSInfo1->ActiveDevice = VIA_DEVICE_LCD; + break; + case (VIA_DEVICE_LCD | VIA_DEVICE_DFP) : /* If LCD + DFP, DFP is IGA1 */ + pBIOSInfo0->ActiveDevice = VIA_DEVICE_DFP; + pBIOSInfo1->ActiveDevice = VIA_DEVICE_LCD; + break; + case (VIA_DEVICE_TV | VIA_DEVICE_DFP) : /* If TV + DFP, TV is IGA1 */ + pBIOSInfo0->ActiveDevice = VIA_DEVICE_TV; + pBIOSInfo1->ActiveDevice = VIA_DEVICE_DFP; + break; + default : + return FALSE; + break; + } + DEBUG(xf86DrvMsg(pVIAEnt->pPrimaryScrn->scrnIndex, X_INFO, "Active Device is %d\n", pBIOSInfo0->ActiveDevice)); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Active Device is %d\n", pBIOSInfo1->ActiveDevice)); + return TRUE; +} + +#ifdef XF86DRI +void +VIAInitialize3DEngine(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + int i; + + if (!pVia->sharedData->b3DRegsInitialized) + { + + VIASETREG(0x43C, 0x00010000); + + for (i = 0; i <= 0x7D; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x43C, 0x00020000); + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x440, 0x82400000); + + VIASETREG(0x43C, 0x01020000); + + + for (i = 0; i <= 0x94; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x440, 0x82400000); + VIASETREG(0x43C, 0xfe020000); + + for (i = 0; i <= 0x03; i++) + { + VIASETREG(0x440, (CARD32) i << 24); + } + + VIASETREG(0x43C, 0x00030000); + + for (i = 0; i <= 0xff; i++) + { + VIASETREG(0x440, 0); + } + VIASETREG(0x43C, 0x00100000); + VIASETREG(0x440, 0x00333004); + VIASETREG(0x440, 0x10000002); + VIASETREG(0x440, 0x60000000); + VIASETREG(0x440, 0x61000000); + VIASETREG(0x440, 0x62000000); + VIASETREG(0x440, 0x63000000); + VIASETREG(0x440, 0x64000000); + + VIASETREG(0x43C, 0x00fe0000); + + if (pVia->ChipRev >= 3 ) + VIASETREG(0x440,0x40008c0f); + else + VIASETREG(0x440,0x4000800f); + + VIASETREG(0x440,0x44000000); + VIASETREG(0x440,0x45080C04); + VIASETREG(0x440,0x46800408); + VIASETREG(0x440,0x50000000); + VIASETREG(0x440,0x51000000); + VIASETREG(0x440,0x52000000); + VIASETREG(0x440,0x53000000); + + pVia->sharedData->b3DRegsInitialized = 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "3D Register has been initilized !\n"); + } + + VIASETREG(0x43C,0x00fe0000); + VIASETREG(0x440,0x08000001); + VIASETREG(0x440,0x0A000183); + VIASETREG(0x440,0x0B00019F); + VIASETREG(0x440,0x0C00018B); + VIASETREG(0x440,0x0D00019B); + VIASETREG(0x440,0x0E000000); + VIASETREG(0x440,0x0F000000); + VIASETREG(0x440,0x10000000); + VIASETREG(0x440,0x11000000); + VIASETREG(0x440,0x20000000); +} +#endif |