savage_driver.c revision 8697ee19
1ab47cfaaSmrg/* 2ab47cfaaSmrg * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3ab47cfaaSmrg * Copyright (c) 2003-2006, X.Org Foundation 4ab47cfaaSmrg * 5ab47cfaaSmrg * Permission is hereby granted, free of charge, to any person obtaining a 6ab47cfaaSmrg * copy of this software and associated documentation files (the "Software"), 7ab47cfaaSmrg * to deal in the Software without restriction, including without limitation 8ab47cfaaSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9ab47cfaaSmrg * and/or sell copies of the Software, and to permit persons to whom the 10ab47cfaaSmrg * Software is furnished to do so, subject to the following conditions: 11ab47cfaaSmrg * 12ab47cfaaSmrg * The above copyright notice and this permission notice shall be included in 13ab47cfaaSmrg * all copies or substantial portions of the Software. 14ab47cfaaSmrg * 15ab47cfaaSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16ab47cfaaSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17ab47cfaaSmrg * FITESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18ab47cfaaSmrg * COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19ab47cfaaSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20ab47cfaaSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21ab47cfaaSmrg * DEALINGS IN THE SOFTWARE. 22ab47cfaaSmrg * 23ab47cfaaSmrg * Except as contained in this notice, the name of the copyright holder(s) 24ab47cfaaSmrg * and author(s) shall not be used in advertising or otherwise to promote 25ab47cfaaSmrg * the sale, use or other dealings in this Software without prior written 26ab47cfaaSmrg * authorization from the copyright holder(s) and author(s). 27ab47cfaaSmrg */ 28ab47cfaaSmrg 29ab47cfaaSmrg/** 30ab47cfaaSmrg * \file savage_driver.c 31ab47cfaaSmrg * 32ab47cfaaSmrg * \author Tim Roberts <timr@probo.com> 33ab47cfaaSmrg * \author Ani Joshi <ajoshi@unixbox.com> 34ab47cfaaSmrg * 35ab47cfaaSmrg * \todo Add credits for the 3.3.x authors. 36ab47cfaaSmrg */ 37ab47cfaaSmrg 38ab47cfaaSmrg#ifdef HAVE_CONFIG_H 39ab47cfaaSmrg#include "config.h" 40ab47cfaaSmrg#endif 41ab47cfaaSmrg 428697ee19Smrg#include <unistd.h> 438697ee19Smrg#include <errno.h> 448697ee19Smrg 45ab47cfaaSmrg#include "xf86RAC.h" 46ab47cfaaSmrg#include "shadowfb.h" 47ab47cfaaSmrg 48ab47cfaaSmrg#include "globals.h" 49ab47cfaaSmrg#define DPMS_SERVER 50ab47cfaaSmrg#include <X11/extensions/dpms.h> 51ab47cfaaSmrg 52ab47cfaaSmrg#include "xf86xv.h" 53ab47cfaaSmrg 54ab47cfaaSmrg#include "savage_driver.h" 55ab47cfaaSmrg#include "savage_regs.h" 56ab47cfaaSmrg#include "savage_bci.h" 57ab47cfaaSmrg#include "savage_streams.h" 58ab47cfaaSmrg 59ab47cfaaSmrg#define TRANSPARENCY_KEY 0xff; 60ab47cfaaSmrg 61ab47cfaaSmrg#ifdef XF86DRI 62ab47cfaaSmrg#define _XF86DRI_SERVER_ 63ab47cfaaSmrg#include "savage_dri.h" 64ab47cfaaSmrg#include "savage_sarea.h" 65ab47cfaaSmrg#endif 66ab47cfaaSmrg 67ab47cfaaSmrg 68ab47cfaaSmrg/* 69ab47cfaaSmrg * prototypes 70ab47cfaaSmrg */ 71ab47cfaaSmrgstatic void SavageEnableMMIO(ScrnInfoPtr pScrn); 72ab47cfaaSmrgstatic void SavageDisableMMIO(ScrnInfoPtr pScrn); 73ab47cfaaSmrg 74ab47cfaaSmrgstatic const OptionInfoRec * SavageAvailableOptions(int chipid, int busid); 75ab47cfaaSmrgstatic void SavageIdentify(int flags); 768697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 778697ee19Smrgstatic Bool SavagePciProbe(DriverPtr drv, int entity_num, 788697ee19Smrg struct pci_device *dev, intptr_t match_data); 798697ee19Smrg#else 80ab47cfaaSmrgstatic Bool SavageProbe(DriverPtr drv, int flags); 818697ee19Smrgstatic int LookupChipID(PciChipsets* pset, int ChipID); 828697ee19Smrg#endif 83ab47cfaaSmrgstatic Bool SavagePreInit(ScrnInfoPtr pScrn, int flags); 84ab47cfaaSmrg 85ab47cfaaSmrgstatic Bool SavageEnterVT(int scrnIndex, int flags); 86ab47cfaaSmrgstatic void SavageLeaveVT(int scrnIndex, int flags); 87ab47cfaaSmrgstatic void SavageSave(ScrnInfoPtr pScrn); 88ab47cfaaSmrgstatic void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr, SavageRegPtr, Bool); 89ab47cfaaSmrg 90ab47cfaaSmrgstatic void SavageInitStatus(ScrnInfoPtr pScrn); 91ab47cfaaSmrgstatic void SavageInitShadowStatus(ScrnInfoPtr pScrn); 92ab47cfaaSmrg 93ab47cfaaSmrgstatic Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 94ab47cfaaSmrg char **argv); 95ab47cfaaSmrgstatic int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen); 96ab47cfaaSmrgstatic ModeStatus SavageValidMode(int index, DisplayModePtr mode, 97ab47cfaaSmrg Bool verbose, int flags); 98ab47cfaaSmrg 99ab47cfaaSmrgvoid SavageDGAInit(ScreenPtr); 100ab47cfaaSmrgstatic Bool SavageMapMem(ScrnInfoPtr pScrn); 101ab47cfaaSmrgstatic void SavageUnmapMem(ScrnInfoPtr pScrn, int All); 102ab47cfaaSmrgstatic Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 103ab47cfaaSmrgstatic Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen); 104ab47cfaaSmrgstatic Bool SavageSaveScreen(ScreenPtr pScreen, int mode); 105ab47cfaaSmrgstatic void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, 106ab47cfaaSmrg int *indicies, LOCO *colors, 107ab47cfaaSmrg VisualPtr pVisual); 108ab47cfaaSmrgstatic void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, 109ab47cfaaSmrg int *indicies, LOCO *colors, 110ab47cfaaSmrg VisualPtr pVisual); 111ab47cfaaSmrgstatic void SavageUpdateKey(ScrnInfoPtr pScrn, int r, int g, int b); 112ab47cfaaSmrgstatic void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, 113ab47cfaaSmrg int min_n2, int max_n2, long freq_min, 114ab47cfaaSmrg long freq_max, unsigned int *mdiv, 115ab47cfaaSmrg unsigned int *ndiv, unsigned int *r); 116ab47cfaaSmrgvoid SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file); 117ab47cfaaSmrgvoid SavagePrintRegs(ScrnInfoPtr pScrn); 118ab47cfaaSmrgstatic void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags); 119ab47cfaaSmrgstatic Bool SavageDDC1(int scrnIndex); 120ab47cfaaSmrgstatic unsigned int SavageDDC1Read(ScrnInfoPtr pScrn); 121ab47cfaaSmrgstatic void SavageProbeDDC(ScrnInfoPtr pScrn, int index); 122ab47cfaaSmrgstatic void SavageGetTvMaxSize(SavagePtr psav); 1238697ee19Smrgstatic Bool SavagePanningCheck(ScrnInfoPtr pScrn, DisplayModePtr pMode); 124ab47cfaaSmrg#ifdef XF86DRI 125ab47cfaaSmrgstatic Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn); 126ab47cfaaSmrg#endif 127ab47cfaaSmrgstatic void SavageResetStreams(ScrnInfoPtr pScrn); 128ab47cfaaSmrg 129ab47cfaaSmrgextern ScrnInfoPtr gpScrn; 130ab47cfaaSmrg 131ab47cfaaSmrg#define iabs(a) ((int)(a)>0?(a):(-(a))) 132ab47cfaaSmrg 133ab47cfaaSmrg/*#define TRACEON*/ 134ab47cfaaSmrg#ifdef TRACEON 135ab47cfaaSmrg#define TRACE(prms) ErrorF prms 136ab47cfaaSmrg#else 137ab47cfaaSmrg#define TRACE(prms) 138ab47cfaaSmrg#endif 139ab47cfaaSmrg 140ab47cfaaSmrgint gSavageEntityIndex = -1; 141ab47cfaaSmrg 1428697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 1438697ee19Smrg#define SAVAGE_DEVICE_MATCH(d, i) \ 1448697ee19Smrg { 0x5333, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) } 1458697ee19Smrg 1468697ee19Smrgstatic const struct pci_id_match savage_device_match[] = { 1478697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE4, S3_SAVAGE4), 1488697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE3D, S3_SAVAGE3D), 1498697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE3D_MV, S3_SAVAGE3D), 1508697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE2000, S3_SAVAGE2000), 1518697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_MX_MV, S3_SAVAGE_MX), 1528697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_MX, S3_SAVAGE_MX), 1538697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_IX_MV, S3_SAVAGE_MX), 1548697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SAVAGE_IX, S3_SAVAGE_MX), 1558697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_PM, S3_PROSAVAGE), 1568697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_KM, S3_PROSAVAGE), 1578697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_S3TWISTER_P, S3_TWISTER), 1588697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_S3TWISTER_K, S3_TWISTER), 1598697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_MX128, S3_SUPERSAVAGE), 1608697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_MX64, S3_SUPERSAVAGE), 1618697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_MX64C, S3_SUPERSAVAGE), 1628697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX128SDR, S3_SUPERSAVAGE), 1638697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX128DDR, S3_SUPERSAVAGE), 1648697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX64SDR, S3_SUPERSAVAGE), 1658697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IX64DDR, S3_SUPERSAVAGE), 1668697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IXCSDR, S3_SUPERSAVAGE), 1678697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_SUPSAV_IXCDDR, S3_SUPERSAVAGE), 1688697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_DDR, S3_PROSAVAGEDDR), 1698697ee19Smrg SAVAGE_DEVICE_MATCH(PCI_CHIP_PROSAVAGE_DDRK, S3_PROSAVAGEDDR), 1708697ee19Smrg 1718697ee19Smrg { 0, 0, 0 }, 172ab47cfaaSmrg}; 1738697ee19Smrg#endif 174ab47cfaaSmrg 175ab47cfaaSmrg/* Supported chipsets */ 176ab47cfaaSmrg 177ab47cfaaSmrgstatic SymTabRec SavageChips[] = { 178ab47cfaaSmrg { PCI_CHIP_SAVAGE4, "Savage4" }, 179ab47cfaaSmrg { PCI_CHIP_SAVAGE3D, "Savage3D" }, 180ab47cfaaSmrg { PCI_CHIP_SAVAGE3D_MV, "Savage3D-MV" }, 181ab47cfaaSmrg { PCI_CHIP_SAVAGE2000, "Savage2000" }, 182ab47cfaaSmrg { PCI_CHIP_SAVAGE_MX_MV, "Savage/MX-MV" }, 183ab47cfaaSmrg { PCI_CHIP_SAVAGE_MX, "Savage/MX" }, 184ab47cfaaSmrg { PCI_CHIP_SAVAGE_IX_MV, "Savage/IX-MV" }, 185ab47cfaaSmrg { PCI_CHIP_SAVAGE_IX, "Savage/IX" }, 186ab47cfaaSmrg { PCI_CHIP_PROSAVAGE_PM, "ProSavage PM133" }, 187ab47cfaaSmrg { PCI_CHIP_PROSAVAGE_KM, "ProSavage KM133" }, 188ab47cfaaSmrg { PCI_CHIP_S3TWISTER_P, "Twister PN133" }, 189ab47cfaaSmrg { PCI_CHIP_S3TWISTER_K, "Twister KN133" }, 190ab47cfaaSmrg { PCI_CHIP_SUPSAV_MX128, "SuperSavage/MX 128" }, 191ab47cfaaSmrg { PCI_CHIP_SUPSAV_MX64, "SuperSavage/MX 64" }, 192ab47cfaaSmrg { PCI_CHIP_SUPSAV_MX64C, "SuperSavage/MX 64C" }, 193ab47cfaaSmrg { PCI_CHIP_SUPSAV_IX128SDR, "SuperSavage/IX 128" }, 194ab47cfaaSmrg { PCI_CHIP_SUPSAV_IX128DDR, "SuperSavage/IX 128" }, 195ab47cfaaSmrg { PCI_CHIP_SUPSAV_IX64SDR, "SuperSavage/IX 64" }, 196ab47cfaaSmrg { PCI_CHIP_SUPSAV_IX64DDR, "SuperSavage/IX 64" }, 197ab47cfaaSmrg { PCI_CHIP_SUPSAV_IXCSDR, "SuperSavage/IXC 64" }, 198ab47cfaaSmrg { PCI_CHIP_SUPSAV_IXCDDR, "SuperSavage/IXC 64" }, 199ab47cfaaSmrg { PCI_CHIP_PROSAVAGE_DDR, "ProSavage DDR" }, 200ab47cfaaSmrg { PCI_CHIP_PROSAVAGE_DDRK, "ProSavage DDR-K" }, 201ab47cfaaSmrg { -1, NULL } 202ab47cfaaSmrg}; 203ab47cfaaSmrg 204ab47cfaaSmrgstatic SymTabRec SavageChipsets[] = { 205ab47cfaaSmrg { S3_SAVAGE3D, "Savage3D" }, 206ab47cfaaSmrg { S3_SAVAGE4, "Savage4" }, 207ab47cfaaSmrg { S3_SAVAGE2000, "Savage2000" }, 208ab47cfaaSmrg { S3_SAVAGE_MX, "MobileSavage" }, 209ab47cfaaSmrg { S3_PROSAVAGE, "ProSavage" }, 210ab47cfaaSmrg { S3_TWISTER, "Twister"}, 211ab47cfaaSmrg { S3_PROSAVAGEDDR, "ProSavageDDR"}, 212ab47cfaaSmrg { S3_SUPERSAVAGE, "SuperSavage" }, 213ab47cfaaSmrg { -1, NULL } 214ab47cfaaSmrg}; 215ab47cfaaSmrg 2168697ee19Smrg#ifndef XSERVER_LIBPCIACCESS 217ab47cfaaSmrg/* This table maps a PCI device ID to a chipset family identifier. */ 218ab47cfaaSmrg 219ab47cfaaSmrgstatic PciChipsets SavagePciChipsets[] = { 220ab47cfaaSmrg { S3_SAVAGE3D, PCI_CHIP_SAVAGE3D, RES_SHARED_VGA }, 221ab47cfaaSmrg { S3_SAVAGE3D, PCI_CHIP_SAVAGE3D_MV, RES_SHARED_VGA }, 222ab47cfaaSmrg { S3_SAVAGE4, PCI_CHIP_SAVAGE4, RES_SHARED_VGA }, 223ab47cfaaSmrg { S3_SAVAGE2000, PCI_CHIP_SAVAGE2000, RES_SHARED_VGA }, 224ab47cfaaSmrg { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_MX_MV, RES_SHARED_VGA }, 225ab47cfaaSmrg { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_MX, RES_SHARED_VGA }, 226ab47cfaaSmrg { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_IX_MV, RES_SHARED_VGA }, 227ab47cfaaSmrg { S3_SAVAGE_MX, PCI_CHIP_SAVAGE_IX, RES_SHARED_VGA }, 228ab47cfaaSmrg { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_PM, RES_SHARED_VGA }, 229ab47cfaaSmrg { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_KM, RES_SHARED_VGA }, 230ab47cfaaSmrg { S3_TWISTER, PCI_CHIP_S3TWISTER_P, RES_SHARED_VGA }, 231ab47cfaaSmrg { S3_TWISTER, PCI_CHIP_S3TWISTER_K, RES_SHARED_VGA }, 232ab47cfaaSmrg { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDR, RES_SHARED_VGA }, 233ab47cfaaSmrg { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDRK, RES_SHARED_VGA }, 234ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX128, RES_SHARED_VGA }, 235ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64, RES_SHARED_VGA }, 236ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64C, RES_SHARED_VGA }, 237ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX128SDR, RES_SHARED_VGA }, 238ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX128DDR, RES_SHARED_VGA }, 239ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX64SDR, RES_SHARED_VGA }, 240ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IX64DDR, RES_SHARED_VGA }, 241ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IXCSDR, RES_SHARED_VGA }, 242ab47cfaaSmrg { S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_IXCDDR, RES_SHARED_VGA }, 243ab47cfaaSmrg { -1, -1, RES_UNDEFINED } 244ab47cfaaSmrg}; 2458697ee19Smrg#endif 246ab47cfaaSmrg 247ab47cfaaSmrgtypedef enum { 248ab47cfaaSmrg OPTION_PCI_BURST 249ab47cfaaSmrg ,OPTION_PCI_RETRY 250ab47cfaaSmrg ,OPTION_NOACCEL 251ab47cfaaSmrg ,OPTION_ACCELMETHOD 252ab47cfaaSmrg ,OPTION_LCD_CENTER 253ab47cfaaSmrg ,OPTION_LCDCLOCK 254ab47cfaaSmrg ,OPTION_MCLK 255ab47cfaaSmrg ,OPTION_REFCLK 256ab47cfaaSmrg ,OPTION_SHOWCACHE 257ab47cfaaSmrg ,OPTION_SWCURSOR 258ab47cfaaSmrg ,OPTION_HWCURSOR 259ab47cfaaSmrg ,OPTION_SHADOW_FB 260ab47cfaaSmrg ,OPTION_ROTATE 261ab47cfaaSmrg ,OPTION_USEBIOS 262ab47cfaaSmrg ,OPTION_SHADOW_STATUS 263ab47cfaaSmrg ,OPTION_CRT_ONLY 264ab47cfaaSmrg ,OPTION_TV_ON 265ab47cfaaSmrg ,OPTION_TV_PAL 266ab47cfaaSmrg ,OPTION_FORCE_INIT 267ab47cfaaSmrg ,OPTION_OVERLAY 268ab47cfaaSmrg ,OPTION_T_KEY 269ab47cfaaSmrg ,OPTION_DISABLE_XVMC 270ab47cfaaSmrg ,OPTION_DISABLE_TILE 271ab47cfaaSmrg ,OPTION_DISABLE_COB 272ab47cfaaSmrg ,OPTION_BCI_FOR_XV 273ab47cfaaSmrg ,OPTION_DVI 274ab47cfaaSmrg ,OPTION_BUS_TYPE 275ab47cfaaSmrg ,OPTION_DMA_TYPE 276ab47cfaaSmrg ,OPTION_DMA_MODE 277ab47cfaaSmrg ,OPTION_AGP_MODE 278ab47cfaaSmrg ,OPTION_AGP_SIZE 279ab47cfaaSmrg ,OPTION_DRI 2808697ee19Smrg ,OPTION_IGNORE_EDID 281ab47cfaaSmrg} SavageOpts; 282ab47cfaaSmrg 283ab47cfaaSmrg 284ab47cfaaSmrgstatic const OptionInfoRec SavageOptions[] = 285ab47cfaaSmrg{ 286ab47cfaaSmrg { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 287ab47cfaaSmrg { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, 288ab47cfaaSmrg { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, 289ab47cfaaSmrg { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, 290ab47cfaaSmrg { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 291ab47cfaaSmrg { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 292ab47cfaaSmrg { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, 293ab47cfaaSmrg { OPTION_LCDCLOCK, "LCDClock", OPTV_FREQ, {0}, FALSE }, 294ab47cfaaSmrg { OPTION_SHADOW_STATUS, "ShadowStatus", OPTV_BOOLEAN, {0}, FALSE }, 295ab47cfaaSmrg { OPTION_CRT_ONLY, "CrtOnly", OPTV_BOOLEAN, {0}, FALSE }, 296ab47cfaaSmrg { OPTION_TV_ON, "TvOn", OPTV_BOOLEAN, {0}, FALSE }, 297ab47cfaaSmrg { OPTION_TV_PAL, "PAL", OPTV_BOOLEAN, {0}, FALSE }, 298ab47cfaaSmrg { OPTION_FORCE_INIT,"ForceInit", OPTV_BOOLEAN, {0}, FALSE }, 299ab47cfaaSmrg { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE }, 300ab47cfaaSmrg { OPTION_T_KEY, "TransparencyKey", OPTV_ANYSTR, {0}, FALSE }, 301ab47cfaaSmrg { OPTION_FORCE_INIT, "ForceInit", OPTV_BOOLEAN, {0}, FALSE }, 302ab47cfaaSmrg { OPTION_DISABLE_XVMC, "DisableXVMC", OPTV_BOOLEAN, {0}, FALSE }, 303ab47cfaaSmrg { OPTION_DISABLE_TILE, "DisableTile", OPTV_BOOLEAN, {0}, FALSE }, 304ab47cfaaSmrg { OPTION_DISABLE_COB, "DisableCOB", OPTV_BOOLEAN, {0}, FALSE }, 305ab47cfaaSmrg { OPTION_BCI_FOR_XV, "BCIforXv", OPTV_BOOLEAN, {0}, FALSE }, 306ab47cfaaSmrg { OPTION_DVI, "DVI", OPTV_BOOLEAN, {0}, FALSE }, 3078697ee19Smrg { OPTION_IGNORE_EDID, "IgnoreEDID", OPTV_BOOLEAN, {0}, FALSE }, 308ab47cfaaSmrg#ifdef XF86DRI 309ab47cfaaSmrg { OPTION_BUS_TYPE, "BusType", OPTV_ANYSTR, {0}, FALSE }, 310ab47cfaaSmrg { OPTION_DMA_TYPE, "DmaType", OPTV_ANYSTR, {0}, FALSE }, 311ab47cfaaSmrg { OPTION_DMA_MODE, "DmaMode", OPTV_ANYSTR, {0}, FALSE }, 312ab47cfaaSmrg { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, 313ab47cfaaSmrg { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, 314ab47cfaaSmrg { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, TRUE }, 315ab47cfaaSmrg#endif 316ab47cfaaSmrg { -1, NULL, OPTV_NONE, {0}, FALSE } 317ab47cfaaSmrg}; 318ab47cfaaSmrg 3198697ee19Smrg_X_EXPORT DriverRec SAVAGE = 3208697ee19Smrg{ 3218697ee19Smrg SAVAGE_VERSION, 3228697ee19Smrg SAVAGE_DRIVER_NAME, 3238697ee19Smrg SavageIdentify, 3248697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 3258697ee19Smrg NULL, 3268697ee19Smrg#else 3278697ee19Smrg SavageProbe, 3288697ee19Smrg#endif 3298697ee19Smrg SavageAvailableOptions, 3308697ee19Smrg NULL, 3318697ee19Smrg 0, 3328697ee19Smrg NULL, 3338697ee19Smrg 3348697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 3358697ee19Smrg savage_device_match, 3368697ee19Smrg SavagePciProbe 3378697ee19Smrg#endif 3388697ee19Smrg}; 3398697ee19Smrg 3408697ee19Smrg 341ab47cfaaSmrg 342ab47cfaaSmrgstatic const char *vgaHWSymbols[] = { 343ab47cfaaSmrg "vgaHWBlankScreen", 344ab47cfaaSmrg "vgaHWCopyReg", 345ab47cfaaSmrg "vgaHWGetHWRec", 346ab47cfaaSmrg "vgaHWGetIOBase", 347ab47cfaaSmrg "vgaHWGetIndex", 348ab47cfaaSmrg "vgaHWInit", 349ab47cfaaSmrg "vgaHWLock", 350ab47cfaaSmrg "vgaHWProtect", 351ab47cfaaSmrg "vgaHWRestore", 352ab47cfaaSmrg "vgaHWSave", 353ab47cfaaSmrg "vgaHWSaveScreen", 354ab47cfaaSmrg "vgaHWSetMmioFuncs", 355ab47cfaaSmrg "vgaHWSetStdFuncs", 356ab47cfaaSmrg "vgaHWUnmapMem", 357ab47cfaaSmrg "vgaHWddc1SetSpeedWeak", 358ab47cfaaSmrg#if 0 359ab47cfaaSmrg "vgaHWFreeHWRec", 360ab47cfaaSmrg "vgaHWMapMem", 361ab47cfaaSmrg "vgaHWUnlock", 362ab47cfaaSmrg#endif 363ab47cfaaSmrg NULL 364ab47cfaaSmrg}; 365ab47cfaaSmrg 366ab47cfaaSmrg#ifdef XF86DRI 367ab47cfaaSmrgstatic const char *drmSymbols[] = { 368ab47cfaaSmrg "drmAvailable", 369ab47cfaaSmrg "drmAddBufs", 370ab47cfaaSmrg "drmAddMap", 371ab47cfaaSmrg "drmCtlInstHandler", 372ab47cfaaSmrg "drmGetInterruptFromBusID", 373ab47cfaaSmrg "drmFreeVersion", 374ab47cfaaSmrg "drmGetVersion", 375ab47cfaaSmrg "drmMap", 376ab47cfaaSmrg "drmUnmap", 377ab47cfaaSmrg "drmMapBufs", 378ab47cfaaSmrg "drmUnmapBufs", 379ab47cfaaSmrg "drmAgpAcquire", 380ab47cfaaSmrg "drmAgpRelease", 381ab47cfaaSmrg "drmAgpEnable", 382ab47cfaaSmrg "drmAgpAlloc", 383ab47cfaaSmrg "drmAgpFree", 384ab47cfaaSmrg "drmAgpBind", 385ab47cfaaSmrg "drmAgpUnbind", 386ab47cfaaSmrg "drmAgpGetMode", 387ab47cfaaSmrg "drmAgpBase", 388ab47cfaaSmrg "drmAgpSize", 389ab47cfaaSmrg "drmAgpVendorId", 390ab47cfaaSmrg "drmAgpDeviceId", 391ab47cfaaSmrg "drmMGAInitDMA", 392ab47cfaaSmrg "drmMGACleanupDMA", 393ab47cfaaSmrg "drmMGAFlushDMA", 394ab47cfaaSmrg "drmMGAEngineReset", 395ab47cfaaSmrg NULL 396ab47cfaaSmrg}; 397ab47cfaaSmrg 398ab47cfaaSmrgstatic const char *driSymbols[] = { 399ab47cfaaSmrg "DRIGetDrawableIndex", 400ab47cfaaSmrg "DRIFinishScreenInit", 401ab47cfaaSmrg "DRIDestroyInfoRec", 402ab47cfaaSmrg "DRICloseScreen", 403ab47cfaaSmrg "DRIDestroyInfoRec", 404ab47cfaaSmrg "DRIScreenInit", 405ab47cfaaSmrg "DRIDestroyInfoRec", 406ab47cfaaSmrg "DRICreateInfoRec", 407ab47cfaaSmrg "DRILock", 408ab47cfaaSmrg "DRIUnlock", 409ab47cfaaSmrg "DRIGetSAREAPrivate", 410ab47cfaaSmrg "DRIGetContext", 411ab47cfaaSmrg "DRIQueryVersion", 412ab47cfaaSmrg "DRIAdjustFrame", 413ab47cfaaSmrg "DRIOpenFullScreen", 414ab47cfaaSmrg "DRICloseFullScreen", 415ab47cfaaSmrg "GlxSetVisualConfigs", 416ab47cfaaSmrg NULL 417ab47cfaaSmrg}; 418ab47cfaaSmrg#endif 419ab47cfaaSmrg 420ab47cfaaSmrg 421ab47cfaaSmrgstatic const char *ramdacSymbols[] = { 422ab47cfaaSmrg "xf86CreateCursorInfoRec", 423ab47cfaaSmrg#if 0 424ab47cfaaSmrg "xf86DestroyCursorInfoRec", 425ab47cfaaSmrg#endif 426ab47cfaaSmrg "xf86InitCursor", 427ab47cfaaSmrg NULL 428ab47cfaaSmrg}; 429ab47cfaaSmrg 430ab47cfaaSmrgstatic const char *int10Symbols[] = { 431ab47cfaaSmrg "xf86ExecX86int10", 432ab47cfaaSmrg "xf86Int10AllocPages", 433ab47cfaaSmrg "xf86int10Addr", 434ab47cfaaSmrg "xf86Int10FreePages" 435ab47cfaaSmrg}; 436ab47cfaaSmrg 437ab47cfaaSmrgstatic const char *vbeSymbols[] = { 438ab47cfaaSmrg "VBEInit", 439ab47cfaaSmrg "vbeDoEDID", 440ab47cfaaSmrg#if 0 441ab47cfaaSmrg "vbeFree", 442ab47cfaaSmrg#endif 443ab47cfaaSmrg NULL 444ab47cfaaSmrg}; 445ab47cfaaSmrg 446ab47cfaaSmrgstatic const char *vbeOptSymbols[] = { 447ab47cfaaSmrg "vbeModeInit", 448ab47cfaaSmrg "VBESetVBEMode", 449ab47cfaaSmrg "VBEGetVBEInfo", 450ab47cfaaSmrg "VBEFreeVBEInfo", 451ab47cfaaSmrg NULL 452ab47cfaaSmrg}; 453ab47cfaaSmrg 454ab47cfaaSmrgstatic const char *ddcSymbols[] = { 455ab47cfaaSmrg "xf86DoEDID_DDC1", 456ab47cfaaSmrg "xf86DoEDID_DDC2", 457ab47cfaaSmrg "xf86PrintEDID", 458ab47cfaaSmrg "xf86SetDDCproperties", 459ab47cfaaSmrg NULL 460ab47cfaaSmrg}; 461ab47cfaaSmrg 462ab47cfaaSmrgstatic const char *i2cSymbols[] = { 463ab47cfaaSmrg "xf86CreateI2CBusRec", 464ab47cfaaSmrg "xf86I2CBusInit", 465ab47cfaaSmrg "xf86CreateI2CDevRec", 466ab47cfaaSmrg "xf86I2CDevInit", 467ab47cfaaSmrg "xf86I2CWriteByte", 468ab47cfaaSmrg "xf86I2CWriteBytes", 469ab47cfaaSmrg "xf86I2CReadByte", 470ab47cfaaSmrg "xf86I2CReadBytes", 471ab47cfaaSmrg "xf86I2CWriteRead", 472ab47cfaaSmrg "xf86DestroyI2CDevRec", 473ab47cfaaSmrg NULL 474ab47cfaaSmrg}; 475ab47cfaaSmrg 476ab47cfaaSmrgstatic const char *xaaSymbols[] = { 477ab47cfaaSmrg "XAAGetCopyROP", 478ab47cfaaSmrg "XAAGetCopyROP_PM", 479ab47cfaaSmrg "XAACreateInfoRec", 480ab47cfaaSmrg "XAADestroyInfoRec", 481ab47cfaaSmrg "XAAFillSolidRects", 482ab47cfaaSmrg "XAAHelpPatternROP", 483ab47cfaaSmrg "XAAHelpSolidROP", 484ab47cfaaSmrg "XAAInit", 485ab47cfaaSmrg "XAAScreenIndex", 486ab47cfaaSmrg NULL 487ab47cfaaSmrg}; 488ab47cfaaSmrg 489ab47cfaaSmrgstatic const char *exaSymbols[] = { 490ab47cfaaSmrg "exaDriverAlloc", 491ab47cfaaSmrg "exaDriverInit", 492ab47cfaaSmrg "exaDriverFini", 493ab47cfaaSmrg "exaOffscreenAlloc", 494ab47cfaaSmrg "exaOffscreenFree", 495ab47cfaaSmrg "exaGetPixmapOffset", 496ab47cfaaSmrg "exaGetPixmapPitch", 497ab47cfaaSmrg "exaGetPixmapSize", 498ab47cfaaSmrg NULL 499ab47cfaaSmrg}; 500ab47cfaaSmrg 501ab47cfaaSmrgstatic const char *shadowSymbols[] = { 502ab47cfaaSmrg "ShadowFBInit", 503ab47cfaaSmrg NULL 504ab47cfaaSmrg}; 505ab47cfaaSmrg 506ab47cfaaSmrgstatic const char *fbSymbols[] = { 507ab47cfaaSmrg "fbPictureInit", 508ab47cfaaSmrg "fbScreenInit", 509ab47cfaaSmrg NULL 510ab47cfaaSmrg}; 511ab47cfaaSmrg 512ab47cfaaSmrg#ifdef XFree86LOADER 513ab47cfaaSmrg 514ab47cfaaSmrgstatic MODULESETUPPROTO(SavageSetup); 515ab47cfaaSmrg 516ab47cfaaSmrgstatic XF86ModuleVersionInfo SavageVersRec = { 517ab47cfaaSmrg "savage", 518ab47cfaaSmrg MODULEVENDORSTRING, 519ab47cfaaSmrg MODINFOSTRING1, 520ab47cfaaSmrg MODINFOSTRING2, 521ab47cfaaSmrg XORG_VERSION_CURRENT, 522ab47cfaaSmrg SAVAGE_VERSION_MAJOR, SAVAGE_VERSION_MINOR, SAVAGE_PATCHLEVEL, 523ab47cfaaSmrg ABI_CLASS_VIDEODRV, 524ab47cfaaSmrg ABI_VIDEODRV_VERSION, 525ab47cfaaSmrg MOD_CLASS_VIDEODRV, 526ab47cfaaSmrg {0, 0, 0, 0} 527ab47cfaaSmrg}; 528ab47cfaaSmrg 529ab47cfaaSmrg_X_EXPORT XF86ModuleData savageModuleData = { 530ab47cfaaSmrg &SavageVersRec, 531ab47cfaaSmrg SavageSetup, 532ab47cfaaSmrg NULL 533ab47cfaaSmrg}; 534ab47cfaaSmrg 535ab47cfaaSmrgstatic pointer SavageSetup(pointer module, pointer opts, int *errmaj, 536ab47cfaaSmrg int *errmin) 537ab47cfaaSmrg{ 538ab47cfaaSmrg static Bool setupDone = FALSE; 539ab47cfaaSmrg 540ab47cfaaSmrg if (!setupDone) { 541ab47cfaaSmrg setupDone = TRUE; 542ab47cfaaSmrg xf86AddDriver(&SAVAGE, module, 1); 543ab47cfaaSmrg LoaderRefSymLists(vgaHWSymbols, fbSymbols, ramdacSymbols, 544ab47cfaaSmrg xaaSymbols, 545ab47cfaaSmrg exaSymbols, 546ab47cfaaSmrg shadowSymbols, vbeSymbols, vbeOptSymbols, 547ab47cfaaSmrg#ifdef XF86DRI 548ab47cfaaSmrg drmSymbols, driSymbols, 549ab47cfaaSmrg#endif 550ab47cfaaSmrg int10Symbols, i2cSymbols, ddcSymbols, NULL); 551ab47cfaaSmrg return (pointer) 1; 552ab47cfaaSmrg } else { 553ab47cfaaSmrg if (errmaj) 554ab47cfaaSmrg *errmaj = LDR_ONCEONLY; 555ab47cfaaSmrg return NULL; 556ab47cfaaSmrg } 557ab47cfaaSmrg} 558ab47cfaaSmrg 559ab47cfaaSmrg#endif /* XFree86LOADER */ 560ab47cfaaSmrg 561ab47cfaaSmrgstatic SavageEntPtr SavageEntPriv(ScrnInfoPtr pScrn) 562ab47cfaaSmrg{ 563ab47cfaaSmrg DevUnion *pPriv; 564ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 565ab47cfaaSmrg pPriv = xf86GetEntityPrivate(psav->pEnt->index, 566ab47cfaaSmrg gSavageEntityIndex); 567ab47cfaaSmrg return pPriv->ptr; 568ab47cfaaSmrg} 569ab47cfaaSmrg 570ab47cfaaSmrg 571ab47cfaaSmrg/* 572ab47cfaaSmrg * I'd rather have these wait macros be inline, but S3 has made it 573ab47cfaaSmrg * darned near impossible. The bit fields are in a different place in 574ab47cfaaSmrg * all three families, the status register has a different address in the 575ab47cfaaSmrg * three families, and even the idle vs busy sense flipped in the Sav2K. 576ab47cfaaSmrg */ 577ab47cfaaSmrg 578ab47cfaaSmrgstatic void 579ab47cfaaSmrgResetBCI2K( SavagePtr psav ) 580ab47cfaaSmrg{ 581ab47cfaaSmrg CARD32 cob = INREG( 0x48c18 ); 582ab47cfaaSmrg /* if BCI is enabled and BCI is busy... */ 583ab47cfaaSmrg 584ab47cfaaSmrg if( 585ab47cfaaSmrg (cob & 0x00000008) && 586ab47cfaaSmrg ! (ALT_STATUS_WORD0 & 0x00200000) 587ab47cfaaSmrg ) 588ab47cfaaSmrg { 589ab47cfaaSmrg ErrorF( "Resetting BCI, stat = %08lx...\n", 590ab47cfaaSmrg (unsigned long) ALT_STATUS_WORD0); 591ab47cfaaSmrg /* Turn off BCI */ 592ab47cfaaSmrg OUTREG( 0x48c18, cob & ~8 ); 593ab47cfaaSmrg usleep(10000); 594ab47cfaaSmrg /* Turn it back on */ 595ab47cfaaSmrg OUTREG( 0x48c18, cob ); 596ab47cfaaSmrg usleep(10000); 597ab47cfaaSmrg } 598ab47cfaaSmrg} 599ab47cfaaSmrg 600ab47cfaaSmrgstatic Bool 601ab47cfaaSmrgShadowWait( SavagePtr psav ) 602ab47cfaaSmrg{ 603ab47cfaaSmrg BCI_GET_PTR; 604ab47cfaaSmrg int loop = 0; 605ab47cfaaSmrg 606ab47cfaaSmrg if( !psav->NoPCIRetry ) 607ab47cfaaSmrg return 0; 608ab47cfaaSmrg 609ab47cfaaSmrg psav->ShadowCounter = (psav->ShadowCounter + 1) & 0xffff; 610ab47cfaaSmrg if (psav->ShadowCounter == 0) 611ab47cfaaSmrg psav->ShadowCounter++; /* 0 is reserved for the BIOS 612ab47cfaaSmrg to avoid confusion in the DRM */ 613ab47cfaaSmrg BCI_SEND( psav->dwBCIWait2DIdle ); 614ab47cfaaSmrg BCI_SEND( 0x98000000 + psav->ShadowCounter ); 615ab47cfaaSmrg 616ab47cfaaSmrg while( 617ab47cfaaSmrg (int)(psav->ShadowVirtual[psav->eventStatusReg] & 0xffff) != 618ab47cfaaSmrg psav->ShadowCounter && (loop++ < MAXLOOP) 619ab47cfaaSmrg ) 620ab47cfaaSmrg ; 621ab47cfaaSmrg 622ab47cfaaSmrg return loop >= MAXLOOP; 623ab47cfaaSmrg} 624ab47cfaaSmrg 625ab47cfaaSmrgstatic Bool 626ab47cfaaSmrgShadowWaitQueue( SavagePtr psav, int v ) 627ab47cfaaSmrg{ 628ab47cfaaSmrg int loop = 0; 629ab47cfaaSmrg CARD32 slots = MAXFIFO - v; 630ab47cfaaSmrg 631ab47cfaaSmrg if (slots >= psav->bciThresholdHi) 632ab47cfaaSmrg slots = psav->bciThresholdHi; 633ab47cfaaSmrg else 634ab47cfaaSmrg return ShadowWait( psav ); 635ab47cfaaSmrg 636ab47cfaaSmrg /* Savage 2000 reports only entries filled in the COB, not the on-chip 637ab47cfaaSmrg * queue. Also it reports in qword units instead of dwords. */ 638ab47cfaaSmrg if (psav->Chipset == S3_SAVAGE2000) 639ab47cfaaSmrg slots = (slots - 32) / 4; 640ab47cfaaSmrg 641ab47cfaaSmrg while( ((psav->ShadowVirtual[0] & psav->bciUsedMask) >= slots) && (loop++ < MAXLOOP)) 642ab47cfaaSmrg ; 643ab47cfaaSmrg 644ab47cfaaSmrg return loop >= MAXLOOP; 645ab47cfaaSmrg} 646ab47cfaaSmrg 647ab47cfaaSmrg/* Wait until "v" queue entries are free */ 648ab47cfaaSmrg 649ab47cfaaSmrgstatic int 650ab47cfaaSmrgWaitQueue3D( SavagePtr psav, int v ) 651ab47cfaaSmrg{ 652ab47cfaaSmrg int loop = 0; 653ab47cfaaSmrg CARD32 slots = MAXFIFO - v; 654ab47cfaaSmrg 655ab47cfaaSmrg mem_barrier(); 656ab47cfaaSmrg if( psav->ShadowVirtual ) 657ab47cfaaSmrg { 658ab47cfaaSmrg psav->WaitQueue = ShadowWaitQueue; 659ab47cfaaSmrg return ShadowWaitQueue(psav, v); 660ab47cfaaSmrg } 661ab47cfaaSmrg else 662ab47cfaaSmrg { 663ab47cfaaSmrg loop &= STATUS_WORD0; 664ab47cfaaSmrg while( ((STATUS_WORD0 & 0x0000ffff) > slots) && (loop++ < MAXLOOP)) 665ab47cfaaSmrg ; 666ab47cfaaSmrg } 667ab47cfaaSmrg return loop >= MAXLOOP; 668ab47cfaaSmrg} 669ab47cfaaSmrg 670ab47cfaaSmrgstatic int 671ab47cfaaSmrgWaitQueue4( SavagePtr psav, int v ) 672ab47cfaaSmrg{ 673ab47cfaaSmrg int loop = 0; 674ab47cfaaSmrg CARD32 slots = MAXFIFO - v; 675ab47cfaaSmrg 676ab47cfaaSmrg if( !psav->NoPCIRetry ) 677ab47cfaaSmrg return 0; 678ab47cfaaSmrg mem_barrier(); 679ab47cfaaSmrg if( psav->ShadowVirtual ) 680ab47cfaaSmrg { 681ab47cfaaSmrg psav->WaitQueue = ShadowWaitQueue; 682ab47cfaaSmrg return ShadowWaitQueue(psav, v); 683ab47cfaaSmrg } 684ab47cfaaSmrg else 685ab47cfaaSmrg while( ((ALT_STATUS_WORD0 & 0x001fffff) > slots) && (loop++ < MAXLOOP)); 686ab47cfaaSmrg return loop >= MAXLOOP; 687ab47cfaaSmrg} 688ab47cfaaSmrg 689ab47cfaaSmrgstatic int 690ab47cfaaSmrgWaitQueue2K( SavagePtr psav, int v ) 691ab47cfaaSmrg{ 692ab47cfaaSmrg int loop = 0; 693ab47cfaaSmrg CARD32 slots = (MAXFIFO - v) / 4; 694ab47cfaaSmrg 695ab47cfaaSmrg if( !psav->NoPCIRetry ) 696ab47cfaaSmrg return 0; 697ab47cfaaSmrg mem_barrier(); 698ab47cfaaSmrg if( psav->ShadowVirtual ) 699ab47cfaaSmrg { 700ab47cfaaSmrg psav->WaitQueue = ShadowWaitQueue; 701ab47cfaaSmrg return ShadowWaitQueue(psav, v); 702ab47cfaaSmrg } 703ab47cfaaSmrg else 704ab47cfaaSmrg while( ((ALT_STATUS_WORD0 & 0x000fffff) > slots) && (loop++ < MAXLOOP)) 705ab47cfaaSmrg ; 706ab47cfaaSmrg if( loop >= MAXLOOP ) 707ab47cfaaSmrg ResetBCI2K(psav); 708ab47cfaaSmrg return loop >= MAXLOOP; 709ab47cfaaSmrg} 710ab47cfaaSmrg 711ab47cfaaSmrg/* Wait until GP is idle and queue is empty */ 712ab47cfaaSmrg 713ab47cfaaSmrgstatic int 714ab47cfaaSmrgWaitIdleEmpty3D(SavagePtr psav) 715ab47cfaaSmrg{ 716ab47cfaaSmrg int loop = 0; 717ab47cfaaSmrg mem_barrier(); 718ab47cfaaSmrg if( psav->ShadowVirtual ) 719ab47cfaaSmrg { 720ab47cfaaSmrg psav->WaitIdleEmpty = ShadowWait; 721ab47cfaaSmrg return ShadowWait(psav); 722ab47cfaaSmrg } 723ab47cfaaSmrg loop &= STATUS_WORD0; 724ab47cfaaSmrg while( ((STATUS_WORD0 & 0x0008ffff) != 0x80000) && (loop++ < MAXLOOP) ); 725ab47cfaaSmrg return loop >= MAXLOOP; 726ab47cfaaSmrg} 727ab47cfaaSmrg 728ab47cfaaSmrgstatic int 729ab47cfaaSmrgWaitIdleEmpty4(SavagePtr psav) 730ab47cfaaSmrg{ 731ab47cfaaSmrg int loop = 0; 732ab47cfaaSmrg mem_barrier(); 733ab47cfaaSmrg if( psav->ShadowVirtual ) 734ab47cfaaSmrg { 735ab47cfaaSmrg psav->WaitIdleEmpty = ShadowWait; 736ab47cfaaSmrg return ShadowWait(psav); 737ab47cfaaSmrg } 738ab47cfaaSmrg /* which is right?*/ 739ab47cfaaSmrg /*while( ((ALT_STATUS_WORD0 & 0x00a1ffff) != 0x00a00000) && (loop++ < MAXLOOP) );*/ /* tim */ 740ab47cfaaSmrg while (((ALT_STATUS_WORD0 & 0x00e1ffff) != 0x00e00000) && (loop++ < MAXLOOP)); /* S3 */ 741ab47cfaaSmrg return loop >= MAXLOOP; 742ab47cfaaSmrg} 743ab47cfaaSmrg 744ab47cfaaSmrgstatic int 745ab47cfaaSmrgWaitIdleEmpty2K(SavagePtr psav) 746ab47cfaaSmrg{ 747ab47cfaaSmrg int loop = 0; 748ab47cfaaSmrg mem_barrier(); 749ab47cfaaSmrg if( psav->ShadowVirtual ) 750ab47cfaaSmrg { 751ab47cfaaSmrg psav->WaitIdleEmpty = ShadowWait; 752ab47cfaaSmrg return ShadowWait(psav); 753ab47cfaaSmrg } 754ab47cfaaSmrg loop &= ALT_STATUS_WORD0; 755ab47cfaaSmrg while( ((ALT_STATUS_WORD0 & 0x009fffff) != 0) && (loop++ < MAXLOOP) ); 756ab47cfaaSmrg if( loop >= MAXLOOP ) 757ab47cfaaSmrg ResetBCI2K(psav); 758ab47cfaaSmrg return loop >= MAXLOOP; 759ab47cfaaSmrg} 760ab47cfaaSmrg 761ab47cfaaSmrg/* Wait until GP is idle */ 762ab47cfaaSmrg 763ab47cfaaSmrgstatic int 764ab47cfaaSmrgWaitIdle3D(SavagePtr psav) 765ab47cfaaSmrg{ 766ab47cfaaSmrg int loop = 0; 767ab47cfaaSmrg mem_barrier(); 768ab47cfaaSmrg if( psav->ShadowVirtual ) 769ab47cfaaSmrg { 770ab47cfaaSmrg psav->WaitIdle = ShadowWait; 771ab47cfaaSmrg return ShadowWait(psav); 772ab47cfaaSmrg } 773ab47cfaaSmrg while( (!(STATUS_WORD0 & 0x00080000)) && (loop++ < MAXLOOP) ); 774ab47cfaaSmrg return loop >= MAXLOOP; 775ab47cfaaSmrg} 776ab47cfaaSmrg 777ab47cfaaSmrgstatic int 778ab47cfaaSmrgWaitIdle4(SavagePtr psav) 779ab47cfaaSmrg{ 780ab47cfaaSmrg int loop = 0; 781ab47cfaaSmrg mem_barrier(); 782ab47cfaaSmrg if( psav->ShadowVirtual ) 783ab47cfaaSmrg { 784ab47cfaaSmrg psav->WaitIdle = ShadowWait; 785ab47cfaaSmrg return ShadowWait(psav); 786ab47cfaaSmrg } 787ab47cfaaSmrg /* which is right?*/ 788ab47cfaaSmrg /*while( (!(ALT_STATUS_WORD0 & 0x00800000)) && (loop++ < MAXLOOP) );*/ /* tim */ 789ab47cfaaSmrg while (((ALT_STATUS_WORD0 & 0x00E00000)!=0x00E00000) && (loop++ < MAXLOOP)); /* S3 */ 790ab47cfaaSmrg return loop >= MAXLOOP; 791ab47cfaaSmrg} 792ab47cfaaSmrg 793ab47cfaaSmrgstatic int 794ab47cfaaSmrgWaitIdle2K(SavagePtr psav) 795ab47cfaaSmrg{ 796ab47cfaaSmrg int loop = 0; 797ab47cfaaSmrg mem_barrier(); 798ab47cfaaSmrg if( psav->ShadowVirtual ) 799ab47cfaaSmrg { 800ab47cfaaSmrg psav->WaitIdle = ShadowWait; 801ab47cfaaSmrg return ShadowWait(psav); 802ab47cfaaSmrg } 803ab47cfaaSmrg loop &= ALT_STATUS_WORD0; 804ab47cfaaSmrg while( (ALT_STATUS_WORD0 & 0x00900000) && (loop++ < MAXLOOP) ); 805ab47cfaaSmrg return loop >= MAXLOOP; 806ab47cfaaSmrg} 807ab47cfaaSmrg 808ab47cfaaSmrg 809ab47cfaaSmrgstatic Bool SavageGetRec(ScrnInfoPtr pScrn) 810ab47cfaaSmrg{ 811ab47cfaaSmrg if (pScrn->driverPrivate) 812ab47cfaaSmrg return TRUE; 813ab47cfaaSmrg 814ab47cfaaSmrg pScrn->driverPrivate = xnfcalloc(sizeof(SavageRec), 1); 815ab47cfaaSmrg return TRUE; 816ab47cfaaSmrg} 817ab47cfaaSmrg 818ab47cfaaSmrg 819ab47cfaaSmrgstatic void SavageFreeRec(ScrnInfoPtr pScrn) 820ab47cfaaSmrg{ 821ab47cfaaSmrg TRACE(( "SavageFreeRec(%x)\n", pScrn->driverPrivate )); 822ab47cfaaSmrg if (!pScrn->driverPrivate) 823ab47cfaaSmrg return; 824ab47cfaaSmrg SavageUnmapMem(pScrn, 1); 825ab47cfaaSmrg xfree(pScrn->driverPrivate); 826ab47cfaaSmrg pScrn->driverPrivate = NULL; 827ab47cfaaSmrg} 828ab47cfaaSmrg 829ab47cfaaSmrg 830ab47cfaaSmrgstatic const OptionInfoRec * SavageAvailableOptions(int chipid, int busid) 831ab47cfaaSmrg{ 832ab47cfaaSmrg return SavageOptions; 833ab47cfaaSmrg} 834ab47cfaaSmrg 835ab47cfaaSmrg 836ab47cfaaSmrgstatic void SavageIdentify(int flags) 837ab47cfaaSmrg{ 838ab47cfaaSmrg xf86PrintChipsets("SAVAGE", 839ab47cfaaSmrg "driver (version " SAVAGE_DRIVER_VERSION ") for S3 Savage chipsets", 840ab47cfaaSmrg SavageChips); 841ab47cfaaSmrg} 842ab47cfaaSmrg 843ab47cfaaSmrg 8448697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 8458697ee19Smrgstatic Bool SavagePciProbe(DriverPtr drv, int entity_num, 8468697ee19Smrg struct pci_device *dev, intptr_t match_data) 8478697ee19Smrg{ 8488697ee19Smrg ScrnInfoPtr pScrn; 8498697ee19Smrg 8508697ee19Smrg 8518697ee19Smrg if ((match_data < S3_SAVAGE3D) || (match_data > S3_SAVAGE2000)) { 8528697ee19Smrg return FALSE; 8538697ee19Smrg } 8548697ee19Smrg 8558697ee19Smrg pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, 8568697ee19Smrg RES_SHARED_VGA, NULL, NULL, NULL, NULL); 8578697ee19Smrg if (pScrn != NULL) { 8588697ee19Smrg EntityInfoPtr pEnt; 8598697ee19Smrg SavagePtr psav; 8608697ee19Smrg 8618697ee19Smrg 8628697ee19Smrg pScrn->driverVersion = SAVAGE_VERSION; 8638697ee19Smrg pScrn->driverName = SAVAGE_DRIVER_NAME; 8648697ee19Smrg pScrn->name = "SAVAGE"; 8658697ee19Smrg pScrn->Probe = NULL; 8668697ee19Smrg pScrn->PreInit = SavagePreInit; 8678697ee19Smrg pScrn->ScreenInit = SavageScreenInit; 8688697ee19Smrg pScrn->SwitchMode = SavageSwitchMode; 8698697ee19Smrg pScrn->AdjustFrame = SavageAdjustFrame; 8708697ee19Smrg pScrn->EnterVT = SavageEnterVT; 8718697ee19Smrg pScrn->LeaveVT = SavageLeaveVT; 8728697ee19Smrg pScrn->FreeScreen = NULL; 8738697ee19Smrg pScrn->ValidMode = SavageValidMode; 8748697ee19Smrg 8758697ee19Smrg if (!SavageGetRec(pScrn)) 8768697ee19Smrg return FALSE; 8778697ee19Smrg 8788697ee19Smrg psav = SAVPTR(pScrn); 8798697ee19Smrg 8808697ee19Smrg psav->PciInfo = dev; 8818697ee19Smrg psav->Chipset = match_data; 8828697ee19Smrg 8838697ee19Smrg pEnt = xf86GetEntityInfo(entity_num); 8848697ee19Smrg 8858697ee19Smrg /* MX, IX, SuperSavage cards support Dual-Head, mark the entity as 8868697ee19Smrg * sharable. 8878697ee19Smrg */ 8888697ee19Smrg if (pEnt->chipset == S3_SAVAGE_MX || pEnt->chipset == S3_SUPERSAVAGE) { 8898697ee19Smrg DevUnion *pPriv; 8908697ee19Smrg SavageEntPtr pSavageEnt; 8918697ee19Smrg 8928697ee19Smrg xf86SetEntitySharable(entity_num); 8938697ee19Smrg 8948697ee19Smrg if (gSavageEntityIndex == -1) 8958697ee19Smrg gSavageEntityIndex = xf86AllocateEntityPrivateIndex(); 8968697ee19Smrg 8978697ee19Smrg pPriv = xf86GetEntityPrivate(pEnt->index, gSavageEntityIndex); 8988697ee19Smrg if (!pPriv->ptr) { 8998697ee19Smrg int j; 9008697ee19Smrg int instance = xf86GetNumEntityInstances(pEnt->index); 9018697ee19Smrg 9028697ee19Smrg for (j = 0; j < instance; j++) 9038697ee19Smrg xf86SetEntityInstanceForScreen(pScrn, pEnt->index, j); 9048697ee19Smrg 9058697ee19Smrg pPriv->ptr = xnfcalloc(sizeof(SavageEntRec), 1); 9068697ee19Smrg pSavageEnt = pPriv->ptr; 9078697ee19Smrg pSavageEnt->HasSecondary = FALSE; 9088697ee19Smrg } else { 9098697ee19Smrg pSavageEnt = pPriv->ptr; 9108697ee19Smrg pSavageEnt->HasSecondary = TRUE; 9118697ee19Smrg } 9128697ee19Smrg } 9138697ee19Smrg } 9148697ee19Smrg 9158697ee19Smrg return (pScrn != NULL); 9168697ee19Smrg} 9178697ee19Smrg 9188697ee19Smrg#else 9198697ee19Smrg 920ab47cfaaSmrgstatic Bool SavageProbe(DriverPtr drv, int flags) 921ab47cfaaSmrg{ 922ab47cfaaSmrg int i; 923ab47cfaaSmrg GDevPtr *devSections = NULL; 924ab47cfaaSmrg int *usedChips; 925ab47cfaaSmrg int numDevSections; 926ab47cfaaSmrg int numUsed; 927ab47cfaaSmrg Bool foundScreen = FALSE; 928ab47cfaaSmrg 929ab47cfaaSmrg /* sanity checks */ 930ab47cfaaSmrg if ((numDevSections = xf86MatchDevice("savage", &devSections)) <= 0) 931ab47cfaaSmrg return FALSE; 932ab47cfaaSmrg if (xf86GetPciVideoInfo() == NULL) { 933ab47cfaaSmrg if (devSections) 934ab47cfaaSmrg xfree(devSections); 935ab47cfaaSmrg return FALSE; 936ab47cfaaSmrg } 937ab47cfaaSmrg 938ab47cfaaSmrg numUsed = xf86MatchPciInstances("SAVAGE", PCI_VENDOR_S3, 939ab47cfaaSmrg SavageChipsets, SavagePciChipsets, 940ab47cfaaSmrg devSections, numDevSections, drv, 941ab47cfaaSmrg &usedChips); 942ab47cfaaSmrg if (devSections) 943ab47cfaaSmrg xfree(devSections); 944ab47cfaaSmrg devSections = NULL; 945ab47cfaaSmrg if (numUsed <= 0) 946ab47cfaaSmrg return FALSE; 947ab47cfaaSmrg 948ab47cfaaSmrg if (flags & PROBE_DETECT) 949ab47cfaaSmrg foundScreen = TRUE; 950ab47cfaaSmrg else 951ab47cfaaSmrg for (i=0; i<numUsed; i++) { 952ab47cfaaSmrg EntityInfoPtr pEnt = xf86GetEntityInfo(usedChips[i]);; 953ab47cfaaSmrg ScrnInfoPtr pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i], 954ab47cfaaSmrg NULL, RES_SHARED_VGA, 955ab47cfaaSmrg NULL, NULL, NULL, NULL); 956ab47cfaaSmrg 957ab47cfaaSmrg if (pScrn != NULL) { 9588697ee19Smrg SavagePtr psav; 9598697ee19Smrg 960ab47cfaaSmrg pScrn->driverVersion = SAVAGE_VERSION; 961ab47cfaaSmrg pScrn->driverName = SAVAGE_DRIVER_NAME; 962ab47cfaaSmrg pScrn->name = "SAVAGE"; 963ab47cfaaSmrg pScrn->Probe = SavageProbe; 964ab47cfaaSmrg pScrn->PreInit = SavagePreInit; 965ab47cfaaSmrg pScrn->ScreenInit = SavageScreenInit; 966ab47cfaaSmrg pScrn->SwitchMode = SavageSwitchMode; 967ab47cfaaSmrg pScrn->AdjustFrame = SavageAdjustFrame; 968ab47cfaaSmrg pScrn->EnterVT = SavageEnterVT; 969ab47cfaaSmrg pScrn->LeaveVT = SavageLeaveVT; 970ab47cfaaSmrg pScrn->FreeScreen = NULL; 971ab47cfaaSmrg pScrn->ValidMode = SavageValidMode; 972ab47cfaaSmrg foundScreen = TRUE; 9738697ee19Smrg 9748697ee19Smrg if (!SavageGetRec(pScrn)) 9758697ee19Smrg return FALSE; 9768697ee19Smrg 9778697ee19Smrg psav = SAVPTR(pScrn); 9788697ee19Smrg 9798697ee19Smrg psav->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 9808697ee19Smrg if (pEnt->device->chipset && *pEnt->device->chipset) { 9818697ee19Smrg psav->Chipset = xf86StringToToken(SavageChipsets, 9828697ee19Smrg pEnt->device->chipset); 9838697ee19Smrg } else if (pEnt->device->chipID >= 0) { 9848697ee19Smrg psav->Chipset = LookupChipID(SavagePciChipsets, 9858697ee19Smrg pEnt->device->chipID); 9868697ee19Smrg } else { 9878697ee19Smrg psav->Chipset = LookupChipID(SavagePciChipsets, 9888697ee19Smrg psav->PciInfo->chipType); 9898697ee19Smrg } 990ab47cfaaSmrg } 991ab47cfaaSmrg 992ab47cfaaSmrg pEnt = xf86GetEntityInfo(usedChips[i]); 993ab47cfaaSmrg 994ab47cfaaSmrg /* MX, IX, SuperSavage cards support Dual-Head, mark the entity as sharable*/ 995ab47cfaaSmrg if(pEnt->chipset == S3_SAVAGE_MX || pEnt->chipset == S3_SUPERSAVAGE) 996ab47cfaaSmrg { 997ab47cfaaSmrg DevUnion *pPriv; 998ab47cfaaSmrg SavageEntPtr pSavageEnt; 999ab47cfaaSmrg 1000ab47cfaaSmrg xf86SetEntitySharable(usedChips[i]); 1001ab47cfaaSmrg 1002ab47cfaaSmrg if (gSavageEntityIndex == -1) 1003ab47cfaaSmrg gSavageEntityIndex = xf86AllocateEntityPrivateIndex(); 1004ab47cfaaSmrg 1005ab47cfaaSmrg pPriv = xf86GetEntityPrivate(pEnt->index, 1006ab47cfaaSmrg gSavageEntityIndex); 1007ab47cfaaSmrg 1008ab47cfaaSmrg if (!pPriv->ptr) { 1009ab47cfaaSmrg int j; 1010ab47cfaaSmrg int instance = xf86GetNumEntityInstances(pEnt->index); 1011ab47cfaaSmrg 1012ab47cfaaSmrg for (j = 0; j < instance; j++) 1013ab47cfaaSmrg xf86SetEntityInstanceForScreen(pScrn, pEnt->index, j); 1014ab47cfaaSmrg 1015ab47cfaaSmrg pPriv->ptr = xnfcalloc(sizeof(SavageEntRec), 1); 1016ab47cfaaSmrg pSavageEnt = pPriv->ptr; 1017ab47cfaaSmrg pSavageEnt->HasSecondary = FALSE; 1018ab47cfaaSmrg } else { 1019ab47cfaaSmrg pSavageEnt = pPriv->ptr; 1020ab47cfaaSmrg pSavageEnt->HasSecondary = TRUE; 1021ab47cfaaSmrg } 1022ab47cfaaSmrg } 1023ab47cfaaSmrg xfree(pEnt); 1024ab47cfaaSmrg } 1025ab47cfaaSmrg 1026ab47cfaaSmrg 1027ab47cfaaSmrg xfree(usedChips); 1028ab47cfaaSmrg return foundScreen; 1029ab47cfaaSmrg} 1030ab47cfaaSmrg 1031ab47cfaaSmrgstatic int LookupChipID( PciChipsets* pset, int ChipID ) 1032ab47cfaaSmrg{ 1033ab47cfaaSmrg /* Is there a function to do this for me? */ 1034ab47cfaaSmrg while( pset->numChipset >= 0 ) 1035ab47cfaaSmrg { 1036ab47cfaaSmrg if( pset->PCIid == ChipID ) 1037ab47cfaaSmrg return pset->numChipset; 1038ab47cfaaSmrg pset++; 1039ab47cfaaSmrg } 1040ab47cfaaSmrg 1041ab47cfaaSmrg return -1; 1042ab47cfaaSmrg} 10438697ee19Smrg#endif 1044ab47cfaaSmrg 1045ab47cfaaSmrgstatic void SavageDoDDC(ScrnInfoPtr pScrn) 1046ab47cfaaSmrg{ 1047ab47cfaaSmrg SavagePtr psav= SAVPTR(pScrn); 1048ab47cfaaSmrg pointer ddc; 1049ab47cfaaSmrg 1050ab47cfaaSmrg /* Do the DDC dance. */ /* S3/VIA's DDC code */ 1051ab47cfaaSmrg ddc = xf86LoadSubModule(pScrn, "ddc"); 1052ab47cfaaSmrg if (ddc) { 1053ab47cfaaSmrg xf86LoaderReqSymLists(ddcSymbols, NULL); 1054ab47cfaaSmrg switch( psav->Chipset ) { 1055ab47cfaaSmrg case S3_SAVAGE3D: 1056ab47cfaaSmrg case S3_SAVAGE_MX: 1057ab47cfaaSmrg case S3_SUPERSAVAGE: 1058ab47cfaaSmrg case S3_SAVAGE2000: 1059ab47cfaaSmrg psav->DDCPort = 0xAA; 1060ab47cfaaSmrg psav->I2CPort = 0xA0; 1061ab47cfaaSmrg break; 1062ab47cfaaSmrg 1063ab47cfaaSmrg case S3_SAVAGE4: 1064ab47cfaaSmrg case S3_PROSAVAGE: 1065ab47cfaaSmrg case S3_TWISTER: 1066ab47cfaaSmrg case S3_PROSAVAGEDDR: 1067ab47cfaaSmrg psav->DDCPort = 0xB1; 1068ab47cfaaSmrg psav->I2CPort = 0xA0; 1069ab47cfaaSmrg break; 1070ab47cfaaSmrg } 1071ab47cfaaSmrg 1072ab47cfaaSmrg if (!SavageDDC1(pScrn->scrnIndex)) { 1073ab47cfaaSmrg /* DDC1 failed,switch to DDC2 */ 1074ab47cfaaSmrg if (xf86LoadSubModule(pScrn, "i2c")) { 1075ab47cfaaSmrg xf86LoaderReqSymLists(i2cSymbols,NULL); 1076ab47cfaaSmrg if (SavageI2CInit(pScrn)) { 1077ab47cfaaSmrg unsigned char tmp; 10788697ee19Smrg xf86MonPtr pMon; 1079ab47cfaaSmrg 1080ab47cfaaSmrg InI2CREG(tmp,psav->DDCPort); 1081ab47cfaaSmrg OutI2CREG(tmp | 0x13,psav->DDCPort); 10828697ee19Smrg pMon = xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C)); 10838697ee19Smrg if (!psav->IgnoreEDID) xf86SetDDCproperties(pScrn, pMon); 1084ab47cfaaSmrg OutI2CREG(tmp,psav->DDCPort); 1085ab47cfaaSmrg } 1086ab47cfaaSmrg } 1087ab47cfaaSmrg } 1088ab47cfaaSmrg } 1089ab47cfaaSmrg} 1090ab47cfaaSmrg 1091ab47cfaaSmrg/* Copied from ddc/Property.c via nv */ 1092ab47cfaaSmrgstatic DisplayModePtr 1093ab47cfaaSmrgSavageModesAdd(DisplayModePtr Modes, DisplayModePtr Additions) 1094ab47cfaaSmrg{ 1095ab47cfaaSmrg if (!Modes) { 1096ab47cfaaSmrg if (Additions) 1097ab47cfaaSmrg return Additions; 1098ab47cfaaSmrg else 1099ab47cfaaSmrg return NULL; 1100ab47cfaaSmrg } 1101ab47cfaaSmrg 1102ab47cfaaSmrg if (Additions) { 1103ab47cfaaSmrg DisplayModePtr Mode = Modes; 1104ab47cfaaSmrg 1105ab47cfaaSmrg while (Mode->next) 1106ab47cfaaSmrg Mode = Mode->next; 1107ab47cfaaSmrg 1108ab47cfaaSmrg Mode->next = Additions; 1109ab47cfaaSmrg Additions->prev = Mode; 1110ab47cfaaSmrg } 1111ab47cfaaSmrg 1112ab47cfaaSmrg return Modes; 1113ab47cfaaSmrg} 1114ab47cfaaSmrg 1115ab47cfaaSmrg/* borrowed from nv */ 1116ab47cfaaSmrgstatic void 1117ab47cfaaSmrgSavageAddPanelMode(ScrnInfoPtr pScrn) 1118ab47cfaaSmrg{ 1119ab47cfaaSmrg SavagePtr psav= SAVPTR(pScrn); 1120ab47cfaaSmrg DisplayModePtr Mode = NULL; 1121ab47cfaaSmrg 1122ab47cfaaSmrg Mode = xf86CVTMode(psav->PanelX, psav->PanelY, 60.00, TRUE, FALSE); 1123ab47cfaaSmrg Mode->type = M_T_DRIVER | M_T_PREFERRED; 1124ab47cfaaSmrg pScrn->monitor->Modes = SavageModesAdd(pScrn->monitor->Modes, Mode); 1125ab47cfaaSmrg 1126ab47cfaaSmrg if ((pScrn->monitor->nHsync == 0) && 1127ab47cfaaSmrg (pScrn->monitor->nVrefresh == 0)) { 1128ab47cfaaSmrg if (!Mode->HSync) 1129ab47cfaaSmrg Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal); 1130ab47cfaaSmrg if (!Mode->VRefresh) 1131ab47cfaaSmrg Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 1132ab47cfaaSmrg ((float) (Mode->HTotal * Mode->VTotal)); 1133ab47cfaaSmrg 1134ab47cfaaSmrg if (Mode->HSync < pScrn->monitor->hsync[0].lo) 1135ab47cfaaSmrg pScrn->monitor->hsync[0].lo = Mode->HSync; 1136ab47cfaaSmrg if (Mode->HSync > pScrn->monitor->hsync[0].hi) 1137ab47cfaaSmrg pScrn->monitor->hsync[0].hi = Mode->HSync; 1138ab47cfaaSmrg if (Mode->VRefresh < pScrn->monitor->vrefresh[0].lo) 1139ab47cfaaSmrg pScrn->monitor->vrefresh[0].lo = Mode->VRefresh; 1140ab47cfaaSmrg if (Mode->VRefresh > pScrn->monitor->vrefresh[0].hi) 1141ab47cfaaSmrg pScrn->monitor->vrefresh[0].hi = Mode->VRefresh; 1142ab47cfaaSmrg 1143ab47cfaaSmrg pScrn->monitor->nHsync = 1; 1144ab47cfaaSmrg pScrn->monitor->nVrefresh = 1; 1145ab47cfaaSmrg } 1146ab47cfaaSmrg} 1147ab47cfaaSmrg 1148ab47cfaaSmrgstatic void SavageGetPanelInfo(ScrnInfoPtr pScrn) 1149ab47cfaaSmrg{ 1150ab47cfaaSmrg SavagePtr psav= SAVPTR(pScrn); 1151ab47cfaaSmrg vgaHWPtr hwp; 1152ab47cfaaSmrg unsigned char cr6b; 1153ab47cfaaSmrg int panelX, panelY; 1154ab47cfaaSmrg char * sTechnology = "Unknown"; 1155ab47cfaaSmrg enum ACTIVE_DISPLAYS { /* These are the bits in CR6B */ 1156ab47cfaaSmrg ActiveCRT = 0x01, 1157ab47cfaaSmrg ActiveLCD = 0x02, 1158ab47cfaaSmrg ActiveTV = 0x04, 1159ab47cfaaSmrg ActiveCRT2 = 0x20, 1160ab47cfaaSmrg ActiveDUO = 0x80 1161ab47cfaaSmrg }; 1162ab47cfaaSmrg 1163ab47cfaaSmrg hwp = VGAHWPTR(pScrn); 1164ab47cfaaSmrg 1165ab47cfaaSmrg /* Check LCD panel information */ 1166ab47cfaaSmrg 1167ab47cfaaSmrg cr6b = hwp->readCrtc( hwp, 0x6b ); 1168ab47cfaaSmrg 1169ab47cfaaSmrg panelX = (hwp->readSeq(hwp, 0x61) + 1170ab47cfaaSmrg ((hwp->readSeq(hwp, 0x66) & 0x02) << 7) + 1) * 8; 1171ab47cfaaSmrg panelY = hwp->readSeq(hwp, 0x69) + 1172ab47cfaaSmrg ((hwp->readSeq(hwp, 0x6e) & 0x70) << 4) + 1; 1173ab47cfaaSmrg 1174ab47cfaaSmrg 1175ab47cfaaSmrg /* OK, I admit it. I don't know how to limit the max dot clock 1176ab47cfaaSmrg * for LCD panels of various sizes. I thought I copied the formula 1177ab47cfaaSmrg * from the BIOS, but many users have informed me of my folly. 1178ab47cfaaSmrg * 1179ab47cfaaSmrg * Instead, I'll abandon any attempt to automatically limit the 1180ab47cfaaSmrg * clock, and add an LCDClock option to XF86Config. Some day, 1181ab47cfaaSmrg * I should come back to this. 1182ab47cfaaSmrg */ 1183ab47cfaaSmrg 1184ab47cfaaSmrg 1185ab47cfaaSmrg if( (hwp->readSeq( hwp, 0x39 ) & 0x03) == 0 ) 1186ab47cfaaSmrg { 1187ab47cfaaSmrg sTechnology = "TFT"; 1188ab47cfaaSmrg } 1189ab47cfaaSmrg else if( (hwp->readSeq( hwp, 0x30 ) & 0x01) == 0 ) 1190ab47cfaaSmrg { 1191ab47cfaaSmrg sTechnology = "DSTN"; 1192ab47cfaaSmrg } 1193ab47cfaaSmrg else 1194ab47cfaaSmrg { 1195ab47cfaaSmrg sTechnology = "STN"; 1196ab47cfaaSmrg } 1197ab47cfaaSmrg 1198ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1199ab47cfaaSmrg "%dx%d %s LCD panel detected %s\n", 1200ab47cfaaSmrg panelX, panelY, sTechnology, 1201ab47cfaaSmrg cr6b & ActiveLCD ? "and active" : "but not active"); 1202ab47cfaaSmrg 1203ab47cfaaSmrg if( cr6b & ActiveLCD ) { 1204ab47cfaaSmrg /* If the LCD is active and panel expansion is enabled, */ 1205ab47cfaaSmrg /* we probably want to kill the HW cursor. */ 1206ab47cfaaSmrg 1207ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 1208ab47cfaaSmrg "- Limiting video mode to %dx%d\n", 1209ab47cfaaSmrg panelX, panelY ); 1210ab47cfaaSmrg 1211ab47cfaaSmrg psav->PanelX = panelX; 1212ab47cfaaSmrg psav->PanelY = panelY; 1213ab47cfaaSmrg 12148697ee19Smrg do { 12158697ee19Smrg DisplayModePtr native = xf86CVTMode(panelX, panelY, 60.0, 0, 0); 12168697ee19Smrg if (!native) 12178697ee19Smrg break; 12188697ee19Smrg 12198697ee19Smrg if (!pScrn->monitor->nHsync) { 12208697ee19Smrg pScrn->monitor->nHsync = 1; 12218697ee19Smrg pScrn->monitor->hsync[0].lo = 31.5; 12228697ee19Smrg pScrn->monitor->hsync[0].hi = (float)native->Clock / 12238697ee19Smrg (float)native->HTotal; 12248697ee19Smrg } 12258697ee19Smrg if (!pScrn->monitor->nVrefresh) { 12268697ee19Smrg pScrn->monitor->nVrefresh = 1; 12278697ee19Smrg pScrn->monitor->vrefresh[0].lo = 56.0; 12288697ee19Smrg pScrn->monitor->vrefresh[0].hi = (float)native->Clock * 1000.0 / 12298697ee19Smrg (float)native->HTotal / 12308697ee19Smrg (float)native->VTotal; 12318697ee19Smrg } 12328697ee19Smrg if (!pScrn->monitor->maxPixClock) 12338697ee19Smrg pScrn->monitor->maxPixClock = native->Clock; 12348697ee19Smrg 12358697ee19Smrg xfree(native); 12368697ee19Smrg } while (0); 12378697ee19Smrg 1238ab47cfaaSmrg if( psav->LCDClock > 0.0 ) 1239ab47cfaaSmrg { 1240ab47cfaaSmrg psav->maxClock = psav->LCDClock * 1000.0; 1241ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, 1242ab47cfaaSmrg "- Limiting dot clock to %1.2f MHz\n", 1243ab47cfaaSmrg psav->LCDClock ); 1244ab47cfaaSmrg } 1245ab47cfaaSmrg } else { 1246ab47cfaaSmrg psav->DisplayType = MT_CRT; 1247ab47cfaaSmrg } 1248ab47cfaaSmrg} 1249ab47cfaaSmrg 1250ab47cfaaSmrg 1251ab47cfaaSmrgstatic Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) 1252ab47cfaaSmrg{ 1253ab47cfaaSmrg EntityInfoPtr pEnt; 1254ab47cfaaSmrg SavagePtr psav; 1255ab47cfaaSmrg MessageType from = X_DEFAULT; 1256ab47cfaaSmrg int i; 1257ab47cfaaSmrg ClockRangePtr clockRanges; 1258ab47cfaaSmrg char *s = NULL; 1259ab47cfaaSmrg unsigned char config1, m, n, n1, n2, sr8, cr66 = 0, tmp; 1260ab47cfaaSmrg int mclk; 1261ab47cfaaSmrg vgaHWPtr hwp; 1262ab47cfaaSmrg int vgaCRIndex, vgaCRReg; 1263ab47cfaaSmrg Bool dvi; 1264ab47cfaaSmrg 1265ab47cfaaSmrg TRACE(("SavagePreInit(%d)\n", flags)); 1266ab47cfaaSmrg 1267ab47cfaaSmrg gpScrn = pScrn; 1268ab47cfaaSmrg 1269ab47cfaaSmrg if (flags & PROBE_DETECT) { 1270ab47cfaaSmrg SavageProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index ); 1271ab47cfaaSmrg return TRUE; 1272ab47cfaaSmrg } 1273ab47cfaaSmrg 1274ab47cfaaSmrg if (!xf86LoadSubModule(pScrn, "vgahw")) 1275ab47cfaaSmrg return FALSE; 1276ab47cfaaSmrg 1277ab47cfaaSmrg xf86LoaderReqSymLists(vgaHWSymbols, NULL); 1278ab47cfaaSmrg if (!vgaHWGetHWRec(pScrn)) 1279ab47cfaaSmrg return FALSE; 1280ab47cfaaSmrg 1281ab47cfaaSmrg#if 0 1282ab47cfaaSmrg /* Here we can alter the number of registers saved and restored by the 1283ab47cfaaSmrg * standard vgaHWSave and Restore routines. 1284ab47cfaaSmrg */ 1285ab47cfaaSmrg vgaHWSetRegCounts( pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, VGA_NUM_ATTR ); 1286ab47cfaaSmrg#endif 1287ab47cfaaSmrg 1288ab47cfaaSmrg pScrn->monitor = pScrn->confScreen->monitor; 1289ab47cfaaSmrg 1290ab47cfaaSmrg /* 1291ab47cfaaSmrg * We support depths of 8, 15, 16 and 24. 1292ab47cfaaSmrg * We support bpp of 8, 16, and 32. 1293ab47cfaaSmrg */ 1294ab47cfaaSmrg 1295ab47cfaaSmrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) 1296ab47cfaaSmrg return FALSE; 1297ab47cfaaSmrg else { 1298ab47cfaaSmrg int requiredBpp; 1299ab47cfaaSmrg int altBpp = 0; 1300ab47cfaaSmrg 1301ab47cfaaSmrg switch (pScrn->depth) { 1302ab47cfaaSmrg case 8: 1303ab47cfaaSmrg case 16: 1304ab47cfaaSmrg requiredBpp = pScrn->depth; 1305ab47cfaaSmrg break; 1306ab47cfaaSmrg case 15: 1307ab47cfaaSmrg requiredBpp = 16; 1308ab47cfaaSmrg break; 1309ab47cfaaSmrg case 24: 1310ab47cfaaSmrg requiredBpp = 32; 1311ab47cfaaSmrg altBpp = 24; 1312ab47cfaaSmrg break; 1313ab47cfaaSmrg 1314ab47cfaaSmrg default: 1315ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1316ab47cfaaSmrg "Given depth (%d) is not supported by this driver\n", 1317ab47cfaaSmrg pScrn->depth); 1318ab47cfaaSmrg return FALSE; 1319ab47cfaaSmrg } 1320ab47cfaaSmrg 1321ab47cfaaSmrg if( 1322ab47cfaaSmrg (pScrn->bitsPerPixel != requiredBpp) && 1323ab47cfaaSmrg (pScrn->bitsPerPixel != altBpp) 1324ab47cfaaSmrg ) { 1325ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1326ab47cfaaSmrg "Depth %d must specify %d bpp; %d was given\n", 1327ab47cfaaSmrg pScrn->depth, requiredBpp, pScrn->bitsPerPixel ); 1328ab47cfaaSmrg return FALSE; 1329ab47cfaaSmrg } 1330ab47cfaaSmrg } 1331ab47cfaaSmrg 1332ab47cfaaSmrg xf86PrintDepthBpp(pScrn); 1333ab47cfaaSmrg 1334ab47cfaaSmrg if (pScrn->depth > 8) { 1335ab47cfaaSmrg rgb zeros = {0, 0, 0}; 1336ab47cfaaSmrg 1337ab47cfaaSmrg if (!xf86SetWeight(pScrn, zeros, zeros)) 1338ab47cfaaSmrg return FALSE; 1339ab47cfaaSmrg else { 1340ab47cfaaSmrg /* TODO check weight returned is supported */ 1341ab47cfaaSmrg ; 1342ab47cfaaSmrg } 1343ab47cfaaSmrg } 1344ab47cfaaSmrg 1345ab47cfaaSmrg if (!xf86SetDefaultVisual(pScrn, -1)) { 1346ab47cfaaSmrg return FALSE; 1347ab47cfaaSmrg } else { 1348ab47cfaaSmrg /* We don't currently support DirectColor at 16bpp */ 1349ab47cfaaSmrg if (pScrn->bitsPerPixel == 16 && pScrn->defaultVisual != TrueColor) { 1350ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 1351ab47cfaaSmrg " (%s) is not supported at depth %d\n", 1352ab47cfaaSmrg xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 1353ab47cfaaSmrg return FALSE; 1354ab47cfaaSmrg } 1355ab47cfaaSmrg } 1356ab47cfaaSmrg 1357ab47cfaaSmrg pScrn->progClock = TRUE; 1358ab47cfaaSmrg 1359ab47cfaaSmrg if (!SavageGetRec(pScrn)) 1360ab47cfaaSmrg return FALSE; 1361ab47cfaaSmrg psav = SAVPTR(pScrn); 1362ab47cfaaSmrg 1363ab47cfaaSmrg hwp = VGAHWPTR(pScrn); 1364ab47cfaaSmrg vgaHWGetIOBase(hwp); 1365ab47cfaaSmrg psav->vgaIOBase = hwp->IOBase; 1366ab47cfaaSmrg 1367ab47cfaaSmrg xf86CollectOptions(pScrn, NULL); 1368ab47cfaaSmrg 1369ab47cfaaSmrg if (pScrn->depth == 8) 1370ab47cfaaSmrg pScrn->rgbBits = 8; 1371ab47cfaaSmrg 1372ab47cfaaSmrg if (!(psav->Options = xalloc(sizeof(SavageOptions)))) 1373ab47cfaaSmrg return FALSE; 1374ab47cfaaSmrg memcpy(psav->Options, SavageOptions, sizeof(SavageOptions)); 1375ab47cfaaSmrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, psav->Options); 1376ab47cfaaSmrg 13778697ee19Smrg xf86GetOptValBool(psav->Options, OPTION_IGNORE_EDID, &psav->IgnoreEDID); 1378ab47cfaaSmrg xf86GetOptValBool(psav->Options, OPTION_PCI_BURST, &psav->pci_burst); 1379ab47cfaaSmrg 1380ab47cfaaSmrg if (psav->pci_burst) { 1381ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1382ab47cfaaSmrg "Option: pci_burst - PCI burst read enabled\n"); 1383ab47cfaaSmrg } 1384ab47cfaaSmrg 1385ab47cfaaSmrg psav->NoPCIRetry = 1; /* default */ 1386ab47cfaaSmrg if (xf86ReturnOptValBool(psav->Options, OPTION_PCI_RETRY, FALSE)) { 1387ab47cfaaSmrg if (xf86ReturnOptValBool(psav->Options, OPTION_PCI_BURST, FALSE)) { 1388ab47cfaaSmrg psav->NoPCIRetry = 0; 1389ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_retry\n"); 1390ab47cfaaSmrg } else 1391ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"pci_retry\" option requires \"pci_burst\"\n"); 1392ab47cfaaSmrg } 1393ab47cfaaSmrg 1394ab47cfaaSmrg xf86GetOptValBool( psav->Options, OPTION_SHADOW_FB, &psav->shadowFB ); 1395ab47cfaaSmrg if (psav->shadowFB) { 1396ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: shadow FB enabled\n"); 1397ab47cfaaSmrg } 1398ab47cfaaSmrg 1399ab47cfaaSmrg psav->primStreamBpp = pScrn->bitsPerPixel; 1400ab47cfaaSmrg 1401ab47cfaaSmrg if ((s = xf86GetOptValString(psav->Options, OPTION_ROTATE))) { 1402ab47cfaaSmrg if(!xf86NameCmp(s, "CW")) { 1403ab47cfaaSmrg /* accel is disabled below for shadowFB */ 1404ab47cfaaSmrg /* RandR is disabled when the Rotate option is used (does 1405ab47cfaaSmrg * not work well together and scrambles the screen) */ 1406ab47cfaaSmrg 1407ab47cfaaSmrg psav->shadowFB = TRUE; 1408ab47cfaaSmrg psav->rotate = 1; 1409ab47cfaaSmrg xf86DisableRandR(); 1410ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1411ab47cfaaSmrg "Rotating screen clockwise" 1412ab47cfaaSmrg "- acceleration and RandR disabled\n"); 1413ab47cfaaSmrg } else if(!xf86NameCmp(s, "CCW")) { 1414ab47cfaaSmrg psav->shadowFB = TRUE; 1415ab47cfaaSmrg psav->rotate = -1; 1416ab47cfaaSmrg xf86DisableRandR(); 1417ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1418ab47cfaaSmrg "Rotating screen counter clockwise" 1419ab47cfaaSmrg " - acceleration and RandR disabled\n"); 1420ab47cfaaSmrg 1421ab47cfaaSmrg } else { 1422ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 1423ab47cfaaSmrg "value for Option \"Rotate\"\n", s); 1424ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1425ab47cfaaSmrg "Valid options are \"CW\" or \"CCW\"\n"); 1426ab47cfaaSmrg } 1427ab47cfaaSmrg } 1428ab47cfaaSmrg 1429ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_NOACCEL, &psav->NoAccel)) 1430ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, 1431ab47cfaaSmrg "Option: NoAccel - Acceleration Disabled\n"); 1432ab47cfaaSmrg 1433ab47cfaaSmrg if (psav->shadowFB && !psav->NoAccel) { 1434ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1435ab47cfaaSmrg "HW acceleration not supported with \"shadowFB\".\n"); 1436ab47cfaaSmrg psav->NoAccel = TRUE; 1437ab47cfaaSmrg } 1438ab47cfaaSmrg 1439ab47cfaaSmrg if(!psav->NoAccel) { 1440ab47cfaaSmrg from = X_DEFAULT; 1441ab47cfaaSmrg char *strptr; 1442ab47cfaaSmrg if((strptr = (char *)xf86GetOptValString(psav->Options, OPTION_ACCELMETHOD))) { 1443ab47cfaaSmrg if(!xf86NameCmp(strptr,"XAA")) { 1444ab47cfaaSmrg from = X_CONFIG; 1445ab47cfaaSmrg psav->useEXA = FALSE; 1446ab47cfaaSmrg } else if(!xf86NameCmp(strptr,"EXA")) { 1447ab47cfaaSmrg from = X_CONFIG; 1448ab47cfaaSmrg psav->useEXA = TRUE; 1449ab47cfaaSmrg } 1450ab47cfaaSmrg } 1451ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", 1452ab47cfaaSmrg psav->useEXA ? "EXA" : "XAA"); 1453ab47cfaaSmrg } 1454ab47cfaaSmrg 1455ab47cfaaSmrg if ((s = xf86GetOptValString(psav->Options, OPTION_OVERLAY))) { 1456ab47cfaaSmrg 1457ab47cfaaSmrg if (psav->shadowFB) { 1458ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO, 1459ab47cfaaSmrg "Option \"Overlay\" not supported with shadowFB\n"); 1460ab47cfaaSmrg } else { 1461ab47cfaaSmrg if (pScrn->depth == 8) { 1462ab47cfaaSmrg if (!*s || !xf86NameCmp(s, "24")) { 1463ab47cfaaSmrg psav->overlayDepth = 24; 1464ab47cfaaSmrg psav->NoAccel = TRUE; /* Preliminary */ 1465ab47cfaaSmrg pScrn->colorKey = TRANSPARENCY_KEY; 1466ab47cfaaSmrg pScrn->overlayFlags = OVERLAY_8_32_DUALFB; 1467ab47cfaaSmrg } else if (!xf86NameCmp(s, "16")) { 1468ab47cfaaSmrg psav->overlayDepth = 16; 1469ab47cfaaSmrg psav->NoAccel = TRUE; /* Preliminary */ 1470ab47cfaaSmrg pScrn->colorKey = TRANSPARENCY_KEY; 1471ab47cfaaSmrg pScrn->overlayFlags = OVERLAY_8_32_DUALFB; 1472ab47cfaaSmrg } else { 1473ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"Wrong argument: " 1474ab47cfaaSmrg "\"%s\" Ingnoring\n",s); 1475ab47cfaaSmrg } 1476ab47cfaaSmrg } else if (pScrn->depth != 15) { 1477ab47cfaaSmrg psav->overlayDepth = 8; 1478ab47cfaaSmrg psav->NoAccel = TRUE; /* Preliminary */ 1479ab47cfaaSmrg pScrn->colorKey = TRANSPARENCY_KEY; 1480ab47cfaaSmrg pScrn->overlayFlags = OVERLAY_8_32_DUALFB; 1481ab47cfaaSmrg if (*s && (xf86NameCmp(s, "8"))) 1482ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"Wrong argument: " 1483ab47cfaaSmrg "\"%s\" for depth %i overlay depth must be 8\n", 1484ab47cfaaSmrg s,pScrn->depth); 1485ab47cfaaSmrg } else { 1486ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"Overlay not " 1487ab47cfaaSmrg "supported for depth 15\n"); 1488ab47cfaaSmrg } 1489ab47cfaaSmrg if (psav->overlayDepth) { 1490ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"%i/%i Overlay enabled\n", 1491ab47cfaaSmrg pScrn->depth,psav->overlayDepth); 1492ab47cfaaSmrg psav->primStreamBpp = 8; 1493ab47cfaaSmrg } 1494ab47cfaaSmrg } 1495ab47cfaaSmrg } 1496ab47cfaaSmrg 1497ab47cfaaSmrg if (pScrn->bitsPerPixel == 24 && !psav->NoAccel) { 1498ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1499ab47cfaaSmrg "HW acceleration not possible with depth 32 and bpp 24.\n"); 1500ab47cfaaSmrg psav->NoAccel = TRUE; 1501ab47cfaaSmrg } 1502ab47cfaaSmrg 1503ab47cfaaSmrg /* 1504ab47cfaaSmrg * The SWCursor setting takes priority over HWCursor. The default 1505ab47cfaaSmrg * if neither is specified is HW, unless ShadowFB is specified, 1506ab47cfaaSmrg * then SW. 1507ab47cfaaSmrg */ 1508ab47cfaaSmrg 1509ab47cfaaSmrg from = X_DEFAULT; 1510ab47cfaaSmrg psav->hwcursor = psav->shadowFB ? FALSE : TRUE; 1511ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_HWCURSOR, &psav->hwcursor)) 1512ab47cfaaSmrg from = X_CONFIG; 1513ab47cfaaSmrg if (xf86ReturnOptValBool(psav->Options, OPTION_SWCURSOR, FALSE)) { 1514ab47cfaaSmrg psav->hwcursor = FALSE; 1515ab47cfaaSmrg from = X_CONFIG; 1516ab47cfaaSmrg } 1517ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 1518ab47cfaaSmrg psav->hwcursor ? "HW" : "SW"); 1519ab47cfaaSmrg 1520ab47cfaaSmrg from = X_DEFAULT; 1521ab47cfaaSmrg psav->UseBIOS = TRUE; 1522ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_USEBIOS, &psav->UseBIOS) ) 1523ab47cfaaSmrg from = X_CONFIG; 1524ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, "%ssing video BIOS to set modes\n", 1525ab47cfaaSmrg psav->UseBIOS ? "U" : "Not u" ); 1526ab47cfaaSmrg 1527ab47cfaaSmrg psav->LCDClock = 0.0; 1528ab47cfaaSmrg if( xf86GetOptValFreq( psav->Options, OPTION_LCDCLOCK, OPTUNITS_MHZ, &psav->LCDClock ) ) 1529ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, 1530ab47cfaaSmrg "Option: LCDClock %1.2f MHz\n", psav->LCDClock ); 1531ab47cfaaSmrg 1532ab47cfaaSmrg if( xf86GetOptValBool( psav->Options, OPTION_SHADOW_STATUS, &psav->ShadowStatus)) { 1533ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, 1534ab47cfaaSmrg "Option: ShadowStatus %sabled\n", psav->ShadowStatus ? "en" : "dis" ); 1535ab47cfaaSmrg psav->ForceShadowStatus = TRUE; 1536ab47cfaaSmrg } else 1537ab47cfaaSmrg psav->ForceShadowStatus = FALSE; 1538ab47cfaaSmrg /* If ShadowStatus is off it will be automatically enabled for DRI. 1539ab47cfaaSmrg * If DRI initialization fails fall back to ConfigShadowStatus. */ 1540ab47cfaaSmrg psav->ConfigShadowStatus = psav->ShadowStatus; 1541ab47cfaaSmrg 1542ab47cfaaSmrg if( xf86GetOptValBool( psav->Options, OPTION_CRT_ONLY, &psav->CrtOnly)) 1543ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, 1544ab47cfaaSmrg "Option: CrtOnly enabled\n" ); 1545ab47cfaaSmrg 1546ab47cfaaSmrg if( xf86GetOptValBool( psav->Options, OPTION_TV_ON, &psav->TvOn)) { 1547ab47cfaaSmrg psav->PAL = FALSE; 1548ab47cfaaSmrg SavageGetTvMaxSize(psav); 1549ab47cfaaSmrg } 1550ab47cfaaSmrg 1551ab47cfaaSmrg if( xf86GetOptValBool( psav->Options, OPTION_TV_PAL, &psav->PAL)) { 1552ab47cfaaSmrg SavageGetTvMaxSize(psav); 1553ab47cfaaSmrg psav->TvOn = TRUE; 1554ab47cfaaSmrg } 1555ab47cfaaSmrg 1556ab47cfaaSmrg if( psav->TvOn ) 1557ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, 1558ab47cfaaSmrg "TV enabled in %s format\n", 1559ab47cfaaSmrg psav->PAL ? "PAL" : "NTSC" ); 1560ab47cfaaSmrg 1561ab47cfaaSmrg psav->ForceInit = 0; 1562ab47cfaaSmrg if( xf86GetOptValBool( psav->Options, OPTION_FORCE_INIT, &psav->ForceInit)) 1563ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, 1564ab47cfaaSmrg "Option: ForceInit enabled\n" ); 1565ab47cfaaSmrg 1566ab47cfaaSmrg if (pScrn->numEntities > 1) { 1567ab47cfaaSmrg SavageFreeRec(pScrn); 1568ab47cfaaSmrg return FALSE; 1569ab47cfaaSmrg } 1570ab47cfaaSmrg 1571ab47cfaaSmrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1572ab47cfaaSmrg if (pEnt->resources) { 1573ab47cfaaSmrg xfree(pEnt); 1574ab47cfaaSmrg SavageFreeRec(pScrn); 1575ab47cfaaSmrg return FALSE; 1576ab47cfaaSmrg } 1577ab47cfaaSmrg psav->EntityIndex = pEnt->index; 1578ab47cfaaSmrg 1579ab47cfaaSmrg if (xf86LoadSubModule(pScrn, "vbe")) { 1580ab47cfaaSmrg xf86LoaderReqSymLists(vbeSymbols, NULL); 1581ab47cfaaSmrg psav->pVbe = VBEInit(NULL, pEnt->index); 1582ab47cfaaSmrg } 1583ab47cfaaSmrg 1584ab47cfaaSmrg xf86RegisterResources(pEnt->index, NULL, ResNone); 1585ab47cfaaSmrg xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr); 1586ab47cfaaSmrg xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr); 1587ab47cfaaSmrg 1588ab47cfaaSmrg from = X_DEFAULT; 1589ab47cfaaSmrg if (pEnt->device->chipset && *pEnt->device->chipset) { 1590ab47cfaaSmrg pScrn->chipset = pEnt->device->chipset; 1591ab47cfaaSmrg psav->ChipId = pEnt->device->chipID; 1592ab47cfaaSmrg from = X_CONFIG; 1593ab47cfaaSmrg } else if (pEnt->device->chipID >= 0) { 1594ab47cfaaSmrg psav->ChipId = pEnt->device->chipID; 1595ab47cfaaSmrg pScrn->chipset = (char *)xf86TokenToString(SavageChipsets, 1596ab47cfaaSmrg psav->Chipset); 1597ab47cfaaSmrg from = X_CONFIG; 1598ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 1599ab47cfaaSmrg pEnt->device->chipID); 1600ab47cfaaSmrg } else { 1601ab47cfaaSmrg from = X_PROBED; 16028697ee19Smrg psav->ChipId = DEVICE_ID(psav->PciInfo); 1603ab47cfaaSmrg pScrn->chipset = (char *)xf86TokenToString(SavageChipsets, 1604ab47cfaaSmrg psav->Chipset); 1605ab47cfaaSmrg } 1606ab47cfaaSmrg 1607ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chip: id %04x, \"%s\"\n", 1608ab47cfaaSmrg psav->ChipId, xf86TokenToString( SavageChips, psav->ChipId ) ); 1609ab47cfaaSmrg 1610ab47cfaaSmrg if (pEnt->device->chipRev >= 0) { 1611ab47cfaaSmrg psav->ChipRev = pEnt->device->chipRev; 1612ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 1613ab47cfaaSmrg psav->ChipRev); 1614ab47cfaaSmrg } else 16158697ee19Smrg psav->ChipRev = CHIP_REVISION(psav->PciInfo); 1616ab47cfaaSmrg 1617ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, "Engine: \"%s\"\n", pScrn->chipset); 1618ab47cfaaSmrg 1619ab47cfaaSmrg if (pEnt->device->videoRam != 0) 1620ab47cfaaSmrg pScrn->videoRam = pEnt->device->videoRam; 1621ab47cfaaSmrg 1622ab47cfaaSmrg xfree(pEnt); 1623ab47cfaaSmrg 16248697ee19Smrg#ifndef XSERVER_LIBPCIACCESS 1625ab47cfaaSmrg psav->PciTag = pciTag(psav->PciInfo->bus, psav->PciInfo->device, 1626ab47cfaaSmrg psav->PciInfo->func); 16278697ee19Smrg#endif 1628ab47cfaaSmrg 1629ab47cfaaSmrg 1630ab47cfaaSmrg /* Set AGP Mode from config */ 1631ab47cfaaSmrg /* We support 1X 2X and 4X */ 1632ab47cfaaSmrg#ifdef XF86DRI 16338697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 16348697ee19Smrg /* Try to read the AGP capabilty block from the device. If there is 16358697ee19Smrg * no AGP info, the device is PCI. 16368697ee19Smrg */ 16378697ee19Smrg 16388697ee19Smrg psav->IsPCI = (pci_device_get_agp_info(psav->PciInfo) == NULL); 16398697ee19Smrg#else 1640ab47cfaaSmrg /* AGP/PCI (FK: copied from radeon_driver.c) */ 1641ab47cfaaSmrg /* Proper autodetection of an AGP capable device requires examining 1642ab47cfaaSmrg * PCI config registers to determine if the device implements extended 1643ab47cfaaSmrg * PCI capabilities, and then walking the capability list as indicated 1644ab47cfaaSmrg * in the PCI 2.2 and AGP 2.0 specifications, to determine if AGP 1645ab47cfaaSmrg * capability is present. The procedure is outlined as follows: 1646ab47cfaaSmrg * 1647ab47cfaaSmrg * 1) Test bit 4 (CAP_LIST) of the PCI status register of the device 1648ab47cfaaSmrg * to determine wether or not this device implements any extended 1649ab47cfaaSmrg * capabilities. If this bit is zero, then the device is a PCI 2.1 1650ab47cfaaSmrg * or earlier device and is not AGP capable, and we can conclude it 1651ab47cfaaSmrg * to be a PCI device. 1652ab47cfaaSmrg * 1653ab47cfaaSmrg * 2) If bit 4 of the status register is set, then the device implements 1654ab47cfaaSmrg * extended capabilities. There is an 8 bit wide capabilities pointer 1655ab47cfaaSmrg * register located at offset 0x34 in PCI config space which points to 1656ab47cfaaSmrg * the first capability in a linked list of extended capabilities that 1657ab47cfaaSmrg * this device implements. The lower two bits of this register are 1658ab47cfaaSmrg * reserved and MBZ so must be masked out. 1659ab47cfaaSmrg * 1660ab47cfaaSmrg * 3) The extended capabilities list is formed by one or more extended 1661ab47cfaaSmrg * capabilities structures which are aligned on DWORD boundaries. 1662ab47cfaaSmrg * The first byte of the structure is the capability ID (CAP_ID) 1663ab47cfaaSmrg * indicating what extended capability this structure refers to. The 1664ab47cfaaSmrg * second byte of the structure is an offset from the beginning of 1665ab47cfaaSmrg * PCI config space pointing to the next capability in the linked 1666ab47cfaaSmrg * list (NEXT_PTR) or NULL (0x00) at the end of the list. The lower 1667ab47cfaaSmrg * two bits of this pointer are reserved and MBZ. By examining the 1668ab47cfaaSmrg * CAP_ID of each capability and walking through the list, we will 1669ab47cfaaSmrg * either find the AGP_CAP_ID (0x02) indicating this device is an 1670ab47cfaaSmrg * AGP device, or we'll reach the end of the list, indicating it is 1671ab47cfaaSmrg * a PCI device. 1672ab47cfaaSmrg * 1673ab47cfaaSmrg * Mike A. Harris <mharris@redhat.com> 1674ab47cfaaSmrg * 1675ab47cfaaSmrg * References: 1676ab47cfaaSmrg * - PCI Local Bus Specification Revision 2.2, Chapter 6 1677ab47cfaaSmrg * - AGP Interface Specification Revision 2.0, Section 6.1.5 1678ab47cfaaSmrg */ 1679ab47cfaaSmrg 1680ab47cfaaSmrg psav->IsPCI = TRUE; 1681ab47cfaaSmrg 1682ab47cfaaSmrg if (pciReadLong(psav->PciTag, PCI_CMD_STAT_REG) & SAVAGE_CAP_LIST) { 1683ab47cfaaSmrg CARD32 cap_ptr, cap_id; 1684ab47cfaaSmrg 1685ab47cfaaSmrg cap_ptr = pciReadLong(psav->PciTag, 1686ab47cfaaSmrg SAVAGE_CAPABILITIES_PTR_PCI_CONFIG) 1687ab47cfaaSmrg & SAVAGE_CAP_PTR_MASK; 1688ab47cfaaSmrg 1689ab47cfaaSmrg while(cap_ptr != SAVAGE_CAP_ID_NULL) { 1690ab47cfaaSmrg cap_id = pciReadLong(psav->PciTag, cap_ptr); 1691ab47cfaaSmrg if ((cap_id & 0xff) == SAVAGE_CAP_ID_AGP) { 1692ab47cfaaSmrg psav->IsPCI = FALSE; 1693ab47cfaaSmrg break; 1694ab47cfaaSmrg } 1695ab47cfaaSmrg cap_ptr = (cap_id >> 8) & SAVAGE_CAP_PTR_MASK; 1696ab47cfaaSmrg } 1697ab47cfaaSmrg } 16988697ee19Smrg#endif 1699ab47cfaaSmrg 1700ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s card detected\n", 1701ab47cfaaSmrg (psav->IsPCI) ? "PCI" : "AGP"); 1702ab47cfaaSmrg 1703ab47cfaaSmrg if ((s = xf86GetOptValString(psav->Options, OPTION_BUS_TYPE))) { 1704ab47cfaaSmrg if (strcmp(s, "AGP") == 0) { 1705ab47cfaaSmrg if (psav->IsPCI) { 1706ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1707ab47cfaaSmrg "BusType AGP not available on PCI card\n"); 1708ab47cfaaSmrg } else { 1709ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "BusType set to AGP\n"); 1710ab47cfaaSmrg } 1711ab47cfaaSmrg } else if (strcmp(s, "PCI") == 0) { 1712ab47cfaaSmrg psav->IsPCI = TRUE; 1713ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "BusType set to PCI\n"); 1714ab47cfaaSmrg } else { 1715ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1716ab47cfaaSmrg "Invalid BusType option, using %s DMA\n", 1717ab47cfaaSmrg psav->IsPCI ? "PCI" : "AGP"); 1718ab47cfaaSmrg } 1719ab47cfaaSmrg } 1720ab47cfaaSmrg 1721ab47cfaaSmrg psav->AgpDMA = !psav->IsPCI; 1722ab47cfaaSmrg if ((s = xf86GetOptValString(psav->Options, OPTION_DMA_TYPE))) { 1723ab47cfaaSmrg if (strcmp(s, "AGP") == 0) { 1724ab47cfaaSmrg if (psav->IsPCI) { 1725ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1726ab47cfaaSmrg "AGP DMA not available on PCI card, using PCI DMA\n"); 1727ab47cfaaSmrg } else { 1728ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using AGP DMA\n"); 1729ab47cfaaSmrg } 1730ab47cfaaSmrg } else if (strcmp(s, "PCI") == 0) { 1731ab47cfaaSmrg psav->AgpDMA = FALSE; 1732ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using PCI DMA\n"); 1733ab47cfaaSmrg } else { 1734ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1735ab47cfaaSmrg "Invalid DmaType option, using %s DMA\n", 1736ab47cfaaSmrg psav->AgpDMA ? "AGP" : "PCI"); 1737ab47cfaaSmrg } 1738ab47cfaaSmrg } else { 1739ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, 1740ab47cfaaSmrg "Using %s DMA\n", psav->AgpDMA ? "AGP" : "PCI"); 1741ab47cfaaSmrg } 1742ab47cfaaSmrg 1743ab47cfaaSmrg psav->CommandDMA = TRUE; 1744ab47cfaaSmrg psav->VertexDMA = TRUE; 1745ab47cfaaSmrg from = X_DEFAULT; 1746ab47cfaaSmrg if ((s = xf86GetOptValString(psav->Options, OPTION_DMA_MODE))) { 1747ab47cfaaSmrg from = X_CONFIG; 1748ab47cfaaSmrg if (strcmp(s, "Command") == 0) 1749ab47cfaaSmrg psav->VertexDMA = FALSE; 1750ab47cfaaSmrg else if (strcmp(s, "Vertex") == 0) 1751ab47cfaaSmrg psav->CommandDMA = FALSE; 1752ab47cfaaSmrg else if (strcmp(s, "None") == 0) 1753ab47cfaaSmrg psav->VertexDMA = psav->CommandDMA = FALSE; 1754ab47cfaaSmrg else if (strcmp(s, "Any") != 0) { 1755ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid DmaMode option\n"); 1756ab47cfaaSmrg from = X_DEFAULT; 1757ab47cfaaSmrg } 1758ab47cfaaSmrg } 1759ab47cfaaSmrg if (psav->CommandDMA && S3_SAVAGE3D_SERIES(psav->Chipset)) { 1760ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from == X_CONFIG ? X_WARNING : X_INFO, 1761ab47cfaaSmrg "Savage3D/MX/IX does not support command DMA.\n"); 1762ab47cfaaSmrg psav->CommandDMA = FALSE; 1763ab47cfaaSmrg } 1764ab47cfaaSmrg if ((psav->CommandDMA || psav->VertexDMA) && 1765ab47cfaaSmrg psav->Chipset == S3_SUPERSAVAGE) { 1766ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from == X_CONFIG ? X_WARNING : X_INFO, 1767ab47cfaaSmrg "DMA is not supported on SuperSavages.\n"); 1768ab47cfaaSmrg psav->CommandDMA = psav->VertexDMA = FALSE; 1769ab47cfaaSmrg } 1770ab47cfaaSmrg if (psav->CommandDMA && psav->VertexDMA) 1771ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, 1772ab47cfaaSmrg "Will try command and vertex DMA mode\n"); 1773ab47cfaaSmrg else if (psav->CommandDMA && !psav->VertexDMA) 1774ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, 1775ab47cfaaSmrg "Will try only command DMA mode\n"); 1776ab47cfaaSmrg else if (!psav->CommandDMA && psav->VertexDMA) 1777ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, 1778ab47cfaaSmrg "Will try only vertex DMA mode\n"); 1779ab47cfaaSmrg else 1780ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, 1781ab47cfaaSmrg "DMA disabled\n"); 1782ab47cfaaSmrg 1783ab47cfaaSmrg if (!psav->IsPCI) { 1784ab47cfaaSmrg from = X_DEFAULT; 1785ab47cfaaSmrg psav->agpMode = SAVAGE_DEFAULT_AGP_MODE; 1786ab47cfaaSmrg /*psav->agpMode = SAVAGE_MAX_AGP_MODE;*/ 1787ab47cfaaSmrg psav->agpSize = 16; 1788ab47cfaaSmrg 1789ab47cfaaSmrg if (xf86GetOptValInteger(psav->Options, 1790ab47cfaaSmrg OPTION_AGP_MODE, &(psav->agpMode))) { 1791ab47cfaaSmrg if (psav->agpMode < 1) { 1792ab47cfaaSmrg psav->agpMode = 1; 1793ab47cfaaSmrg } 1794ab47cfaaSmrg if (psav->agpMode > SAVAGE_MAX_AGP_MODE) { 1795ab47cfaaSmrg psav->agpMode = SAVAGE_MAX_AGP_MODE; 1796ab47cfaaSmrg } 1797ab47cfaaSmrg if ((psav->agpMode > 2) && 1798ab47cfaaSmrg (psav->Chipset == S3_SAVAGE3D || 1799ab47cfaaSmrg psav->Chipset == S3_SAVAGE_MX)) 1800ab47cfaaSmrg psav->agpMode = 2; /* old savages only support 2x */ 1801ab47cfaaSmrg from = X_CONFIG; 1802ab47cfaaSmrg } 1803ab47cfaaSmrg 1804ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n", 1805ab47cfaaSmrg psav->agpMode); 1806ab47cfaaSmrg 1807ab47cfaaSmrg from = X_DEFAULT; 1808ab47cfaaSmrg if (xf86GetOptValInteger(psav->Options, 1809ab47cfaaSmrg OPTION_AGP_SIZE, (int *)&(psav->agpSize))) { 1810ab47cfaaSmrg switch (psav->agpSize) { 1811ab47cfaaSmrg case 4: 1812ab47cfaaSmrg case 8: 1813ab47cfaaSmrg case 16: 1814ab47cfaaSmrg case 32: 1815ab47cfaaSmrg case 64: 1816ab47cfaaSmrg case 128: 1817ab47cfaaSmrg case 256: 1818ab47cfaaSmrg from = X_CONFIG; 1819ab47cfaaSmrg break; 1820ab47cfaaSmrg default: 1821ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1822ab47cfaaSmrg "Illegal AGP size: %d MB, defaulting to 16 MB\n", psav->agpSize); 1823ab47cfaaSmrg psav->agpSize = 16; 1824ab47cfaaSmrg } 1825ab47cfaaSmrg } 1826ab47cfaaSmrg 1827ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, from, 1828ab47cfaaSmrg "Using %d MB AGP aperture\n", psav->agpSize); 1829ab47cfaaSmrg } else { 1830ab47cfaaSmrg psav->agpMode = 0; 1831ab47cfaaSmrg psav->agpSize = 0; 1832ab47cfaaSmrg } 1833ab47cfaaSmrg 1834ab47cfaaSmrg#endif 1835ab47cfaaSmrg 1836ab47cfaaSmrg /* we can use Option "DisableTile TRUE" to disable tile mode */ 1837ab47cfaaSmrg psav->bDisableTile = FALSE; 1838ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_TILE,&psav->bDisableTile)) { 1839ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1840ab47cfaaSmrg "Option: %s Tile Mode and Program it \n",(psav->bDisableTile?"Disable":"Enable")); 1841ab47cfaaSmrg } 1842ab47cfaaSmrg 1843ab47cfaaSmrg#ifdef XF86DRI 1844ab47cfaaSmrg /* disabled by default...doesn't seem to work */ 1845ab47cfaaSmrg psav->bDisableXvMC = TRUE; /* if you want to free up more mem for DRI,etc. */ 1846ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_XVMC, &psav->bDisableXvMC)) { 1847ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1848ab47cfaaSmrg "Option: %s Hardware XvMC support\n",(psav->bDisableXvMC?"Disable":"Enable")); 1849ab47cfaaSmrg } 1850ab47cfaaSmrg#endif 1851ab47cfaaSmrg 1852ab47cfaaSmrg psav->disableCOB = FALSE; /* if you are having problems on savage4+ */ 1853ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_COB, &psav->disableCOB)) { 1854ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1855ab47cfaaSmrg "Option: %s the COB\n",(psav->disableCOB?"Disable":"Enable")); 1856ab47cfaaSmrg } 1857ab47cfaaSmrg if (psav->Chipset == S3_PROSAVAGE || 1858ab47cfaaSmrg psav->Chipset == S3_TWISTER || 1859ab47cfaaSmrg psav->Chipset == S3_PROSAVAGEDDR) 1860ab47cfaaSmrg psav->BCIforXv = TRUE; 1861ab47cfaaSmrg else 1862ab47cfaaSmrg psav->BCIforXv = FALSE; /* use the BCI for Xv */ 1863ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_BCI_FOR_XV, &psav->BCIforXv)) { 1864ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1865ab47cfaaSmrg "Option: %s use of the BCI for Xv\n",(psav->BCIforXv?"Enable":"Disable")); 1866ab47cfaaSmrg } 1867ab47cfaaSmrg psav->dvi = FALSE; 1868ab47cfaaSmrg if (xf86GetOptValBool(psav->Options, OPTION_DVI, &psav->dvi)) { 1869ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1870ab47cfaaSmrg "%s DVI port support (Savage4 only)\n",(psav->dvi?"Force":"Disable")); 1871ab47cfaaSmrg } 1872ab47cfaaSmrg 1873ab47cfaaSmrg /* Add more options here. */ 1874ab47cfaaSmrg 1875ab47cfaaSmrg 1876ab47cfaaSmrg psav = SAVPTR(pScrn); 1877ab47cfaaSmrg psav->IsSecondary = FALSE; 1878ab47cfaaSmrg psav->IsPrimary = FALSE; 1879ab47cfaaSmrg psav->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); 1880ab47cfaaSmrg 1881ab47cfaaSmrg if (xf86IsEntityShared(psav->pEnt->index)) { 1882ab47cfaaSmrg if (xf86IsPrimInitDone(psav->pEnt->index)) { 1883ab47cfaaSmrg 1884ab47cfaaSmrg SavageEntPtr pSavageEnt = SavageEntPriv(pScrn); 1885ab47cfaaSmrg 1886ab47cfaaSmrg psav->IsSecondary = TRUE; 1887ab47cfaaSmrg pSavageEnt->pSecondaryScrn = pScrn; 1888ab47cfaaSmrg psav->TvOn = pSavageEnt->TvOn; 1889ab47cfaaSmrg } else { 1890ab47cfaaSmrg SavageEntPtr pSavageEnt = SavageEntPriv(pScrn); 1891ab47cfaaSmrg 1892ab47cfaaSmrg xf86SetPrimInitDone(psav->pEnt->index); 1893ab47cfaaSmrg 1894ab47cfaaSmrg psav->IsPrimary = TRUE; 1895ab47cfaaSmrg pSavageEnt->pPrimaryScrn = pScrn; 1896ab47cfaaSmrg pSavageEnt->TvOn = psav->TvOn; 1897ab47cfaaSmrg } 1898ab47cfaaSmrg } 1899ab47cfaaSmrg 1900ab47cfaaSmrg switch(psav->Chipset) { 1901ab47cfaaSmrg case S3_SAVAGE_MX: 1902ab47cfaaSmrg case S3_SUPERSAVAGE: 1903ab47cfaaSmrg psav->HasCRTC2 = TRUE; 1904ab47cfaaSmrg break; 1905ab47cfaaSmrg default: 1906ab47cfaaSmrg psav->HasCRTC2 = FALSE; 1907ab47cfaaSmrg } 1908ab47cfaaSmrg 1909ab47cfaaSmrg if ((psav->IsSecondary || psav->IsPrimary) && !psav->UseBIOS) { 1910ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "BIOS currently required for Dualhead mode setting.\n"); 1911ab47cfaaSmrg return FALSE; 1912ab47cfaaSmrg } 1913ab47cfaaSmrg 1914ab47cfaaSmrg if (psav->IsSecondary && 1915ab47cfaaSmrg (pScrn->bitsPerPixel > 16) && 1916ab47cfaaSmrg !psav->NoAccel && 1917ab47cfaaSmrg (psav->Chipset == S3_SAVAGE_MX)) { 1918ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No acceleration in Dualhead mode at depth 24\n"); 1919ab47cfaaSmrg return FALSE; 1920ab47cfaaSmrg } 1921ab47cfaaSmrg 1922ab47cfaaSmrg /* maybe throw in some more sanity checks here */ 1923ab47cfaaSmrg 1924ab47cfaaSmrg if (!SavageMapMem(pScrn)) { 1925ab47cfaaSmrg SavageFreeRec(pScrn); 1926ab47cfaaSmrg vbeFree(psav->pVbe); 1927ab47cfaaSmrg psav->pVbe = NULL; 1928ab47cfaaSmrg return FALSE; 1929ab47cfaaSmrg } 1930ab47cfaaSmrg 1931ab47cfaaSmrg vgaCRIndex = psav->vgaIOBase + 4; 1932ab47cfaaSmrg vgaCRReg = psav->vgaIOBase + 5; 1933ab47cfaaSmrg 1934ab47cfaaSmrg xf86EnableIO(); 1935ab47cfaaSmrg /* unprotect CRTC[0-7] */ 1936ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x11); 1937ab47cfaaSmrg tmp = VGAIN8(vgaCRReg); 1938ab47cfaaSmrg VGAOUT8(vgaCRReg, tmp & 0x7f); 1939ab47cfaaSmrg 1940ab47cfaaSmrg /* unlock extended regs */ 1941ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x4838); 1942ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0xa039); 1943ab47cfaaSmrg VGAOUT16(0x3c4, 0x0608); 1944ab47cfaaSmrg 1945ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x40); 1946ab47cfaaSmrg tmp = VGAIN8(vgaCRReg); 1947ab47cfaaSmrg VGAOUT8(vgaCRReg, tmp & ~0x01); 1948ab47cfaaSmrg 1949ab47cfaaSmrg /* unlock sys regs */ 1950ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x38); 1951ab47cfaaSmrg VGAOUT8(vgaCRReg, 0x48); 1952ab47cfaaSmrg 1953ab47cfaaSmrg { 1954ab47cfaaSmrg Gamma zeros = {0.0, 0.0, 0.0}; 1955ab47cfaaSmrg 1956ab47cfaaSmrg if (!xf86SetGamma(pScrn, zeros)) { 1957ab47cfaaSmrg vbeFree(psav->pVbe); 1958ab47cfaaSmrg psav->pVbe = NULL; 1959ab47cfaaSmrg SavageFreeRec(pScrn); 1960ab47cfaaSmrg return FALSE; 1961ab47cfaaSmrg } 1962ab47cfaaSmrg } 1963ab47cfaaSmrg 1964ab47cfaaSmrg /* Unlock system registers. */ 1965ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x4838); 1966ab47cfaaSmrg 1967ab47cfaaSmrg /* Next go on to detect amount of installed ram */ 1968ab47cfaaSmrg 1969ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x36); /* for register CR36 (CONFG_REG1), */ 1970ab47cfaaSmrg config1 = VGAIN8(vgaCRReg); /* get amount of vram installed */ 1971ab47cfaaSmrg 1972ab47cfaaSmrg /* Compute the amount of video memory and offscreen memory. */ 1973ab47cfaaSmrg 1974ab47cfaaSmrg if (!pScrn->videoRam) { 1975ab47cfaaSmrg static const unsigned char RamSavage3D[] = { 8, 4, 4, 2 }; 1976ab47cfaaSmrg static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 }; 1977ab47cfaaSmrg static const unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 }; 1978ab47cfaaSmrg static const unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 16, 2 }; 1979ab47cfaaSmrg 1980ab47cfaaSmrg switch( psav->Chipset ) { 1981ab47cfaaSmrg case S3_SAVAGE3D: 1982ab47cfaaSmrg pScrn->videoRam = RamSavage3D[ (config1 & 0xC0) >> 6 ] * 1024; 1983ab47cfaaSmrg break; 1984ab47cfaaSmrg 1985ab47cfaaSmrg case S3_SAVAGE4: 1986ab47cfaaSmrg /* 1987ab47cfaaSmrg * The Savage4 has one ugly special case to consider. On 1988ab47cfaaSmrg * systems with 4 banks of 2Mx32 SDRAM, the BIOS says 4MB 1989ab47cfaaSmrg * when it really means 8MB. Why do it the same when you 1990ab47cfaaSmrg * can do it different... 1991ab47cfaaSmrg */ 1992ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x68); /* memory control 1 */ 1993ab47cfaaSmrg if( (VGAIN8(vgaCRReg) & 0xC0) == (0x01 << 6) ) 1994ab47cfaaSmrg RamSavage4[1] = 8; 1995ab47cfaaSmrg 1996ab47cfaaSmrg /*FALLTHROUGH*/ 1997ab47cfaaSmrg 1998ab47cfaaSmrg case S3_SAVAGE2000: 1999ab47cfaaSmrg pScrn->videoRam = RamSavage4[ (config1 & 0xE0) >> 5 ] * 1024; 2000ab47cfaaSmrg break; 2001ab47cfaaSmrg 2002ab47cfaaSmrg case S3_SAVAGE_MX: 2003ab47cfaaSmrg case S3_SUPERSAVAGE: 2004ab47cfaaSmrg pScrn->videoRam = RamSavageMX[ (config1 & 0x0E) >> 1 ] * 1024; 2005ab47cfaaSmrg break; 2006ab47cfaaSmrg 2007ab47cfaaSmrg case S3_PROSAVAGE: 2008ab47cfaaSmrg case S3_PROSAVAGEDDR: 2009ab47cfaaSmrg case S3_TWISTER: 2010ab47cfaaSmrg pScrn->videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ] * 1024; 2011ab47cfaaSmrg break; 2012ab47cfaaSmrg 2013ab47cfaaSmrg default: 2014ab47cfaaSmrg /* How did we get here? */ 2015ab47cfaaSmrg pScrn->videoRam = 0; 2016ab47cfaaSmrg break; 2017ab47cfaaSmrg } 2018ab47cfaaSmrg 2019ab47cfaaSmrg psav->videoRambytes = pScrn->videoRam * 1024; 2020ab47cfaaSmrg 2021ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2022ab47cfaaSmrg "probed videoram: %dk\n", 2023ab47cfaaSmrg pScrn->videoRam); 2024ab47cfaaSmrg } else { 2025ab47cfaaSmrg psav->videoRambytes = pScrn->videoRam * 1024; 2026ab47cfaaSmrg 2027ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2028ab47cfaaSmrg "videoram = %dk\n", 2029ab47cfaaSmrg pScrn->videoRam); 2030ab47cfaaSmrg } 2031ab47cfaaSmrg 2032ab47cfaaSmrg /* Get video RAM */ 2033ab47cfaaSmrg if( !pScrn->videoRam && psav->pVbe ) 2034ab47cfaaSmrg { 2035ab47cfaaSmrg /* If VBE is available, ask it about onboard memory. */ 2036ab47cfaaSmrg 2037ab47cfaaSmrg VbeInfoBlock* vib; 2038ab47cfaaSmrg 2039ab47cfaaSmrg vib = VBEGetVBEInfo( psav->pVbe ); 2040ab47cfaaSmrg pScrn->videoRam = vib->TotalMemory * 64; 2041ab47cfaaSmrg VBEFreeVBEInfo( vib ); 2042ab47cfaaSmrg 2043ab47cfaaSmrg /* VBE often cuts 64k off of the RAM total. */ 2044ab47cfaaSmrg 2045ab47cfaaSmrg if( pScrn->videoRam & 64 ) 2046ab47cfaaSmrg pScrn->videoRam += 64; 2047ab47cfaaSmrg 2048ab47cfaaSmrg psav->videoRambytes = pScrn->videoRam * 1024; 2049ab47cfaaSmrg } 2050ab47cfaaSmrg 2051ab47cfaaSmrg 2052ab47cfaaSmrg /* 2053ab47cfaaSmrg * If we're running with acceleration, compute the command overflow 2054ab47cfaaSmrg * buffer location. The command overflow buffer must END at a 2055ab47cfaaSmrg * 4MB boundary; for all practical purposes, that means the very 2056ab47cfaaSmrg * end of the frame buffer. 2057ab47cfaaSmrg */ 2058ab47cfaaSmrg if (psav->NoAccel) { 2059ab47cfaaSmrg psav->cobIndex = 0; 2060ab47cfaaSmrg psav->cobSize = 0; 2061ab47cfaaSmrg } 2062ab47cfaaSmrg else if( ((S3_SAVAGE4_SERIES(psav->Chipset)) || 2063ab47cfaaSmrg (S3_SUPERSAVAGE == psav->Chipset)) && psav->disableCOB ) { 2064ab47cfaaSmrg /* 2065ab47cfaaSmrg * The Savage4 and ProSavage have COB coherency bugs which render 2066ab47cfaaSmrg * the buffer useless. 2067ab47cfaaSmrg */ 2068ab47cfaaSmrg /* 2069ab47cfaaSmrg psav->cobIndex = 2; 2070ab47cfaaSmrg psav->cobSize = 0x8000 << psav->cobIndex; 2071ab47cfaaSmrg */ 2072ab47cfaaSmrg psav->cobIndex = 0; 2073ab47cfaaSmrg psav->cobSize = 0; 2074ab47cfaaSmrg psav->bciThresholdHi = 32; 2075ab47cfaaSmrg psav->bciThresholdLo = 0; 2076ab47cfaaSmrg } else { 2077ab47cfaaSmrg /* We use 128kB for the COB on all other chips. */ 2078ab47cfaaSmrg psav->cobSize = 0x20000; 2079ab47cfaaSmrg if (S3_SAVAGE3D_SERIES(psav->Chipset) || 2080ab47cfaaSmrg psav->Chipset == S3_SAVAGE2000) { 2081ab47cfaaSmrg psav->cobIndex = 7; /* rev.A savage4 apparently also uses 7 */ 2082ab47cfaaSmrg } else { 2083ab47cfaaSmrg psav->cobIndex = 2; 2084ab47cfaaSmrg } 2085ab47cfaaSmrg /* max command size: 2560 entries */ 2086ab47cfaaSmrg psav->bciThresholdHi = psav->cobSize/4 + 32 - 2560; 2087ab47cfaaSmrg psav->bciThresholdLo = psav->bciThresholdHi - 2560; 2088ab47cfaaSmrg } 2089ab47cfaaSmrg 2090ab47cfaaSmrg /* align cob to 128k */ 2091ab47cfaaSmrg psav->cobOffset = (psav->videoRambytes - psav->cobSize) & ~0x1ffff; 2092ab47cfaaSmrg 2093ab47cfaaSmrg /* The cursor must be aligned on a 4k boundary. */ 2094ab47cfaaSmrg psav->CursorKByte = (psav->cobOffset >> 10) - 4; 2095ab47cfaaSmrg psav->endfb = (psav->CursorKByte << 10) - 1; 2096ab47cfaaSmrg 2097ab47cfaaSmrg if (psav->IsPrimary) { 2098ab47cfaaSmrg pScrn->videoRam /= 2; 2099ab47cfaaSmrg psav->videoRambytes = pScrn->videoRam * 1024; 2100ab47cfaaSmrg psav->CursorKByte = (psav->videoRambytes >> 10) - 4; 2101ab47cfaaSmrg psav->endfb = (psav->CursorKByte << 10) - 1; 2102ab47cfaaSmrg psav->videoRambytes *= 2; 2103ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2104ab47cfaaSmrg "Using %dk of videoram for primary head\n", 2105ab47cfaaSmrg pScrn->videoRam); 2106ab47cfaaSmrg } 2107ab47cfaaSmrg 2108ab47cfaaSmrg if(psav->IsSecondary) 2109ab47cfaaSmrg { 2110ab47cfaaSmrg pScrn->videoRam /= 2; 2111ab47cfaaSmrg /*psav->videoRambytes = pScrn->videoRam * 1024;*/ 2112ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2113ab47cfaaSmrg "Using %dk of videoram for secondary head\n", 2114ab47cfaaSmrg pScrn->videoRam); 2115ab47cfaaSmrg } 2116ab47cfaaSmrg 2117ab47cfaaSmrg pScrn->fbOffset = (psav->IsSecondary) 2118ab47cfaaSmrg ? pScrn->videoRam * 1024 : 0; 2119ab47cfaaSmrg 2120ab47cfaaSmrg /* reset graphics engine to avoid memory corruption */ 2121ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2122ab47cfaaSmrg cr66 = VGAIN8(vgaCRReg); 2123ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66 | 0x02); 2124ab47cfaaSmrg usleep(10000); 2125ab47cfaaSmrg 2126ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2127ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66 & ~0x02); /* clear reset flag */ 2128ab47cfaaSmrg usleep(10000); 2129ab47cfaaSmrg 2130ab47cfaaSmrg /* Set status word positions based on chip type. */ 2131ab47cfaaSmrg SavageInitStatus(pScrn); 2132ab47cfaaSmrg 2133ab47cfaaSmrg /* check for DVI/flat panel */ 2134ab47cfaaSmrg dvi = FALSE; 2135ab47cfaaSmrg if (psav->Chipset == S3_SAVAGE4) { 2136ab47cfaaSmrg unsigned char sr30 = 0x00; 2137ab47cfaaSmrg VGAOUT8(0x3c4, 0x30); 2138ab47cfaaSmrg /* clear bit 1 */ 2139ab47cfaaSmrg VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x02); 2140ab47cfaaSmrg sr30 = VGAIN8(0x3c5); 2141ab47cfaaSmrg if (sr30 & 0x02 /*0x04 */) { 2142ab47cfaaSmrg dvi = TRUE; 2143ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Digital Flat Panel Detected\n"); 2144ab47cfaaSmrg } 2145ab47cfaaSmrg } 2146ab47cfaaSmrg 2147ab47cfaaSmrg if( (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || 2148ab47cfaaSmrg S3_MOBILE_TWISTER_SERIES(psav->Chipset)) && !psav->CrtOnly ) { 2149ab47cfaaSmrg psav->DisplayType = MT_LCD; 2150ab47cfaaSmrg } else if (dvi || ((psav->Chipset == S3_SAVAGE4) && psav->dvi)) { 2151ab47cfaaSmrg psav->DisplayType = MT_DFP; 2152ab47cfaaSmrg } else { 2153ab47cfaaSmrg psav->DisplayType = MT_CRT; 2154ab47cfaaSmrg } 2155ab47cfaaSmrg 2156ab47cfaaSmrg if (psav->IsSecondary) 2157ab47cfaaSmrg psav->DisplayType = MT_CRT; 2158ab47cfaaSmrg 2159ab47cfaaSmrg /* Do the DDC dance. */ 2160ab47cfaaSmrg SavageDoDDC(pScrn); 2161ab47cfaaSmrg 2162ab47cfaaSmrg /* set up ramdac max clock - might be altered by SavageGetPanelInfo */ 2163ab47cfaaSmrg if (pScrn->bitsPerPixel >= 24) 2164ab47cfaaSmrg psav->maxClock = 220000; 2165ab47cfaaSmrg else 2166ab47cfaaSmrg psav->maxClock = 250000; 2167ab47cfaaSmrg 2168ab47cfaaSmrg /* detect current mclk */ 2169ab47cfaaSmrg VGAOUT8(0x3c4, 0x08); 2170ab47cfaaSmrg sr8 = VGAIN8(0x3c5); 2171ab47cfaaSmrg VGAOUT8(0x3c5, 0x06); 2172ab47cfaaSmrg VGAOUT8(0x3c4, 0x10); 2173ab47cfaaSmrg n = VGAIN8(0x3c5); 2174ab47cfaaSmrg VGAOUT8(0x3c4, 0x11); 2175ab47cfaaSmrg m = VGAIN8(0x3c5); 2176ab47cfaaSmrg VGAOUT8(0x3c4, 0x08); 2177ab47cfaaSmrg VGAOUT8(0x3c5, sr8); 2178ab47cfaaSmrg m &= 0x7f; 2179ab47cfaaSmrg n1 = n & 0x1f; 2180ab47cfaaSmrg n2 = (n >> 5) & 0x03; 2181ab47cfaaSmrg mclk = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100; 2182ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected current MCLK value of %1.3f MHz\n", 2183ab47cfaaSmrg mclk / 1000.0); 2184ab47cfaaSmrg 2185ab47cfaaSmrg pScrn->maxHValue = 2048 << 3; /* 11 bits of h_total 8-pixel units */ 2186ab47cfaaSmrg pScrn->maxVValue = 2048; /* 11 bits of v_total */ 2187ab47cfaaSmrg pScrn->virtualX = pScrn->display->virtualX; 2188ab47cfaaSmrg pScrn->virtualY = pScrn->display->virtualY; 2189ab47cfaaSmrg 2190ab47cfaaSmrg /* Check LCD panel information */ 2191ab47cfaaSmrg 2192ab47cfaaSmrg if(psav->DisplayType == MT_LCD) 2193ab47cfaaSmrg { 2194ab47cfaaSmrg SavageGetPanelInfo(pScrn); 2195ab47cfaaSmrg SavageAddPanelMode(pScrn); 2196ab47cfaaSmrg } 2197ab47cfaaSmrg 2198ab47cfaaSmrg#if 0 2199ab47cfaaSmrg if (psav->CrtOnly && !psav->UseBIOS) { 2200ab47cfaaSmrg VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */ 2201ab47cfaaSmrg VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x10); /* disable FP */ 2202ab47cfaaSmrg if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) /*|| 2203ab47cfaaSmrg S3_MOBILE_TWISTER_SERIES(psav->Chipset)*/) { /* not sure this works on mobile prosavage */ 2204ab47cfaaSmrg VGAOUT8(0x3c4, 0x31); 2205ab47cfaaSmrg VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x04); /* make sure crtc1 is crt source */ 2206ab47cfaaSmrg } 2207ab47cfaaSmrg } 2208ab47cfaaSmrg#endif 2209ab47cfaaSmrg 2210ab47cfaaSmrg if( psav->UseBIOS ) 2211ab47cfaaSmrg { 2212ab47cfaaSmrg /* Go probe the BIOS for all the modes and refreshes at this depth. */ 2213ab47cfaaSmrg 2214ab47cfaaSmrg if( psav->ModeTable ) 2215ab47cfaaSmrg { 2216ab47cfaaSmrg SavageFreeBIOSModeTable( psav, &psav->ModeTable ); 2217ab47cfaaSmrg } 2218ab47cfaaSmrg 2219ab47cfaaSmrg psav->ModeTable = SavageGetBIOSModeTable( psav, psav->primStreamBpp ); 2220ab47cfaaSmrg 2221ab47cfaaSmrg if( !psav->ModeTable || !psav->ModeTable->NumModes ) { 2222ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2223ab47cfaaSmrg "Failed to fetch any BIOS modes. Disabling BIOS.\n"); 2224ab47cfaaSmrg psav->UseBIOS = FALSE; 2225ab47cfaaSmrg } 2226ab47cfaaSmrg else 2227ab47cfaaSmrg /*if( xf86Verbose )*/ 2228ab47cfaaSmrg { 2229ab47cfaaSmrg SavageModeEntryPtr pmt; 2230ab47cfaaSmrg 2231ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2232ab47cfaaSmrg "Found %d modes at this depth:\n", 2233ab47cfaaSmrg psav->ModeTable->NumModes); 2234ab47cfaaSmrg 2235ab47cfaaSmrg for( 2236ab47cfaaSmrg i = 0, pmt = psav->ModeTable->Modes; 2237ab47cfaaSmrg i < psav->ModeTable->NumModes; 2238ab47cfaaSmrg i++, pmt++ ) 2239ab47cfaaSmrg { 2240ab47cfaaSmrg int j; 2241ab47cfaaSmrg ErrorF( " [%03x] %d x %d", 2242ab47cfaaSmrg pmt->VesaMode, pmt->Width, pmt->Height ); 2243ab47cfaaSmrg for( j = 0; j < pmt->RefreshCount; j++ ) 2244ab47cfaaSmrg { 2245ab47cfaaSmrg ErrorF( ", %dHz", pmt->RefreshRate[j] ); 2246ab47cfaaSmrg } 2247ab47cfaaSmrg ErrorF( "\n"); 2248ab47cfaaSmrg } 2249ab47cfaaSmrg } 2250ab47cfaaSmrg } 2251ab47cfaaSmrg 2252ab47cfaaSmrg clockRanges = xnfalloc(sizeof(ClockRange)); 2253ab47cfaaSmrg clockRanges->next = NULL; 2254ab47cfaaSmrg clockRanges->minClock = 10000; 2255ab47cfaaSmrg clockRanges->maxClock = psav->maxClock; 2256ab47cfaaSmrg clockRanges->clockIndex = -1; 2257ab47cfaaSmrg clockRanges->interlaceAllowed = TRUE; 2258ab47cfaaSmrg clockRanges->doubleScanAllowed = TRUE; 2259ab47cfaaSmrg clockRanges->ClockDivFactor = 1.0; 2260ab47cfaaSmrg clockRanges->ClockMulFactor = 1.0; 2261ab47cfaaSmrg 2262ab47cfaaSmrg i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 2263ab47cfaaSmrg pScrn->display->modes, clockRanges, NULL, 2264ab47cfaaSmrg 256, 2048, 16 * pScrn->bitsPerPixel, 2265ab47cfaaSmrg 128, 2048, 2266ab47cfaaSmrg pScrn->virtualX, pScrn->virtualY, 2267ab47cfaaSmrg psav->videoRambytes, LOOKUP_BEST_REFRESH); 2268ab47cfaaSmrg 2269ab47cfaaSmrg if (i == -1) { 2270ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86ValidateModes failure\n"); 2271ab47cfaaSmrg SavageFreeRec(pScrn); 2272ab47cfaaSmrg vbeFree(psav->pVbe); 2273ab47cfaaSmrg psav->pVbe = NULL; 2274ab47cfaaSmrg return FALSE; 2275ab47cfaaSmrg } 2276ab47cfaaSmrg 2277ab47cfaaSmrg xf86PruneDriverModes(pScrn); 2278ab47cfaaSmrg 2279ab47cfaaSmrg if (i == 0 || pScrn->modes == NULL) { 2280ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 2281ab47cfaaSmrg SavageFreeRec(pScrn); 2282ab47cfaaSmrg vbeFree(psav->pVbe); 2283ab47cfaaSmrg psav->pVbe = NULL; 2284ab47cfaaSmrg return FALSE; 2285ab47cfaaSmrg } 2286ab47cfaaSmrg 2287ab47cfaaSmrg xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 2288ab47cfaaSmrg pScrn->currentMode = pScrn->modes; 2289ab47cfaaSmrg xf86PrintModes(pScrn); 2290ab47cfaaSmrg xf86SetDpi(pScrn, 0, 0); 2291ab47cfaaSmrg 2292ab47cfaaSmrg if (xf86LoadSubModule(pScrn, "fb") == NULL) { 2293ab47cfaaSmrg SavageFreeRec(pScrn); 2294ab47cfaaSmrg vbeFree(psav->pVbe); 2295ab47cfaaSmrg psav->pVbe = NULL; 2296ab47cfaaSmrg return FALSE; 2297ab47cfaaSmrg } 2298ab47cfaaSmrg 2299ab47cfaaSmrg xf86LoaderReqSymLists(fbSymbols, NULL); 2300ab47cfaaSmrg 2301ab47cfaaSmrg if( !psav->NoAccel ) { 2302ab47cfaaSmrg 2303ab47cfaaSmrg char *modName = NULL; 2304ab47cfaaSmrg const char **symNames = NULL; 2305ab47cfaaSmrg 2306ab47cfaaSmrg if (psav->useEXA) { 2307ab47cfaaSmrg modName = "exa"; 2308ab47cfaaSmrg symNames = exaSymbols; 2309ab47cfaaSmrg XF86ModReqInfo req; 2310ab47cfaaSmrg int errmaj, errmin; 2311ab47cfaaSmrg memset(&req, 0, sizeof(req)); 2312ab47cfaaSmrg req.majorversion = 2; 2313ab47cfaaSmrg req.minorversion = 0; 2314ab47cfaaSmrg 2315ab47cfaaSmrg if( !LoadSubModule(pScrn->module, modName, 2316ab47cfaaSmrg NULL, NULL, NULL, &req, &errmaj, &errmin) ) { 2317ab47cfaaSmrg LoaderErrorMsg(NULL, modName, errmaj, errmin); 2318ab47cfaaSmrg SavageFreeRec(pScrn); 2319ab47cfaaSmrg vbeFree(psav->pVbe); 2320ab47cfaaSmrg psav->pVbe = NULL; 2321ab47cfaaSmrg return FALSE; 2322ab47cfaaSmrg } 2323ab47cfaaSmrg } else { 2324ab47cfaaSmrg modName = "xaa"; 2325ab47cfaaSmrg symNames = xaaSymbols; 2326ab47cfaaSmrg if( !xf86LoadSubModule(pScrn, modName) ) { 2327ab47cfaaSmrg SavageFreeRec(pScrn); 2328ab47cfaaSmrg vbeFree(psav->pVbe); 2329ab47cfaaSmrg psav->pVbe = NULL; 2330ab47cfaaSmrg return FALSE; 2331ab47cfaaSmrg } 2332ab47cfaaSmrg } 2333ab47cfaaSmrg 2334ab47cfaaSmrg xf86LoaderReqSymLists(symNames, NULL ); 2335ab47cfaaSmrg 2336ab47cfaaSmrg } 2337ab47cfaaSmrg 2338ab47cfaaSmrg if (psav->hwcursor) { 2339ab47cfaaSmrg if (!xf86LoadSubModule(pScrn, "ramdac")) { 2340ab47cfaaSmrg SavageFreeRec(pScrn); 2341ab47cfaaSmrg vbeFree(psav->pVbe); 2342ab47cfaaSmrg psav->pVbe = NULL; 2343ab47cfaaSmrg return FALSE; 2344ab47cfaaSmrg } 2345ab47cfaaSmrg xf86LoaderReqSymLists(ramdacSymbols, NULL); 2346ab47cfaaSmrg } 2347ab47cfaaSmrg 2348ab47cfaaSmrg if (psav->shadowFB) { 2349ab47cfaaSmrg if (!xf86LoadSubModule(pScrn, "shadowfb")) { 2350ab47cfaaSmrg SavageFreeRec(pScrn); 2351ab47cfaaSmrg vbeFree(psav->pVbe); 2352ab47cfaaSmrg psav->pVbe = NULL; 2353ab47cfaaSmrg return FALSE; 2354ab47cfaaSmrg } 2355ab47cfaaSmrg xf86LoaderReqSymLists(shadowSymbols, NULL); 2356ab47cfaaSmrg } 2357ab47cfaaSmrg vbeFree(psav->pVbe); 2358ab47cfaaSmrg 2359ab47cfaaSmrg psav->pVbe = NULL; 2360ab47cfaaSmrg 2361ab47cfaaSmrg return TRUE; 2362ab47cfaaSmrg} 2363ab47cfaaSmrg 2364ab47cfaaSmrg 2365ab47cfaaSmrgstatic Bool SavageEnterVT(int scrnIndex, int flags) 2366ab47cfaaSmrg{ 2367ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 2368ab47cfaaSmrg#ifdef XF86DRI 2369ab47cfaaSmrg SavagePtr psav= SAVPTR(pScrn); 2370ab47cfaaSmrg ScreenPtr pScreen; 2371ab47cfaaSmrg SAVAGESAREAPrivPtr pSAREAPriv; 2372ab47cfaaSmrg#endif 2373ab47cfaaSmrg 2374ab47cfaaSmrg TRACE(("SavageEnterVT(%d)\n", flags)); 2375ab47cfaaSmrg 2376ab47cfaaSmrg gpScrn = pScrn; 2377ab47cfaaSmrg SavageEnableMMIO(pScrn); 2378ab47cfaaSmrg 2379ab47cfaaSmrg#ifdef XF86DRI 2380ab47cfaaSmrg if (psav->directRenderingEnabled) { 2381ab47cfaaSmrg pScreen = screenInfo.screens[scrnIndex]; 2382ab47cfaaSmrg pSAREAPriv = (SAVAGESAREAPrivPtr)DRIGetSAREAPrivate(pScreen); 2383ab47cfaaSmrg /* Assume that 3D state was clobbered, invalidate it by 2384ab47cfaaSmrg * changing ctxOwner in the sarea. */ 2385ab47cfaaSmrg pSAREAPriv->ctxOwner = DRIGetContext(pScreen); 2386ab47cfaaSmrg DRIUnlock(pScreen); 2387ab47cfaaSmrg psav->LockHeld = 0; 2388ab47cfaaSmrg } 2389ab47cfaaSmrg#endif 2390ab47cfaaSmrg if (!SAVPTR(pScrn)->IsSecondary) 2391ab47cfaaSmrg SavageSave(pScrn); 2392ab47cfaaSmrg if(SavageModeInit(pScrn, pScrn->currentMode)) { 2393ab47cfaaSmrg /* some BIOSes seem to enable HW cursor on PM resume */ 2394ab47cfaaSmrg if (!SAVPTR(pScrn)->hwc_on) 2395ab47cfaaSmrg SavageHideCursor( pScrn ); 2396ab47cfaaSmrg return TRUE; 2397ab47cfaaSmrg } 2398ab47cfaaSmrg 2399ab47cfaaSmrg return FALSE; 2400ab47cfaaSmrg} 2401ab47cfaaSmrg 2402ab47cfaaSmrg 2403ab47cfaaSmrgstatic void SavageLeaveVT(int scrnIndex, int flags) 2404ab47cfaaSmrg{ 2405ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 2406ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 2407ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 2408ab47cfaaSmrg vgaRegPtr vgaSavePtr = &hwp->SavedReg; 2409ab47cfaaSmrg SavageRegPtr SavageSavePtr = &psav->SavedReg; 2410ab47cfaaSmrg#ifdef XF86DRI 2411ab47cfaaSmrg ScreenPtr pScreen; 2412ab47cfaaSmrg#endif 2413ab47cfaaSmrg 2414ab47cfaaSmrg TRACE(("SavageLeaveVT(%d)\n", flags)); 2415ab47cfaaSmrg gpScrn = pScrn; 2416ab47cfaaSmrg 2417ab47cfaaSmrg#ifdef XF86DRI 2418ab47cfaaSmrg if (psav->directRenderingEnabled) { 2419ab47cfaaSmrg pScreen = screenInfo.screens[scrnIndex]; 2420ab47cfaaSmrg DRILock(pScreen, 0); 2421ab47cfaaSmrg psav->LockHeld = 1; 2422ab47cfaaSmrg } 2423ab47cfaaSmrg#endif 2424ab47cfaaSmrg if (psav->FBStart2nd || (psav->videoFlags & VF_STREAMS_ON)) 2425ab47cfaaSmrg SavageStreamsOff(pScrn); 2426ab47cfaaSmrg SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE); 2427ab47cfaaSmrg SavageResetStreams(pScrn); 2428ab47cfaaSmrg SavageDisableMMIO(pScrn); 2429ab47cfaaSmrg 2430ab47cfaaSmrg} 2431ab47cfaaSmrg 2432ab47cfaaSmrg 2433ab47cfaaSmrgstatic void SavageSave(ScrnInfoPtr pScrn) 2434ab47cfaaSmrg{ 2435ab47cfaaSmrg unsigned char cr3a, cr53, cr66; 2436ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 2437ab47cfaaSmrg vgaRegPtr vgaSavePtr = &hwp->SavedReg; 2438ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 2439ab47cfaaSmrg SavageRegPtr save = &psav->SavedReg; 2440ab47cfaaSmrg unsigned short vgaCRReg = psav->vgaIOBase + 5; 2441ab47cfaaSmrg unsigned short vgaCRIndex = psav->vgaIOBase + 4; 2442ab47cfaaSmrg 2443ab47cfaaSmrg TRACE(("SavageSave()\n")); 2444ab47cfaaSmrg 2445ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x4838); 2446ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0xa039); 2447ab47cfaaSmrg VGAOUT16(0x3c4, 0x0608); 2448ab47cfaaSmrg 2449ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2450ab47cfaaSmrg cr66 = VGAIN8(vgaCRReg); 2451ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66 | 0x80); 2452ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 2453ab47cfaaSmrg cr3a = VGAIN8(vgaCRReg); 2454ab47cfaaSmrg VGAOUT8(vgaCRReg, cr3a | 0x80); 2455ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x53); 2456ab47cfaaSmrg cr53 = VGAIN8(vgaCRReg); 2457ab47cfaaSmrg VGAOUT8(vgaCRReg, cr53 & 0x7f); 2458ab47cfaaSmrg 2459ab47cfaaSmrg if (xf86IsPrimaryPci(psav->PciInfo)) 2460ab47cfaaSmrg vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL); 2461ab47cfaaSmrg else 2462ab47cfaaSmrg vgaHWSave(pScrn, vgaSavePtr, VGA_SR_MODE); 2463ab47cfaaSmrg 2464ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2465ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66); 2466ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 2467ab47cfaaSmrg VGAOUT8(vgaCRReg, cr3a); 2468ab47cfaaSmrg 2469ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2470ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66); 2471ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 2472ab47cfaaSmrg VGAOUT8(vgaCRReg, cr3a); 2473ab47cfaaSmrg 2474ab47cfaaSmrg /* unlock extended seq regs */ 2475ab47cfaaSmrg VGAOUT8(0x3c4, 0x08); 2476ab47cfaaSmrg save->SR08 = VGAIN8(0x3c5); 2477ab47cfaaSmrg VGAOUT8(0x3c5, 0x06); 2478ab47cfaaSmrg 2479ab47cfaaSmrg /* now save all the extended regs we need */ 2480ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x31); 2481ab47cfaaSmrg save->CR31 = VGAIN8(vgaCRReg); 2482ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x32); 2483ab47cfaaSmrg save->CR32 = VGAIN8(vgaCRReg); 2484ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x34); 2485ab47cfaaSmrg save->CR34 = VGAIN8(vgaCRReg); 2486ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x36); 2487ab47cfaaSmrg save->CR36 = VGAIN8(vgaCRReg); 2488ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 2489ab47cfaaSmrg save->CR3A = VGAIN8(vgaCRReg); 2490ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x40); 2491ab47cfaaSmrg save->CR40 = VGAIN8(vgaCRReg); 2492ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x42); 2493ab47cfaaSmrg save->CR42 = VGAIN8(vgaCRReg); 2494ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x45); 2495ab47cfaaSmrg save->CR45 = VGAIN8(vgaCRReg); 2496ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x50); 2497ab47cfaaSmrg save->CR50 = VGAIN8(vgaCRReg); 2498ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x51); 2499ab47cfaaSmrg save->CR51 = VGAIN8(vgaCRReg); 2500ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x53); 2501ab47cfaaSmrg save->CR53 = VGAIN8(vgaCRReg); 2502ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x58); 2503ab47cfaaSmrg save->CR58 = VGAIN8(vgaCRReg); 2504ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x60); 2505ab47cfaaSmrg save->CR60 = VGAIN8(vgaCRReg); 2506ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2507ab47cfaaSmrg save->CR66 = VGAIN8(vgaCRReg); 2508ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x67); 2509ab47cfaaSmrg save->CR67 = VGAIN8(vgaCRReg); 2510ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x68); 2511ab47cfaaSmrg save->CR68 = VGAIN8(vgaCRReg); 2512ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x69); 2513ab47cfaaSmrg save->CR69 = VGAIN8(vgaCRReg); 2514ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x6f); 2515ab47cfaaSmrg save->CR6F = VGAIN8(vgaCRReg); 2516ab47cfaaSmrg 2517ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x33); 2518ab47cfaaSmrg save->CR33 = VGAIN8(vgaCRReg); 2519ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x86); 2520ab47cfaaSmrg save->CR86 = VGAIN8(vgaCRReg); 2521ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x88); 2522ab47cfaaSmrg save->CR88 = VGAIN8(vgaCRReg); 2523ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x90); 2524ab47cfaaSmrg save->CR90 = VGAIN8(vgaCRReg); 2525ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x91); 2526ab47cfaaSmrg save->CR91 = VGAIN8(vgaCRReg); 2527ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0xb0); 2528ab47cfaaSmrg save->CRB0 = VGAIN8(vgaCRReg) | 0x80; 2529ab47cfaaSmrg 2530ab47cfaaSmrg /* extended mode timing regs */ 2531ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3b); 2532ab47cfaaSmrg save->CR3B = VGAIN8(vgaCRReg); 2533ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3c); 2534ab47cfaaSmrg save->CR3C = VGAIN8(vgaCRReg); 2535ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x43); 2536ab47cfaaSmrg save->CR43 = VGAIN8(vgaCRReg); 2537ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x5d); 2538ab47cfaaSmrg save->CR5D = VGAIN8(vgaCRReg); 2539ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x5e); 2540ab47cfaaSmrg save->CR5E = VGAIN8(vgaCRReg); 2541ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x65); 2542ab47cfaaSmrg save->CR65 = VGAIN8(vgaCRReg); 2543ab47cfaaSmrg 2544ab47cfaaSmrg /* save seq extended regs for DCLK PLL programming */ 2545ab47cfaaSmrg VGAOUT8(0x3c4, 0x0e); 2546ab47cfaaSmrg save->SR0E = VGAIN8(0x3c5); 2547ab47cfaaSmrg VGAOUT8(0x3c4, 0x0f); 2548ab47cfaaSmrg save->SR0F = VGAIN8(0x3c5); 2549ab47cfaaSmrg VGAOUT8(0x3c4, 0x10); 2550ab47cfaaSmrg save->SR10 = VGAIN8(0x3c5); 2551ab47cfaaSmrg VGAOUT8(0x3c4, 0x11); 2552ab47cfaaSmrg save->SR11 = VGAIN8(0x3c5); 2553ab47cfaaSmrg VGAOUT8(0x3c4, 0x12); 2554ab47cfaaSmrg save->SR12 = VGAIN8(0x3c5); 2555ab47cfaaSmrg VGAOUT8(0x3c4, 0x13); 2556ab47cfaaSmrg save->SR13 = VGAIN8(0x3c5); 2557ab47cfaaSmrg VGAOUT8(0x3c4, 0x29); 2558ab47cfaaSmrg save->SR29 = VGAIN8(0x3c5); 2559ab47cfaaSmrg 2560ab47cfaaSmrg VGAOUT8(0x3c4, 0x15); 2561ab47cfaaSmrg save->SR15 = VGAIN8(0x3c5); 2562ab47cfaaSmrg VGAOUT8(0x3c4, 0x30); 2563ab47cfaaSmrg save->SR30 = VGAIN8(0x3c5); 2564ab47cfaaSmrg VGAOUT8(0x3c4, 0x18); 2565ab47cfaaSmrg save->SR18 = VGAIN8(0x3c5); 2566ab47cfaaSmrg VGAOUT8(0x3c4, 0x1b); 2567ab47cfaaSmrg save->SR1B = VGAIN8(0x3c5); 2568ab47cfaaSmrg 2569ab47cfaaSmrg /* Save flat panel expansion registers. */ 2570ab47cfaaSmrg 2571ab47cfaaSmrg if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || 2572ab47cfaaSmrg S3_MOBILE_TWISTER_SERIES(psav->Chipset)) { 2573ab47cfaaSmrg int i; 2574ab47cfaaSmrg for( i = 0; i < 8; i++ ) { 2575ab47cfaaSmrg VGAOUT8(0x3c4, 0x54+i); 2576ab47cfaaSmrg save->SR54[i] = VGAIN8(0x3c5); 2577ab47cfaaSmrg } 2578ab47cfaaSmrg } 2579ab47cfaaSmrg 2580ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2581ab47cfaaSmrg cr66 = VGAIN8(vgaCRReg); 2582ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66 | 0x80); 2583ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 2584ab47cfaaSmrg cr3a = VGAIN8(vgaCRReg); 2585ab47cfaaSmrg VGAOUT8(vgaCRReg, cr3a | 0x80); 2586ab47cfaaSmrg 2587ab47cfaaSmrg /* now save MIU regs */ 2588ab47cfaaSmrg if( ! S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) { 2589ab47cfaaSmrg save->MMPR0 = INREG(FIFO_CONTROL_REG); 2590ab47cfaaSmrg save->MMPR1 = INREG(MIU_CONTROL_REG); 2591ab47cfaaSmrg save->MMPR2 = INREG(STREAMS_TIMEOUT_REG); 2592ab47cfaaSmrg save->MMPR3 = INREG(MISC_TIMEOUT_REG); 2593ab47cfaaSmrg } 2594ab47cfaaSmrg 2595ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 2596ab47cfaaSmrg VGAOUT8(vgaCRReg, cr3a); 2597ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2598ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66); 2599ab47cfaaSmrg 2600ab47cfaaSmrg if (!psav->ModeStructInit) { 2601ab47cfaaSmrg vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); 2602ab47cfaaSmrg memcpy(&psav->ModeReg, save, sizeof(SavageRegRec)); 2603ab47cfaaSmrg psav->ModeStructInit = TRUE; 2604ab47cfaaSmrg } 2605ab47cfaaSmrg 2606ab47cfaaSmrg#if 0 2607ab47cfaaSmrg if (xf86GetVerbosity() > 1) 2608ab47cfaaSmrg SavagePrintRegs(pScrn); 2609ab47cfaaSmrg#endif 2610ab47cfaaSmrg 2611ab47cfaaSmrg return; 2612ab47cfaaSmrg} 2613ab47cfaaSmrg 2614ab47cfaaSmrg 2615ab47cfaaSmrgstatic void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, 2616ab47cfaaSmrg SavageRegPtr restore, Bool Entering) 2617ab47cfaaSmrg{ 2618ab47cfaaSmrg unsigned char tmp, cr3a, cr66; 2619ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 2620ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 2621ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 2622ab47cfaaSmrg 2623ab47cfaaSmrg 2624ab47cfaaSmrg vgaIOBase = hwp->IOBase; 2625ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 2626ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 2627ab47cfaaSmrg 2628ab47cfaaSmrg TRACE(("SavageWriteMode(%x)\n", restore->mode)); 2629ab47cfaaSmrg 2630ab47cfaaSmrg#ifdef XF86DRI 2631ab47cfaaSmrg if (psav->directRenderingEnabled) { 2632ab47cfaaSmrg DRILock(screenInfo.screens[pScrn->scrnIndex], 0); 2633ab47cfaaSmrg psav->LockHeld = 1; 2634ab47cfaaSmrg } 2635ab47cfaaSmrg#endif 2636ab47cfaaSmrg 2637ab47cfaaSmrg if (psav->IsSecondary) { 2638ab47cfaaSmrg /* Set up the mode. Don't clear video RAM. */ 2639ab47cfaaSmrg SavageSetVESAMode( psav, restore->mode | 0x8000, restore->refresh ); 2640ab47cfaaSmrg SavageSetGBD(pScrn); 2641ab47cfaaSmrg return; 2642ab47cfaaSmrg } 2643ab47cfaaSmrg 2644ab47cfaaSmrg if( Entering && 2645ab47cfaaSmrg (!S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || (psav->ForceInit)) 2646ab47cfaaSmrg ) 2647ab47cfaaSmrg SavageInitialize2DEngine(pScrn); 2648ab47cfaaSmrg 2649ab47cfaaSmrg /* 2650ab47cfaaSmrg * If we figured out a VESA mode number for this timing, just use 2651ab47cfaaSmrg * the S3 BIOS to do the switching, with a few additional tweaks. 2652ab47cfaaSmrg */ 2653ab47cfaaSmrg 2654ab47cfaaSmrg if( psav->UseBIOS && restore->mode > 0x13 ) 2655ab47cfaaSmrg { 2656ab47cfaaSmrg int width; 2657ab47cfaaSmrg unsigned short cr6d; 2658ab47cfaaSmrg unsigned short cr79 = 0; 2659ab47cfaaSmrg 2660ab47cfaaSmrg /* Set up the mode. Don't clear video RAM. */ 2661ab47cfaaSmrg SavageSetVESAMode( psav, restore->mode | 0x8000, restore->refresh ); 2662ab47cfaaSmrg 2663ab47cfaaSmrg /* Restore the DAC. */ 2664ab47cfaaSmrg vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_CMAP); 2665ab47cfaaSmrg 2666ab47cfaaSmrg /* Unlock the extended registers. */ 2667ab47cfaaSmrg 2668ab47cfaaSmrg#if 0 2669ab47cfaaSmrg /* Which way is better? */ 2670ab47cfaaSmrg hwp->writeCrtc( hwp, 0x38, 0x48 ); 2671ab47cfaaSmrg hwp->writeCrtc( hwp, 0x39, 0xa0 ); 2672ab47cfaaSmrg hwp->writeSeq( hwp, 0x08, 0x06 ); 2673ab47cfaaSmrg#endif 2674ab47cfaaSmrg 2675ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x4838); 2676ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0xA039); 2677ab47cfaaSmrg VGAOUT16(0x3c4, 0x0608); 2678ab47cfaaSmrg 2679ab47cfaaSmrg /* Enable linear addressing. */ 2680ab47cfaaSmrg 2681ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x1358); 2682ab47cfaaSmrg 2683ab47cfaaSmrg /* Disable old MMIO. */ 2684ab47cfaaSmrg 2685ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x53); 2686ab47cfaaSmrg VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) & ~0x10); 2687ab47cfaaSmrg 2688ab47cfaaSmrg /* Disable HW cursor */ 2689ab47cfaaSmrg 2690ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x0045); 2691ab47cfaaSmrg 2692ab47cfaaSmrg /* Set the color mode. */ 2693ab47cfaaSmrg 2694ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x67); 2695ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR67); 2696ab47cfaaSmrg 2697ab47cfaaSmrg /* Enable gamma correction, set CLUT to 8 bit */ 2698ab47cfaaSmrg 2699ab47cfaaSmrg VGAOUT8(0x3c4, 0x1b); 2700ab47cfaaSmrg if( (pScrn->bitsPerPixel == 32) && !psav->DGAactive 2701ab47cfaaSmrg && ! psav->FBStart2nd ) 2702ab47cfaaSmrg VGAOUT8(0x3c5, 0x18 ); 2703ab47cfaaSmrg else 2704ab47cfaaSmrg VGAOUT8(0x3c5, 0x10 ); 2705ab47cfaaSmrg 2706ab47cfaaSmrg /* We may need TV/panel fixups here. See s3bios.c line 2904. */ 2707ab47cfaaSmrg 2708ab47cfaaSmrg /* Set FIFO fetch delay. */ 2709ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x85); 2710ab47cfaaSmrg VGAOUT8(vgaCRReg, (VGAIN8(vgaCRReg) & 0xf8) | 0x03); 2711ab47cfaaSmrg 2712ab47cfaaSmrg /* Patch CR79. These values are magical. */ 2713ab47cfaaSmrg 2714ab47cfaaSmrg if( !S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) 2715ab47cfaaSmrg { 2716ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x6d); 2717ab47cfaaSmrg cr6d = VGAIN8(vgaCRReg); 2718ab47cfaaSmrg 2719ab47cfaaSmrg cr79 = 0x04; 2720ab47cfaaSmrg 2721ab47cfaaSmrg if( pScrn->displayWidth >= 1024 ) 2722ab47cfaaSmrg { 2723ab47cfaaSmrg if(psav->primStreamBpp == 32 ) 2724ab47cfaaSmrg { 2725ab47cfaaSmrg if( restore->refresh >= 130 ) 2726ab47cfaaSmrg cr79 = 0x03; 2727ab47cfaaSmrg else if( pScrn->displayWidth >= 1280 ) 2728ab47cfaaSmrg cr79 = 0x02; 2729ab47cfaaSmrg else if( 2730ab47cfaaSmrg (pScrn->displayWidth == 1024) && 2731ab47cfaaSmrg (restore->refresh >= 75) 2732ab47cfaaSmrg ) 2733ab47cfaaSmrg { 2734ab47cfaaSmrg if( cr6d && LCD_ACTIVE ) 2735ab47cfaaSmrg cr79 = 0x05; 2736ab47cfaaSmrg else 2737ab47cfaaSmrg cr79 = 0x08; 2738ab47cfaaSmrg } 2739ab47cfaaSmrg } 2740ab47cfaaSmrg else if( psav->primStreamBpp == 16) 2741ab47cfaaSmrg { 2742ab47cfaaSmrg 2743ab47cfaaSmrg/* The windows driver uses 0x13 for 16-bit 130Hz, but I see terrible 2744ab47cfaaSmrg * screen artifacts with that value. Let's keep it low for now. 2745ab47cfaaSmrg * if( restore->refresh >= 130 ) 2746ab47cfaaSmrg * cr79 = 0x13; 2747ab47cfaaSmrg * else 2748ab47cfaaSmrg */ 2749ab47cfaaSmrg if( pScrn->displayWidth == 1024 ) 2750ab47cfaaSmrg { 2751ab47cfaaSmrg if( cr6d && LCD_ACTIVE ) 2752ab47cfaaSmrg cr79 = 0x08; 2753ab47cfaaSmrg else 2754ab47cfaaSmrg cr79 = 0x0e; 2755ab47cfaaSmrg } 2756ab47cfaaSmrg } 2757ab47cfaaSmrg } 2758ab47cfaaSmrg } 2759ab47cfaaSmrg 2760ab47cfaaSmrg if( (psav->Chipset != S3_SAVAGE2000) && 2761ab47cfaaSmrg !S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) 2762ab47cfaaSmrg VGAOUT16(vgaCRIndex, (cr79 << 8) | 0x79); 2763ab47cfaaSmrg 2764ab47cfaaSmrg /* Make sure 16-bit memory access is enabled. */ 2765ab47cfaaSmrg 2766ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x0c31); 2767ab47cfaaSmrg 2768ab47cfaaSmrg /* Enable the graphics engine. */ 2769ab47cfaaSmrg 2770ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x0140); 2771ab47cfaaSmrg 2772ab47cfaaSmrg /* Handle the pitch. */ 2773ab47cfaaSmrg 2774ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x50); 2775ab47cfaaSmrg VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1); 2776ab47cfaaSmrg 2777ab47cfaaSmrg width = (pScrn->displayWidth * (psav->primStreamBpp / 8)) >> 3; 2778ab47cfaaSmrg VGAOUT16(vgaCRIndex, ((width & 0xff) << 8) | 0x13 ); 2779ab47cfaaSmrg VGAOUT16(vgaCRIndex, ((width & 0x300) << 4) | 0x51 ); 2780ab47cfaaSmrg 2781ab47cfaaSmrg /* Some non-S3 BIOSes enable block write even on non-SGRAM devices. */ 2782ab47cfaaSmrg 2783ab47cfaaSmrg switch( psav->Chipset ) 2784ab47cfaaSmrg { 2785ab47cfaaSmrg case S3_SAVAGE2000: 2786ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x73); 2787ab47cfaaSmrg VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) & 0xdf ); 2788ab47cfaaSmrg break; 2789ab47cfaaSmrg 2790ab47cfaaSmrg case S3_SAVAGE3D: 2791ab47cfaaSmrg case S3_SAVAGE4: 2792ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x68); 2793ab47cfaaSmrg if( !(VGAIN8(vgaCRReg) & 0x80) ) 2794ab47cfaaSmrg { 2795ab47cfaaSmrg /* Not SGRAM; disable block write. */ 2796ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x88); 2797ab47cfaaSmrg VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0x10); 2798ab47cfaaSmrg } 2799ab47cfaaSmrg break; 2800ab47cfaaSmrg } 2801ab47cfaaSmrg 2802ab47cfaaSmrg /* set the correct clock for some BIOSes */ 2803ab47cfaaSmrg VGAOUT8(VGA_MISC_OUT_W, 2804ab47cfaaSmrg VGAIN8(VGA_MISC_OUT_R) | 0x0C); 2805ab47cfaaSmrg /* Some BIOSes turn on clock doubling on non-doubled modes */ 2806ab47cfaaSmrg if (pScrn->bitsPerPixel < 24) { 2807ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x67); 2808ab47cfaaSmrg if (!(VGAIN8(vgaCRReg) & 0x10)) { 2809ab47cfaaSmrg VGAOUT8(0x3c4, 0x15); 2810ab47cfaaSmrg VGAOUT8(0x3c5, VGAIN8(0x3C5) & ~0x10); 2811ab47cfaaSmrg VGAOUT8(0x3c4, 0x18); 2812ab47cfaaSmrg VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x80); 2813ab47cfaaSmrg } 2814ab47cfaaSmrg } 2815ab47cfaaSmrg 2816ab47cfaaSmrg SavageInitialize2DEngine(pScrn); 2817ab47cfaaSmrg 2818ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x0140); 2819ab47cfaaSmrg 2820ab47cfaaSmrg SavageSetGBD(pScrn); 2821ab47cfaaSmrg 2822ab47cfaaSmrg 2823ab47cfaaSmrg#ifdef XF86DRI 2824ab47cfaaSmrg if (psav->directRenderingEnabled) 2825ab47cfaaSmrg DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); 2826ab47cfaaSmrg psav->LockHeld = 0; 2827ab47cfaaSmrg#endif 2828ab47cfaaSmrg 2829ab47cfaaSmrg return; 2830ab47cfaaSmrg } 2831ab47cfaaSmrg 2832ab47cfaaSmrg VGAOUT8(0x3c2, 0x23); 2833ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x4838); 2834ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0xa039); 2835ab47cfaaSmrg VGAOUT16(0x3c4, 0x0608); 2836ab47cfaaSmrg 2837ab47cfaaSmrg vgaHWProtect(pScrn, TRUE); 2838ab47cfaaSmrg 2839ab47cfaaSmrg /* will we be reenabling STREAMS for the new mode? */ 2840ab47cfaaSmrg psav->STREAMSRunning = 0; 2841ab47cfaaSmrg 2842ab47cfaaSmrg /* reset GE to make sure nothing is going on */ 2843ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2844ab47cfaaSmrg if(VGAIN8(vgaCRReg) & 0x01) 2845ab47cfaaSmrg SavageGEReset(pScrn,0,__LINE__,__FILE__); 2846ab47cfaaSmrg 2847ab47cfaaSmrg /* 2848ab47cfaaSmrg * Some Savage/MX and /IX systems go nuts when trying to exit the 2849ab47cfaaSmrg * server after WindowMaker has displayed a gradient background. I 2850ab47cfaaSmrg * haven't been able to find what causes it, but a non-destructive 2851ab47cfaaSmrg * switch to mode 3 here seems to eliminate the issue. 2852ab47cfaaSmrg */ 2853ab47cfaaSmrg 2854ab47cfaaSmrg if( ((restore->CR31 & 0x0a) == 0) && psav->pVbe ) { 2855ab47cfaaSmrg SavageSetTextMode( psav ); 2856ab47cfaaSmrg } 2857ab47cfaaSmrg 2858ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x67); 2859ab47cfaaSmrg (void) VGAIN8(vgaCRReg); 2860ab47cfaaSmrg /*VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c);*/ /* no STREAMS yet */ 2861ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR67 & ~0x0e); /* no STREAMS yet old and new */ 2862ab47cfaaSmrg 2863ab47cfaaSmrg /* restore extended regs */ 2864ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 2865ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR66); 2866ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 2867ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR3A); 2868ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x31); 2869ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR31); 2870ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x32); 2871ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR32); 2872ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x58); 2873ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR58); 2874ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x53); 2875ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR53 & 0x7f); 2876ab47cfaaSmrg 2877ab47cfaaSmrg VGAOUT16(0x3c4, 0x0608); 2878ab47cfaaSmrg 2879ab47cfaaSmrg /* Restore DCLK registers. */ 2880ab47cfaaSmrg 2881ab47cfaaSmrg VGAOUT8(0x3c4, 0x0e); 2882ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR0E); 2883ab47cfaaSmrg VGAOUT8(0x3c4, 0x0f); 2884ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR0F); 2885ab47cfaaSmrg VGAOUT8(0x3c4, 0x29); 2886ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR29); 2887ab47cfaaSmrg VGAOUT8(0x3c4, 0x15); 2888ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR15); 2889ab47cfaaSmrg 2890ab47cfaaSmrg /* Restore flat panel expansion registers. */ 2891ab47cfaaSmrg if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || 2892ab47cfaaSmrg S3_MOBILE_TWISTER_SERIES(psav->Chipset)) { 2893ab47cfaaSmrg int i; 2894ab47cfaaSmrg for( i = 0; i < 8; i++ ) { 2895ab47cfaaSmrg VGAOUT8(0x3c4, 0x54+i); 2896ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR54[i]); 2897ab47cfaaSmrg } 2898ab47cfaaSmrg } 2899ab47cfaaSmrg 2900ab47cfaaSmrg /* restore the standard vga regs */ 2901ab47cfaaSmrg if (xf86IsPrimaryPci(psav->PciInfo)) 2902ab47cfaaSmrg vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL); 2903ab47cfaaSmrg else 2904ab47cfaaSmrg vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_MODE); 2905ab47cfaaSmrg 2906ab47cfaaSmrg /* extended mode timing registers */ 2907ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x53); 2908ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR53); 2909ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x5d); 2910ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR5D); 2911ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x5e); 2912ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR5E); 2913ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3b); 2914ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR3B); 2915ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3c); 2916ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR3C); 2917ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x43); 2918ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR43); 2919ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x65); 2920ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR65); 2921ab47cfaaSmrg 2922ab47cfaaSmrg /* restore the desired video mode with cr67 */ 2923ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x67); 2924ab47cfaaSmrg /*VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c);*/ /* no STREAMS yet */ 2925ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR67 & ~0x0e); /* no streams for new and old streams engines */ 2926ab47cfaaSmrg 2927ab47cfaaSmrg /* other mode timing and extended regs */ 2928ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x34); 2929ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR34); 2930ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x40); 2931ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR40); 2932ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x42); 2933ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR42); 2934ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x45); 2935ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR45); 2936ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x50); 2937ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR50); 2938ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x51); 2939ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR51); 2940ab47cfaaSmrg 2941ab47cfaaSmrg /* memory timings */ 2942ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x36); 2943ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR36); 2944ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x60); 2945ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR60); 2946ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x68); 2947ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR68); 2948ab47cfaaSmrg VerticalRetraceWait(); 2949ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x69); 2950ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR69); 2951ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x6f); 2952ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR6F); 2953ab47cfaaSmrg 2954ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x33); 2955ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR33); 2956ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x86); 2957ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR86); 2958ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x88); 2959ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR88); 2960ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x90); 2961ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR90); 2962ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x91); 2963ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR91); 2964ab47cfaaSmrg if( psav->Chipset == S3_SAVAGE4 ) 2965ab47cfaaSmrg { 2966ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0xb0); 2967ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CRB0); 2968ab47cfaaSmrg } 2969ab47cfaaSmrg 2970ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x32); 2971ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR32); 2972ab47cfaaSmrg 2973ab47cfaaSmrg /* unlock extended seq regs */ 2974ab47cfaaSmrg VGAOUT8(0x3c4, 0x08); 2975ab47cfaaSmrg VGAOUT8(0x3c5, 0x06); 2976ab47cfaaSmrg 2977ab47cfaaSmrg /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates that 2978ab47cfaaSmrg * we should leave the default SR10 and SR11 values there. 2979ab47cfaaSmrg */ 2980ab47cfaaSmrg if (restore->SR10 != 255) { 2981ab47cfaaSmrg VGAOUT8(0x3c4, 0x10); 2982ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR10); 2983ab47cfaaSmrg VGAOUT8(0x3c4, 0x11); 2984ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR11); 2985ab47cfaaSmrg } 2986ab47cfaaSmrg 2987ab47cfaaSmrg /* restore extended seq regs for dclk */ 2988ab47cfaaSmrg VGAOUT8(0x3c4, 0x0e); 2989ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR0E); 2990ab47cfaaSmrg VGAOUT8(0x3c4, 0x0f); 2991ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR0F); 2992ab47cfaaSmrg VGAOUT8(0x3c4, 0x12); 2993ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR12); 2994ab47cfaaSmrg VGAOUT8(0x3c4, 0x13); 2995ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR13); 2996ab47cfaaSmrg VGAOUT8(0x3c4, 0x29); 2997ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR29); 2998ab47cfaaSmrg 2999ab47cfaaSmrg VGAOUT8(0x3c4, 0x18); 3000ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR18); 3001ab47cfaaSmrg VGAOUT8(0x3c4, 0x1b); 3002ab47cfaaSmrg if( psav->DGAactive ) 3003ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR1B & ~0x08 ); 3004ab47cfaaSmrg else 3005ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR1B); 3006ab47cfaaSmrg 3007ab47cfaaSmrg /* load new m, n pll values for dclk & mclk */ 3008ab47cfaaSmrg VGAOUT8(0x3c4, 0x15); 3009ab47cfaaSmrg tmp = VGAIN8(0x3c5) & ~0x21; 3010ab47cfaaSmrg 3011ab47cfaaSmrg VGAOUT8(0x3c5, tmp | 0x03); 3012ab47cfaaSmrg VGAOUT8(0x3c5, tmp | 0x23); 3013ab47cfaaSmrg VGAOUT8(0x3c5, tmp | 0x03); 3014ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR15); 3015ab47cfaaSmrg usleep( 100 ); 3016ab47cfaaSmrg 3017ab47cfaaSmrg VGAOUT8(0x3c4, 0x30); 3018ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR30); 3019ab47cfaaSmrg VGAOUT8(0x3c4, 0x08); 3020ab47cfaaSmrg VGAOUT8(0x3c5, restore->SR08); 3021ab47cfaaSmrg 3022ab47cfaaSmrg /* now write out cr67 in full, possibly starting STREAMS */ 3023ab47cfaaSmrg VerticalRetraceWait(); 3024ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x67); 3025ab47cfaaSmrg#if 0 3026ab47cfaaSmrg VGAOUT8(vgaCRReg, 0x50); 3027ab47cfaaSmrg usleep(10000); 3028ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x67); 3029ab47cfaaSmrg#endif 3030ab47cfaaSmrg VGAOUT8(vgaCRReg, restore->CR67); 3031ab47cfaaSmrg 3032ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 3033ab47cfaaSmrg cr66 = VGAIN8(vgaCRReg); 3034ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66 | 0x80); 3035ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 3036ab47cfaaSmrg cr3a = VGAIN8(vgaCRReg); 3037ab47cfaaSmrg VGAOUT8(vgaCRReg, cr3a | 0x80); 3038ab47cfaaSmrg 3039ab47cfaaSmrg if (Entering) 3040ab47cfaaSmrg SavageGEReset(pScrn,0,__LINE__,__FILE__); 3041ab47cfaaSmrg 3042ab47cfaaSmrg if( !S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) 3043ab47cfaaSmrg { 3044ab47cfaaSmrg VerticalRetraceWait(); 3045ab47cfaaSmrg OUTREG(FIFO_CONTROL_REG, restore->MMPR0); 3046ab47cfaaSmrg OUTREG(MIU_CONTROL_REG, restore->MMPR1); 3047ab47cfaaSmrg OUTREG(STREAMS_TIMEOUT_REG, restore->MMPR2); 3048ab47cfaaSmrg OUTREG(MISC_TIMEOUT_REG, restore->MMPR3); 3049ab47cfaaSmrg } 3050ab47cfaaSmrg 3051ab47cfaaSmrg /* If we're going into graphics mode and acceleration was enabled, */ 3052ab47cfaaSmrg /* go set up the BCI buffer and the global bitmap descriptor. */ 3053ab47cfaaSmrg 3054ab47cfaaSmrg#if 0 3055ab47cfaaSmrg if( Entering && (!psav->NoAccel) ) 3056ab47cfaaSmrg { 3057ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x50); 3058ab47cfaaSmrg VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1); 3059ab47cfaaSmrg SavageInitialize2DEngine(pScrn); 3060ab47cfaaSmrg } 3061ab47cfaaSmrg#endif 3062ab47cfaaSmrg 3063ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 3064ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66); 3065ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 3066ab47cfaaSmrg VGAOUT8(vgaCRReg, cr3a); 3067ab47cfaaSmrg 3068ab47cfaaSmrg if( Entering ) { 3069ab47cfaaSmrg SavageInitialize2DEngine(pScrn); 3070ab47cfaaSmrg 3071ab47cfaaSmrg VGAOUT16(vgaCRIndex, 0x0140); 3072ab47cfaaSmrg 3073ab47cfaaSmrg SavageSetGBD(pScrn); 3074ab47cfaaSmrg } 3075ab47cfaaSmrg 3076ab47cfaaSmrg vgaHWProtect(pScrn, FALSE); 3077ab47cfaaSmrg 3078ab47cfaaSmrg 3079ab47cfaaSmrg#ifdef XF86DRI 3080ab47cfaaSmrg if (psav->directRenderingEnabled) 3081ab47cfaaSmrg DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); 3082ab47cfaaSmrg psav->LockHeld = 0; 3083ab47cfaaSmrg#endif 3084ab47cfaaSmrg 3085ab47cfaaSmrg return; 3086ab47cfaaSmrg} 3087ab47cfaaSmrg 3088ab47cfaaSmrg 3089ab47cfaaSmrgstatic Bool SavageMapMem(ScrnInfoPtr pScrn) 3090ab47cfaaSmrg{ 3091ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 30928697ee19Smrg int err; 3093ab47cfaaSmrg 3094ab47cfaaSmrg TRACE(("SavageMapMem()\n")); 3095ab47cfaaSmrg 3096ab47cfaaSmrg if( S3_SAVAGE3D_SERIES(psav->Chipset) ) { 30978697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 30988697ee19Smrg psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S3 30998697ee19Smrg + psav->PciInfo->regions[0].base_addr; 31008697ee19Smrg psav->FbRegion.base = psav->PciInfo->regions[0].base_addr; 31018697ee19Smrg#else 31028697ee19Smrg psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S3 31038697ee19Smrg + psav->PciInfo->memBase[0]; 31048697ee19Smrg psav->FbRegion.base = psav->PciInfo->memBase[0]; 31058697ee19Smrg#endif 3106ab47cfaaSmrg } else { 31078697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 31088697ee19Smrg psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S4 31098697ee19Smrg + psav->PciInfo->regions[0].base_addr; 31108697ee19Smrg psav->FbRegion.base = psav->PciInfo->regions[1].base_addr; 31118697ee19Smrg#else 31128697ee19Smrg psav->MmioRegion.base = SAVAGE_NEWMMIO_REGBASE_S4 31138697ee19Smrg + psav->PciInfo->memBase[0]; 31148697ee19Smrg psav->FbRegion.base = psav->PciInfo->memBase[1]; 31158697ee19Smrg#endif 3116ab47cfaaSmrg } 3117ab47cfaaSmrg 31188697ee19Smrg psav->MmioRegion.size = SAVAGE_NEWMMIO_REGSIZE; 31198697ee19Smrg psav->FbRegion.size = psav->videoRambytes; 31208697ee19Smrg 3121ab47cfaaSmrg /* On Paramount and Savage 2000, aperture 0 is PCI base 2. On other 3122ab47cfaaSmrg * chipsets it's in the same BAR as the framebuffer. 3123ab47cfaaSmrg */ 3124ab47cfaaSmrg 31258697ee19Smrg psav->ApertureRegion.size = (psav->IsPrimary || psav->IsSecondary) 31268697ee19Smrg ? (0x01000000 * 2) : (0x01000000 * 5); 31278697ee19Smrg 31288697ee19Smrg if ((psav->Chipset == S3_SUPERSAVAGE) 31298697ee19Smrg || (psav->Chipset == S3_SAVAGE2000)) { 31308697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 31318697ee19Smrg psav->ApertureRegion.base = psav->PciInfo->regions[2].base_addr; 31328697ee19Smrg if (psav->ApertureRegion.size > psav->PciInfo->regions[2].size) 31338697ee19Smrg psav->ApertureRegion.size = psav->PciInfo->regions[2].size; 31348697ee19Smrg#else 31358697ee19Smrg psav->ApertureRegion.base = psav->PciInfo->memBase[2]; 31368697ee19Smrg#endif 3137ab47cfaaSmrg } else { 31388697ee19Smrg psav->ApertureRegion.base = psav->FbRegion.base + 0x02000000; 3139ab47cfaaSmrg } 3140ab47cfaaSmrg 3141ab47cfaaSmrg 3142ab47cfaaSmrg 31438697ee19Smrg if (psav->FbRegion.size != 0) { 31448697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 31458697ee19Smrg err = pci_device_map_range(psav->PciInfo, psav->FbRegion.base, 31468697ee19Smrg psav->FbRegion.size, 31478697ee19Smrg (PCI_DEV_MAP_FLAG_WRITABLE 31488697ee19Smrg | PCI_DEV_MAP_FLAG_WRITE_COMBINE), 31498697ee19Smrg & psav->FbRegion.memory); 31508697ee19Smrg#else 31518697ee19Smrg psav->FbRegion.memory = 31528697ee19Smrg xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 31538697ee19Smrg psav->PciTag, psav->FbRegion.base, 31548697ee19Smrg psav->FbRegion.size); 31558697ee19Smrg err = (psav->FbRegion.memory == NULL) ? errno : 0; 31568697ee19Smrg#endif 31578697ee19Smrg if (err) { 31588697ee19Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 31598697ee19Smrg "Internal error: could not map framebuffer range (%d, %s).\n", 31608697ee19Smrg err, strerror(err)); 31618697ee19Smrg return FALSE; 31628697ee19Smrg } 3163ab47cfaaSmrg 31648697ee19Smrg psav->FBBase = psav->FbRegion.memory; 31658697ee19Smrg psav->FBStart = (psav->IsSecondary) 31668697ee19Smrg ? psav->FBBase + 0x1000000 : psav->FBBase; 3167ab47cfaaSmrg } 3168ab47cfaaSmrg 31698697ee19Smrg if (psav->ApertureRegion.memory == NULL) { 31708697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 31718697ee19Smrg err = pci_device_map_range(psav->PciInfo, psav->ApertureRegion.base, 31728697ee19Smrg psav->ApertureRegion.size, 31738697ee19Smrg (PCI_DEV_MAP_FLAG_WRITABLE 31748697ee19Smrg | PCI_DEV_MAP_FLAG_WRITE_COMBINE), 31758697ee19Smrg & psav->ApertureRegion.memory); 31768697ee19Smrg#else 31778697ee19Smrg psav->ApertureRegion.memory = 31788697ee19Smrg xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 31798697ee19Smrg psav->PciTag, psav->ApertureRegion.base, 31808697ee19Smrg psav->ApertureRegion.size); 31818697ee19Smrg err = (psav->ApertureRegion.memory == NULL) ? errno : 0; 31828697ee19Smrg#endif 31838697ee19Smrg if (err) { 31848697ee19Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 31858697ee19Smrg "Internal error: could not map aperture range (%d, %s).\n", 31868697ee19Smrg err, strerror(err)); 31878697ee19Smrg return FALSE; 31888697ee19Smrg } 3189ab47cfaaSmrg 31908697ee19Smrg psav->ApertureMap = (psav->IsSecondary) 31918697ee19Smrg ? psav->ApertureRegion.memory + 0x1000000 31928697ee19Smrg : psav->ApertureRegion.memory; 31938697ee19Smrg } 3194ab47cfaaSmrg 31958697ee19Smrg if (psav->MmioRegion.memory == NULL) { 31968697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 31978697ee19Smrg err = pci_device_map_range(psav->PciInfo, psav->MmioRegion.base, 31988697ee19Smrg psav->MmioRegion.size, 31998697ee19Smrg (PCI_DEV_MAP_FLAG_WRITABLE), 32008697ee19Smrg & psav->MmioRegion.memory); 32018697ee19Smrg#else 32028697ee19Smrg psav->MmioRegion.memory = 32038697ee19Smrg xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, 32048697ee19Smrg psav->PciTag, psav->MmioRegion.base, 32058697ee19Smrg psav->MmioRegion.size); 32068697ee19Smrg err = (psav->MmioRegion.memory == NULL) ? errno : 0; 32078697ee19Smrg#endif 32088697ee19Smrg if (err) { 32098697ee19Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 32108697ee19Smrg "Internal error: could not map MMIO range (%d, %s).\n", 32118697ee19Smrg err, strerror(err)); 32128697ee19Smrg return FALSE; 32138697ee19Smrg } 3214ab47cfaaSmrg 32158697ee19Smrg psav->MapBase = psav->MmioRegion.memory; 32168697ee19Smrg psav->BciMem = psav->MapBase + 0x10000; 3217ab47cfaaSmrg 32188697ee19Smrg SavageEnableMMIO(pScrn); 3219ab47cfaaSmrg } 3220ab47cfaaSmrg 32218697ee19Smrg pScrn->memPhysBase = psav->FbRegion.base; 3222ab47cfaaSmrg return TRUE; 3223ab47cfaaSmrg} 3224ab47cfaaSmrg 3225ab47cfaaSmrg 3226ab47cfaaSmrgstatic void SavageUnmapMem(ScrnInfoPtr pScrn, int All) 3227ab47cfaaSmrg{ 3228ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 3229ab47cfaaSmrg 3230ab47cfaaSmrg TRACE(("SavageUnmapMem(%x,%x)\n", psav->MapBase, psav->FBBase)); 3231ab47cfaaSmrg 3232ab47cfaaSmrg if (psav->PrimaryVidMapped) { 32338697ee19Smrg vgaHWUnmapMem(pScrn); 32348697ee19Smrg psav->PrimaryVidMapped = FALSE; 3235ab47cfaaSmrg } 3236ab47cfaaSmrg 3237ab47cfaaSmrg SavageDisableMMIO(pScrn); 3238ab47cfaaSmrg 32398697ee19Smrg if (All && (psav->MmioRegion.memory != NULL)) { 32408697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 32418697ee19Smrg pci_device_unmap_range(psav->PciInfo, 32428697ee19Smrg psav->MmioRegion.memory, 32438697ee19Smrg psav->MmioRegion.size); 32448697ee19Smrg#else 32458697ee19Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->MapBase, 32468697ee19Smrg SAVAGE_NEWMMIO_REGSIZE); 32478697ee19Smrg#endif 32488697ee19Smrg 32498697ee19Smrg psav->MmioRegion.memory = NULL; 32508697ee19Smrg psav->MapBase = 0; 32518697ee19Smrg psav->BciMem = 0; 32528697ee19Smrg } 32538697ee19Smrg 32548697ee19Smrg if (psav->FbRegion.memory != NULL) { 32558697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 32568697ee19Smrg pci_device_unmap_range(psav->PciInfo, 32578697ee19Smrg psav->FbRegion.memory, 32588697ee19Smrg psav->FbRegion.size); 32598697ee19Smrg#else 32608697ee19Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->FbRegion.base, 32618697ee19Smrg psav->FbRegion.size); 32628697ee19Smrg#endif 3263ab47cfaaSmrg } 3264ab47cfaaSmrg 32658697ee19Smrg if (psav->ApertureRegion.memory != NULL) { 32668697ee19Smrg#ifdef XSERVER_LIBPCIACCESS 32678697ee19Smrg pci_device_unmap_range(psav->PciInfo, 32688697ee19Smrg psav->ApertureRegion.memory, 32698697ee19Smrg psav->ApertureRegion.size); 32708697ee19Smrg#else 32718697ee19Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->ApertureRegion.base, 32728697ee19Smrg psav->ApertureRegion.size); 32738697ee19Smrg#endif 3274ab47cfaaSmrg } 32758697ee19Smrg 32768697ee19Smrg psav->FbRegion.memory = NULL; 32778697ee19Smrg psav->ApertureRegion.memory = NULL; 3278ab47cfaaSmrg psav->FBBase = 0; 3279ab47cfaaSmrg psav->FBStart = 0; 3280ab47cfaaSmrg psav->ApertureMap = 0; 3281ab47cfaaSmrg 3282ab47cfaaSmrg return; 3283ab47cfaaSmrg} 3284ab47cfaaSmrg 3285ab47cfaaSmrg#ifdef XF86DRI 3286ab47cfaaSmrgstatic Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn) 3287ab47cfaaSmrg{ 3288ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 3289ab47cfaaSmrg int cpp = pScrn->bitsPerPixel / 8; 3290ab47cfaaSmrg int tiledBufferSize, RamNeededFor3D; 3291ab47cfaaSmrg 3292ab47cfaaSmrg if (cpp == 2) { 3293ab47cfaaSmrg tiledBufferSize = ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16) * 2048; 3294ab47cfaaSmrg } else { 3295ab47cfaaSmrg tiledBufferSize = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16) * 2048; 3296ab47cfaaSmrg } 3297ab47cfaaSmrg 3298ab47cfaaSmrg RamNeededFor3D = 4096 + /* hw cursor*/ 3299ab47cfaaSmrg psav->cobSize + /*COB*/ 3300ab47cfaaSmrg tiledBufferSize + /* front buffer */ 3301ab47cfaaSmrg tiledBufferSize + /* back buffer */ 3302ab47cfaaSmrg tiledBufferSize; /* depth buffer */ 3303ab47cfaaSmrg 3304ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO, 3305ab47cfaaSmrg "%d kB of Videoram needed for 3D; %d kB of Videoram available\n", 3306ab47cfaaSmrg RamNeededFor3D/1024, psav->videoRambytes/1024); 3307ab47cfaaSmrg 3308ab47cfaaSmrg if (RamNeededFor3D <= psav->videoRambytes) { 3309ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Sufficient Videoram available for 3D\n"); 3310ab47cfaaSmrg return TRUE; 3311ab47cfaaSmrg } else { 3312ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Insufficient Videoram available for 3D -- " 3313ab47cfaaSmrg "Try a lower color depth or smaller desktop. " 3314ab47cfaaSmrg "For integrated savages try increasing the videoram in the BIOS.\n"); 3315ab47cfaaSmrg return FALSE; 3316ab47cfaaSmrg } 3317ab47cfaaSmrg} 3318ab47cfaaSmrg#endif 3319ab47cfaaSmrg 3320ab47cfaaSmrgstatic void SavageInitStatus(ScrnInfoPtr pScrn) 3321ab47cfaaSmrg{ 3322ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 3323ab47cfaaSmrg 3324ab47cfaaSmrg switch( psav->Chipset ) { 3325ab47cfaaSmrg case S3_SAVAGE3D: 3326ab47cfaaSmrg case S3_SAVAGE_MX: 3327ab47cfaaSmrg psav->WaitQueue = WaitQueue3D; 3328ab47cfaaSmrg psav->WaitIdle = WaitIdle3D; 3329ab47cfaaSmrg psav->WaitIdleEmpty = WaitIdleEmpty3D; 3330ab47cfaaSmrg psav->bciUsedMask = 0x1ffff; 3331ab47cfaaSmrg psav->eventStatusReg= 1; 3332ab47cfaaSmrg break; 3333ab47cfaaSmrg 3334ab47cfaaSmrg case S3_SAVAGE4: 3335ab47cfaaSmrg case S3_PROSAVAGE: 3336ab47cfaaSmrg case S3_SUPERSAVAGE: 3337ab47cfaaSmrg case S3_PROSAVAGEDDR: 3338ab47cfaaSmrg case S3_TWISTER: 3339ab47cfaaSmrg psav->WaitQueue = WaitQueue4; 3340ab47cfaaSmrg psav->WaitIdle = WaitIdle4; 3341ab47cfaaSmrg psav->WaitIdleEmpty = WaitIdleEmpty4; 3342ab47cfaaSmrg psav->bciUsedMask = 0x1fffff; 3343ab47cfaaSmrg psav->eventStatusReg= 1; 3344ab47cfaaSmrg break; 3345ab47cfaaSmrg 3346ab47cfaaSmrg case S3_SAVAGE2000: 3347ab47cfaaSmrg psav->WaitQueue = WaitQueue2K; 3348ab47cfaaSmrg psav->WaitIdle = WaitIdle2K; 3349ab47cfaaSmrg psav->WaitIdleEmpty = WaitIdleEmpty2K; 3350ab47cfaaSmrg psav->bciUsedMask = 0xfffff; 3351ab47cfaaSmrg psav->eventStatusReg= 2; 3352ab47cfaaSmrg break; 3353ab47cfaaSmrg } 3354ab47cfaaSmrg} 3355ab47cfaaSmrg 3356ab47cfaaSmrgstatic void SavageInitShadowStatus(ScrnInfoPtr pScrn) 3357ab47cfaaSmrg{ 3358ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 3359ab47cfaaSmrg 3360ab47cfaaSmrg psav->ShadowStatus = psav->ConfigShadowStatus; 3361ab47cfaaSmrg 3362ab47cfaaSmrg SavageInitStatus(pScrn); 3363ab47cfaaSmrg 3364ab47cfaaSmrg if( psav->ShadowStatus ) { 3365ab47cfaaSmrg psav->ShadowPhysical = 33668697ee19Smrg psav->FbRegion.base + psav->CursorKByte*1024 + 4096 - 32; 3367ab47cfaaSmrg 3368ab47cfaaSmrg psav->ShadowVirtual = (CARD32 *) 3369ab47cfaaSmrg (psav->FBBase + psav->CursorKByte*1024 + 4096 - 32); 3370ab47cfaaSmrg 3371ab47cfaaSmrg xf86DrvMsg( pScrn->scrnIndex, X_PROBED, 3372ab47cfaaSmrg "Shadow area physical %08lx, linear %p\n", 3373ab47cfaaSmrg psav->ShadowPhysical, (void *)psav->ShadowVirtual ); 3374ab47cfaaSmrg 3375ab47cfaaSmrg psav->WaitQueue = ShadowWaitQueue; 3376ab47cfaaSmrg psav->WaitIdle = ShadowWait; 3377ab47cfaaSmrg psav->WaitIdleEmpty = ShadowWait; 3378ab47cfaaSmrg } 3379ab47cfaaSmrg 3380ab47cfaaSmrg if( psav->Chipset == S3_SAVAGE2000 ) 3381ab47cfaaSmrg psav->dwBCIWait2DIdle = 0xc0040000; 3382ab47cfaaSmrg else 3383ab47cfaaSmrg psav->dwBCIWait2DIdle = 0xc0020000; 3384ab47cfaaSmrg} 3385ab47cfaaSmrg 3386ab47cfaaSmrgstatic Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, 3387ab47cfaaSmrg int argc, char **argv) 3388ab47cfaaSmrg{ 3389ab47cfaaSmrg ScrnInfoPtr pScrn; 3390ab47cfaaSmrg SavagePtr psav; 3391ab47cfaaSmrg EntityInfoPtr pEnt; 3392ab47cfaaSmrg int ret; 3393ab47cfaaSmrg int colormapFlags; 3394ab47cfaaSmrg 3395ab47cfaaSmrg TRACE(("SavageScreenInit()\n")); 3396ab47cfaaSmrg 3397ab47cfaaSmrg pScrn = xf86Screens[pScreen->myNum]; 3398ab47cfaaSmrg psav = SAVPTR(pScrn); 3399ab47cfaaSmrg 3400ab47cfaaSmrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 3401ab47cfaaSmrg if (!psav->pVbe) 3402ab47cfaaSmrg psav->pVbe = VBEInit(NULL, pEnt->index); 3403ab47cfaaSmrg 3404ab47cfaaSmrg SavageEnableMMIO(pScrn); 3405ab47cfaaSmrg 3406ab47cfaaSmrg if (!SavageMapMem(pScrn)) 3407ab47cfaaSmrg return FALSE; 3408ab47cfaaSmrg 3409ab47cfaaSmrg psav->FBStart2nd = 0; 3410ab47cfaaSmrg 3411ab47cfaaSmrg if (psav->overlayDepth) { 3412ab47cfaaSmrg if ((pScrn->virtualX * pScrn->virtualY * 3413ab47cfaaSmrg (DEPTH_BPP(DEPTH_2ND(pScrn))) >> 3) 3414ab47cfaaSmrg > (psav->CursorKByte * 1024)) 3415ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_WARNING, 3416ab47cfaaSmrg "Not enough memory for overlay mode: disabling\n"); 3417ab47cfaaSmrg else psav->FBStart2nd = psav->FBStart 3418ab47cfaaSmrg + ((pScrn->virtualX * pScrn->virtualY + 0xff) & ~0xff); 3419ab47cfaaSmrg 3420ab47cfaaSmrg } 3421ab47cfaaSmrg 3422ab47cfaaSmrg SavageInitShadowStatus(pScrn); 3423ab47cfaaSmrg psav->ShadowCounter = 0; 3424ab47cfaaSmrg 3425ab47cfaaSmrg SavageSave(pScrn); 3426ab47cfaaSmrg 3427ab47cfaaSmrg vgaHWBlankScreen(pScrn, TRUE); 3428ab47cfaaSmrg 3429ab47cfaaSmrg#ifdef XF86DRI 3430ab47cfaaSmrg if (!xf86ReturnOptValBool(psav->Options, OPTION_DRI, TRUE)) { 3431ab47cfaaSmrg psav->directRenderingEnabled = FALSE; 3432ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3433ab47cfaaSmrg "Direct rendering forced off\n"); 3434ab47cfaaSmrg } else if (psav->IsSecondary) { 3435ab47cfaaSmrg psav->directRenderingEnabled = FALSE; 3436ab47cfaaSmrg } else if (xf86IsEntityShared(psav->pEnt->index)) { 3437ab47cfaaSmrg /* Xinerama has sync problem with DRI, disable it for now */ 3438ab47cfaaSmrg psav->directRenderingEnabled = FALSE; 3439ab47cfaaSmrg xf86DrvMsg(scrnIndex, X_WARNING, 3440ab47cfaaSmrg "Direct Rendering Disabled -- " 3441ab47cfaaSmrg "Dual-head configuration is not working with " 3442ab47cfaaSmrg "DRI at present.\n"); 3443ab47cfaaSmrg } else if (/*!psav->bTiled*/psav->bDisableTile) { 3444ab47cfaaSmrg xf86DrvMsg(scrnIndex, X_WARNING, 3445ab47cfaaSmrg "Direct Rendering requires a tiled framebuffer -- " 3446ab47cfaaSmrg "Set Option \"DisableTile\" \"false\"\n"); 3447ab47cfaaSmrg } else if (psav->cobSize == 0) { 3448ab47cfaaSmrg xf86DrvMsg(scrnIndex, X_WARNING, 3449ab47cfaaSmrg "Direct Rendering requires the COB -- " 3450ab47cfaaSmrg "Set Option \"DisableCOB\" \"false\"\n"); 3451ab47cfaaSmrg } else if (((psav->Chipset == S3_TWISTER) 3452ab47cfaaSmrg || (psav->Chipset == S3_PROSAVAGE) 3453ab47cfaaSmrg || (psav->Chipset == S3_SAVAGE4) 3454ab47cfaaSmrg || (psav->Chipset == S3_SAVAGE_MX) 3455ab47cfaaSmrg || (psav->Chipset == S3_SAVAGE3D) 3456ab47cfaaSmrg || (psav->Chipset == S3_SUPERSAVAGE) 3457ab47cfaaSmrg || (psav->Chipset == S3_PROSAVAGEDDR)) 3458ab47cfaaSmrg && (!psav->NoAccel) 3459ab47cfaaSmrg && (SavageCheckAvailableRamFor3D(pScrn))) { 3460ab47cfaaSmrg /* Setup DRI after visuals have been established */ 3461ab47cfaaSmrg psav->directRenderingEnabled = SAVAGEDRIScreenInit(pScreen); 3462ab47cfaaSmrg /* If DRI init failed, reset shadow status. */ 3463ab47cfaaSmrg if (!psav->directRenderingEnabled && 3464ab47cfaaSmrg psav->ShadowStatus != psav->ConfigShadowStatus) { 3465ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Resetting ShadowStatus.\n"); 3466ab47cfaaSmrg SavageInitShadowStatus(pScrn); 3467ab47cfaaSmrg } 3468ab47cfaaSmrg /* If shadow status was enabled for DRI, hook up the shadow 3469ab47cfaaSmrg * waiting functions now. */ 3470ab47cfaaSmrg else if (psav->ShadowStatus && !psav->ConfigShadowStatus) { 3471ab47cfaaSmrg psav->WaitQueue = ShadowWaitQueue; 3472ab47cfaaSmrg psav->WaitIdle = ShadowWait; 3473ab47cfaaSmrg psav->WaitIdleEmpty = ShadowWait; 3474ab47cfaaSmrg } 3475ab47cfaaSmrg } else 3476ab47cfaaSmrg psav->directRenderingEnabled = FALSE; 3477ab47cfaaSmrg 3478ab47cfaaSmrg if(psav->directRenderingEnabled) { 3479ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"DRI is enabled\n"); 3480ab47cfaaSmrg } 3481ab47cfaaSmrg else { 3482ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"DRI isn't enabled\n"); 3483ab47cfaaSmrg } 3484ab47cfaaSmrg#endif 3485ab47cfaaSmrg 3486ab47cfaaSmrg if (!SavageModeInit(pScrn, pScrn->currentMode)) 3487ab47cfaaSmrg return FALSE; 3488ab47cfaaSmrg 3489ab47cfaaSmrg miClearVisualTypes(); 3490ab47cfaaSmrg 3491ab47cfaaSmrg { 3492ab47cfaaSmrg int visual; 3493ab47cfaaSmrg 3494ab47cfaaSmrg visual = ((psav->FBStart2nd && pScrn->bitsPerPixel > 8) 3495ab47cfaaSmrg || pScrn->bitsPerPixel == 16) ? TrueColorMask 3496ab47cfaaSmrg : miGetDefaultVisualMask(DEPTH_BPP(pScrn->depth)); 3497ab47cfaaSmrg if (!miSetVisualTypes(pScrn->depth, visual, 3498ab47cfaaSmrg pScrn->rgbBits, pScrn->defaultVisual)) 3499ab47cfaaSmrg return FALSE; 3500ab47cfaaSmrg 3501ab47cfaaSmrg if (psav->FBStart2nd) {/* we have overlay */ 3502ab47cfaaSmrg visual = psav->overlayDepth > 8 ? TrueColorMask : 3503ab47cfaaSmrg miGetDefaultVisualMask(DEPTH_BPP(psav->overlayDepth)); 3504ab47cfaaSmrg if (!miSetVisualTypes(psav->overlayDepth, visual, 3505ab47cfaaSmrg psav->overlayDepth > 8 ? 8 : 6, 3506ab47cfaaSmrg pScrn->defaultVisual)) 3507ab47cfaaSmrg return FALSE; 3508ab47cfaaSmrg } 3509ab47cfaaSmrg } 3510ab47cfaaSmrg if (!miSetPixmapDepths ()) 3511ab47cfaaSmrg return FALSE; 3512ab47cfaaSmrg 3513ab47cfaaSmrg ret = SavageInternalScreenInit(scrnIndex, pScreen); 3514ab47cfaaSmrg if (!ret) 3515ab47cfaaSmrg return FALSE; 3516ab47cfaaSmrg 3517ab47cfaaSmrg xf86SetBlackWhitePixels(pScreen); 3518ab47cfaaSmrg 3519ab47cfaaSmrg { 3520ab47cfaaSmrg VisualPtr visual; 3521ab47cfaaSmrg visual = pScreen->visuals + pScreen->numVisuals; 3522ab47cfaaSmrg while (--visual >= pScreen->visuals) { 3523ab47cfaaSmrg if ((visual->class | DynamicClass) == DirectColor 3524ab47cfaaSmrg && visual->nplanes > MAX_PSEUDO_DEPTH) { 3525ab47cfaaSmrg if (visual->nplanes == pScrn->depth) { 3526ab47cfaaSmrg visual->offsetRed = pScrn->offset.red; 3527ab47cfaaSmrg visual->offsetGreen = pScrn->offset.green; 3528ab47cfaaSmrg visual->offsetBlue = pScrn->offset.blue; 3529ab47cfaaSmrg visual->redMask = pScrn->mask.red; 3530ab47cfaaSmrg visual->greenMask = pScrn->mask.green; 3531ab47cfaaSmrg visual->blueMask = pScrn->mask.blue; 3532ab47cfaaSmrg } else if (visual->offsetRed > 8 3533ab47cfaaSmrg || visual->offsetGreen > 8 3534ab47cfaaSmrg || visual->offsetBlue > 8) { 3535ab47cfaaSmrg /* 3536ab47cfaaSmrg * mi has set these wrong. fix it here -- we cannot use pScrn 3537ab47cfaaSmrg * as this is set up for the default depth 8. 3538ab47cfaaSmrg */ 3539ab47cfaaSmrg int tmp; 3540ab47cfaaSmrg int c_s = 0; 3541ab47cfaaSmrg 3542ab47cfaaSmrg tmp = visual->offsetBlue; 3543ab47cfaaSmrg visual->offsetBlue = visual->offsetRed; 3544ab47cfaaSmrg visual->offsetRed = tmp; 3545ab47cfaaSmrg tmp = visual->blueMask; 3546ab47cfaaSmrg visual->blueMask = visual->redMask; 3547ab47cfaaSmrg visual->redMask = tmp; 3548ab47cfaaSmrg switch (DEPTH_2ND(pScrn)) { 3549ab47cfaaSmrg case 16: 3550ab47cfaaSmrg visual->offsetRed = 11; 3551ab47cfaaSmrg visual->offsetGreen = 5; 3552ab47cfaaSmrg visual->offsetBlue = 0; 3553ab47cfaaSmrg visual->redMask = 0xF800; 3554ab47cfaaSmrg visual->greenMask = 0x7E0; 3555ab47cfaaSmrg visual->blueMask = 0x1F; 3556ab47cfaaSmrg break; 3557ab47cfaaSmrg case 24: 3558ab47cfaaSmrg visual->offsetRed = 16; 3559ab47cfaaSmrg visual->offsetGreen = 8; 3560ab47cfaaSmrg visual->offsetBlue = 0; 3561ab47cfaaSmrg visual->redMask = 0xFF0000; 3562ab47cfaaSmrg visual->greenMask = 0xFF00; 3563ab47cfaaSmrg visual->blueMask = 0xFF; 3564ab47cfaaSmrg c_s = 2; 3565ab47cfaaSmrg break; 3566ab47cfaaSmrg } 3567ab47cfaaSmrg psav->overlay.redMask = visual->redMask; 3568ab47cfaaSmrg psav->overlay.greenMask = visual->greenMask; 3569ab47cfaaSmrg psav->overlay.blueMask = visual->blueMask; 3570ab47cfaaSmrg psav->overlay.redShift = visual->offsetRed + c_s; 3571ab47cfaaSmrg psav->overlay.greenShift = visual->offsetGreen + c_s; 3572ab47cfaaSmrg psav->overlay.blueShift = visual->offsetBlue + c_s; 3573ab47cfaaSmrg } 3574ab47cfaaSmrg } 3575ab47cfaaSmrg } 3576ab47cfaaSmrg } 3577ab47cfaaSmrg 3578ab47cfaaSmrg /* must be after RGB ordering fixed */ 3579ab47cfaaSmrg fbPictureInit (pScreen, 0, 0); 3580ab47cfaaSmrg 3581ab47cfaaSmrg if( !psav->NoAccel ) { 3582ab47cfaaSmrg SavageInitAccel(pScreen); 3583ab47cfaaSmrg } 3584ab47cfaaSmrg 3585ab47cfaaSmrg miInitializeBackingStore(pScreen); 3586ab47cfaaSmrg xf86SetBackingStore(pScreen); 3587ab47cfaaSmrg 3588ab47cfaaSmrg if( !psav->shadowFB && !psav->useEXA ) 3589ab47cfaaSmrg SavageDGAInit(pScreen); 3590ab47cfaaSmrg 3591ab47cfaaSmrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 3592ab47cfaaSmrg 3593ab47cfaaSmrg if (psav->hwcursor) 3594ab47cfaaSmrg if (!SavageHWCursorInit(pScreen)) 3595ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3596ab47cfaaSmrg "Hardware cursor initialization failed\n"); 3597ab47cfaaSmrg 3598ab47cfaaSmrg if (psav->shadowFB) { 3599ab47cfaaSmrg RefreshAreaFuncPtr refreshArea = SavageRefreshArea; 3600ab47cfaaSmrg 3601ab47cfaaSmrg if(psav->rotate) { 3602ab47cfaaSmrg if (!psav->PointerMoved) { 3603ab47cfaaSmrg psav->PointerMoved = pScrn->PointerMoved; 3604ab47cfaaSmrg pScrn->PointerMoved = SavagePointerMoved; 3605ab47cfaaSmrg } 3606ab47cfaaSmrg 3607ab47cfaaSmrg switch(pScrn->bitsPerPixel) { 3608ab47cfaaSmrg case 8: refreshArea = SavageRefreshArea8; break; 3609ab47cfaaSmrg case 16: refreshArea = SavageRefreshArea16; break; 3610ab47cfaaSmrg case 24: refreshArea = SavageRefreshArea24; break; 3611ab47cfaaSmrg case 32: refreshArea = SavageRefreshArea32; break; 3612ab47cfaaSmrg } 3613ab47cfaaSmrg } 3614ab47cfaaSmrg 3615ab47cfaaSmrg ShadowFBInit(pScreen, refreshArea); 3616ab47cfaaSmrg } 3617ab47cfaaSmrg 3618ab47cfaaSmrg if (!miCreateDefColormap(pScreen)) 3619ab47cfaaSmrg return FALSE; 3620ab47cfaaSmrg 3621ab47cfaaSmrg colormapFlags = CMAP_RELOAD_ON_MODE_SWITCH 3622ab47cfaaSmrg | ((psav->FBStart2nd) ? 0 : CMAP_PALETTED_TRUECOLOR); 3623ab47cfaaSmrg 3624ab47cfaaSmrg if (psav->Chipset == S3_SAVAGE4) { 3625ab47cfaaSmrg if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, SavageLoadPaletteSavage4, 3626ab47cfaaSmrg NULL, colormapFlags )) 3627ab47cfaaSmrg return FALSE; 3628ab47cfaaSmrg } else { 3629ab47cfaaSmrg if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, SavageLoadPalette, NULL, 3630ab47cfaaSmrg colormapFlags )) 3631ab47cfaaSmrg return FALSE; 3632ab47cfaaSmrg } 3633ab47cfaaSmrg 3634ab47cfaaSmrg vgaHWBlankScreen(pScrn, FALSE); 3635ab47cfaaSmrg 3636ab47cfaaSmrg psav->CloseScreen = pScreen->CloseScreen; 3637ab47cfaaSmrg pScreen->SaveScreen = SavageSaveScreen; 3638ab47cfaaSmrg pScreen->CloseScreen = SavageCloseScreen; 3639ab47cfaaSmrg 3640ab47cfaaSmrg if (xf86DPMSInit(pScreen, SavageDPMS, 0) == FALSE) 3641ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed\n"); 3642ab47cfaaSmrg 3643ab47cfaaSmrg#ifdef XF86DRI 3644ab47cfaaSmrg if (psav->directRenderingEnabled) { 3645ab47cfaaSmrg /* complete the DRI setup.*/ 3646ab47cfaaSmrg psav->directRenderingEnabled = SAVAGEDRIFinishScreenInit(pScreen); 3647ab47cfaaSmrg /* If DRI initialization failed, reset shadow status and 3648ab47cfaaSmrg * reinitialize 2D engine. */ 3649ab47cfaaSmrg if (!psav->directRenderingEnabled && 3650ab47cfaaSmrg psav->ShadowStatus != psav->ConfigShadowStatus) { 3651ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Resetting ShadowStatus.\n"); 3652ab47cfaaSmrg SavageInitShadowStatus(pScrn); 3653ab47cfaaSmrg SavageInitialize2DEngine(pScrn); 3654ab47cfaaSmrg } 3655ab47cfaaSmrg } 3656ab47cfaaSmrg if (psav->directRenderingEnabled) { 3657ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 3658ab47cfaaSmrg } else { 3659ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n"); 3660ab47cfaaSmrg } 3661ab47cfaaSmrg#endif 3662ab47cfaaSmrg 36638697ee19Smrg SavagePanningCheck(pScrn, pScrn->currentMode); 3664ab47cfaaSmrg#ifdef XvExtension 3665ab47cfaaSmrg if( !psav->FBStart2nd && !psav->NoAccel /*&& !SavagePanningCheck(pScrn)*/ ) { 3666ab47cfaaSmrg if (psav->IsSecondary) 3667ab47cfaaSmrg /* Xv should work on crtc2, but I haven't gotten there yet. -- AGD */ 3668ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv currently disabled for crtc2.\n"); 3669ab47cfaaSmrg else 3670ab47cfaaSmrg SavageInitVideo( pScreen ); 3671ab47cfaaSmrg } 3672ab47cfaaSmrg#endif 3673ab47cfaaSmrg 3674ab47cfaaSmrg#ifdef XF86DRI 3675ab47cfaaSmrg if ((psav->directRenderingEnabled) && (!psav->bDisableXvMC)) { 3676ab47cfaaSmrg if (SAVAGEInitMC(pScreen)) 3677ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"XvMC is enabled\n"); 3678ab47cfaaSmrg else 3679ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"XvMC is not enabled\n"); 3680ab47cfaaSmrg } 3681ab47cfaaSmrg#endif 3682ab47cfaaSmrg 3683ab47cfaaSmrg if (serverGeneration == 1) 3684ab47cfaaSmrg xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 3685ab47cfaaSmrg 3686ab47cfaaSmrg return TRUE; 3687ab47cfaaSmrg} 3688ab47cfaaSmrg 3689ab47cfaaSmrg 3690ab47cfaaSmrgstatic int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen) 3691ab47cfaaSmrg{ 3692ab47cfaaSmrg int ret = TRUE; 3693ab47cfaaSmrg ScrnInfoPtr pScrn; 3694ab47cfaaSmrg SavagePtr psav; 3695ab47cfaaSmrg int width, height, displayWidth; 3696ab47cfaaSmrg unsigned char *FBStart; 3697ab47cfaaSmrg 3698ab47cfaaSmrg TRACE(("SavageInternalScreenInit()\n")); 3699ab47cfaaSmrg 3700ab47cfaaSmrg pScrn = xf86Screens[pScreen->myNum]; 3701ab47cfaaSmrg psav = SAVPTR(pScrn); 3702ab47cfaaSmrg 3703ab47cfaaSmrg displayWidth = pScrn->displayWidth; 3704ab47cfaaSmrg 3705ab47cfaaSmrg if (psav->rotate) { 3706ab47cfaaSmrg height = pScrn->virtualX; 3707ab47cfaaSmrg width = pScrn->virtualY; 3708ab47cfaaSmrg } else { 3709ab47cfaaSmrg width = pScrn->virtualX; 3710ab47cfaaSmrg height = pScrn->virtualY; 3711ab47cfaaSmrg } 3712ab47cfaaSmrg 3713ab47cfaaSmrg 3714ab47cfaaSmrg if(psav->shadowFB) { 3715ab47cfaaSmrg psav->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 3716ab47cfaaSmrg psav->ShadowPtr = xalloc(psav->ShadowPitch * height); 3717ab47cfaaSmrg displayWidth = psav->ShadowPitch / (pScrn->bitsPerPixel >> 3); 3718ab47cfaaSmrg FBStart = psav->ShadowPtr; 3719ab47cfaaSmrg } else { 3720ab47cfaaSmrg psav->ShadowPtr = NULL; 3721ab47cfaaSmrg FBStart = psav->FBStart; 3722ab47cfaaSmrg } 3723ab47cfaaSmrg 3724ab47cfaaSmrg if (!psav->FBStart2nd) { 3725ab47cfaaSmrg 3726ab47cfaaSmrg ret = fbScreenInit(pScreen, FBStart, width, height, 3727ab47cfaaSmrg pScrn->xDpi, pScrn->yDpi, 3728ab47cfaaSmrg psav->ulAperturePitch / (pScrn->bitsPerPixel >> 3), /*displayWidth,*/ 3729ab47cfaaSmrg pScrn->bitsPerPixel); 3730ab47cfaaSmrg 3731ab47cfaaSmrg } else { 3732ab47cfaaSmrg FbOverlayScrPrivPtr pScrPriv; 3733ab47cfaaSmrg int Depth2nd = DEPTH_2ND(pScrn); 3734ab47cfaaSmrg if (!fbSetupScreen (pScreen, FBStart, width, height, 3735ab47cfaaSmrg pScrn->xDpi, pScrn->yDpi, displayWidth, 8)) 3736ab47cfaaSmrg return FALSE; 3737ab47cfaaSmrg if (pScrn->depth == 8) { 3738ab47cfaaSmrg ret = fbOverlayFinishScreenInit (pScreen, FBStart, 3739ab47cfaaSmrg psav->FBStart2nd, width, 3740ab47cfaaSmrg height,pScrn->xDpi, pScrn->yDpi, 3741ab47cfaaSmrg displayWidth,displayWidth, 3742ab47cfaaSmrg 8, DEPTH_BPP(Depth2nd), 3743ab47cfaaSmrg 8, Depth2nd); 3744ab47cfaaSmrg pScrPriv = fbOverlayGetScrPriv(pScreen); 3745ab47cfaaSmrg pScrPriv->layer[0].key = pScrn->colorKey; 3746ab47cfaaSmrg } else { 3747ab47cfaaSmrg ret = fbOverlayFinishScreenInit (pScreen, psav->FBStart2nd, 3748ab47cfaaSmrg FBStart, 3749ab47cfaaSmrg width, height,pScrn->xDpi, 3750ab47cfaaSmrg pScrn->yDpi, 3751ab47cfaaSmrg displayWidth,displayWidth, 3752ab47cfaaSmrg DEPTH_BPP(Depth2nd), 8, 3753ab47cfaaSmrg Depth2nd, 8); 3754ab47cfaaSmrg pScrPriv = fbOverlayGetScrPriv(pScreen); 3755ab47cfaaSmrg pScrPriv->layer[1].key = pScrn->colorKey; 3756ab47cfaaSmrg } 3757ab47cfaaSmrg } 3758ab47cfaaSmrg return ret; 3759ab47cfaaSmrg} 3760ab47cfaaSmrg 3761ab47cfaaSmrg 3762ab47cfaaSmrgstatic int SavageGetRefresh(DisplayModePtr mode) 3763ab47cfaaSmrg{ 3764ab47cfaaSmrg int refresh = (mode->Clock * 1000) / (mode->HTotal * mode->VTotal); 3765ab47cfaaSmrg if (mode->Flags & V_INTERLACE) 3766ab47cfaaSmrg refresh *= 2.0; 3767ab47cfaaSmrg if (mode->Flags & V_DBLSCAN) 3768ab47cfaaSmrg refresh /= 2.0; 3769ab47cfaaSmrg if (mode->VScan > 1) 3770ab47cfaaSmrg refresh /= mode->VScan; 3771ab47cfaaSmrg return refresh; 3772ab47cfaaSmrg} 3773ab47cfaaSmrg 3774ab47cfaaSmrg 3775ab47cfaaSmrgstatic ModeStatus SavageValidMode(int index, DisplayModePtr pMode, 3776ab47cfaaSmrg Bool verbose, int flags) 3777ab47cfaaSmrg{ 3778ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[index]; 3779ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 3780ab47cfaaSmrg int refresh; 3781ab47cfaaSmrg 3782ab47cfaaSmrg TRACE(("SavageValidMode\n")); 3783ab47cfaaSmrg 3784ab47cfaaSmrg /* We prohibit modes bigger than the LCD panel. */ 3785ab47cfaaSmrg /* TODO We should do this only if the panel is active. */ 3786ab47cfaaSmrg 3787ab47cfaaSmrg if( psav->TvOn ) 3788ab47cfaaSmrg { 3789ab47cfaaSmrg if( pMode->HDisplay > psav->TVSizeX ) 3790ab47cfaaSmrg return MODE_VIRTUAL_X; 3791ab47cfaaSmrg 3792ab47cfaaSmrg if( pMode->VDisplay > psav->TVSizeY ) 3793ab47cfaaSmrg return MODE_VIRTUAL_Y; 3794ab47cfaaSmrg 3795ab47cfaaSmrg } 3796ab47cfaaSmrg 3797ab47cfaaSmrg if((psav->DisplayType == MT_LCD) && 3798ab47cfaaSmrg ((pMode->HDisplay > psav->PanelX) || 3799ab47cfaaSmrg (pMode->VDisplay > psav->PanelY))) 3800ab47cfaaSmrg return MODE_PANEL; 3801ab47cfaaSmrg 3802ab47cfaaSmrg if (psav->UseBIOS) { 3803ab47cfaaSmrg refresh = SavageGetRefresh(pMode); 3804ab47cfaaSmrg return (SavageMatchBiosMode(pScrn,pMode->HDisplay, 3805ab47cfaaSmrg pMode->VDisplay, 3806ab47cfaaSmrg refresh,NULL,NULL)); 3807ab47cfaaSmrg } 3808ab47cfaaSmrg 3809ab47cfaaSmrg return MODE_OK; 3810ab47cfaaSmrg} 3811ab47cfaaSmrg 3812ab47cfaaSmrgstatic Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 3813ab47cfaaSmrg{ 3814ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 3815ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 3816ab47cfaaSmrg int width, dclk, i, j; /*, refresh; */ 3817ab47cfaaSmrg unsigned int m, n, r; 3818ab47cfaaSmrg unsigned char tmp = 0; 3819ab47cfaaSmrg SavageRegPtr new = &psav->ModeReg; 3820ab47cfaaSmrg vgaRegPtr vganew = &hwp->ModeReg; 3821ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 3822ab47cfaaSmrg int refresh; 3823ab47cfaaSmrg unsigned int newmode=0, newrefresh=0; 3824ab47cfaaSmrg 3825ab47cfaaSmrg vgaIOBase = hwp->IOBase; 3826ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 3827ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 3828ab47cfaaSmrg 3829ab47cfaaSmrg TRACE(("SavageModeInit(%dx%d, %dHz)\n", 3830ab47cfaaSmrg mode->HDisplay, mode->VDisplay, mode->Clock)); 3831ab47cfaaSmrg 3832ab47cfaaSmrg#if 0 3833ab47cfaaSmrg ErrorF("Clock = %d, HDisplay = %d, HSStart = %d\n", 3834ab47cfaaSmrg mode->Clock, mode->HDisplay, mode->HSyncStart); 3835ab47cfaaSmrg ErrorF("HSEnd = %d, HSkew = %d\n", 3836ab47cfaaSmrg mode->HSyncEnd, mode->HSkew); 3837ab47cfaaSmrg ErrorF("VDisplay - %d, VSStart = %d, VSEnd = %d\n", 3838ab47cfaaSmrg mode->VDisplay, mode->VSyncStart, mode->VSyncEnd); 3839ab47cfaaSmrg ErrorF("VTotal = %d\n", 3840ab47cfaaSmrg mode->VTotal); 3841ab47cfaaSmrg ErrorF("HDisplay = %d, HSStart = %d\n", 3842ab47cfaaSmrg mode->CrtcHDisplay, mode->CrtcHSyncStart); 3843ab47cfaaSmrg ErrorF("HSEnd = %d, HSkey = %d\n", 3844ab47cfaaSmrg mode->CrtcHSyncEnd, mode->CrtcHSkew); 3845ab47cfaaSmrg ErrorF("VDisplay - %d, VSStart = %d, VSEnd = %d\n", 3846ab47cfaaSmrg mode->CrtcVDisplay, mode->CrtcVSyncStart, mode->CrtcVSyncEnd); 3847ab47cfaaSmrg ErrorF("VTotal = %d\n", 3848ab47cfaaSmrg mode->CrtcVTotal); 3849ab47cfaaSmrg#endif 3850ab47cfaaSmrg 3851ab47cfaaSmrg if (psav->IsSecondary) { 3852ab47cfaaSmrg refresh = SavageGetRefresh(mode); 3853ab47cfaaSmrg 3854ab47cfaaSmrg SavageMatchBiosMode(pScrn,mode->HDisplay,mode->VDisplay,refresh, 3855ab47cfaaSmrg &newmode,&newrefresh); 3856ab47cfaaSmrg new->mode = newmode; 3857ab47cfaaSmrg new->refresh = newrefresh; 3858ab47cfaaSmrg 3859ab47cfaaSmrg /* do it! */ 3860ab47cfaaSmrg SavageWriteMode(pScrn, vganew, new, TRUE); 3861ab47cfaaSmrg 3862ab47cfaaSmrg if (psav->FBStart2nd) { 3863ab47cfaaSmrg SavageStreamsOn(pScrn); 3864ab47cfaaSmrg SavageInitSecondaryStream(pScrn); 3865ab47cfaaSmrg } 3866ab47cfaaSmrg 3867ab47cfaaSmrg SavageAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 3868ab47cfaaSmrg return TRUE; 3869ab47cfaaSmrg } 3870ab47cfaaSmrg 3871ab47cfaaSmrg 3872ab47cfaaSmrg if (pScrn->bitsPerPixel == 8) 3873ab47cfaaSmrg psav->HorizScaleFactor = 1; 3874ab47cfaaSmrg else if (pScrn->bitsPerPixel == 16) 3875ab47cfaaSmrg psav->HorizScaleFactor = 1; /* I don't think we ever want 2 */ 3876ab47cfaaSmrg else 3877ab47cfaaSmrg psav->HorizScaleFactor = 1; 3878ab47cfaaSmrg 3879ab47cfaaSmrg if (psav->HorizScaleFactor == 2) 3880ab47cfaaSmrg if (!mode->CrtcHAdjusted) { 3881ab47cfaaSmrg mode->CrtcHDisplay *= 2; 3882ab47cfaaSmrg mode->CrtcHSyncStart *= 2; 3883ab47cfaaSmrg mode->CrtcHSyncEnd *= 2; 3884ab47cfaaSmrg mode->CrtcHBlankStart *= 2; 3885ab47cfaaSmrg mode->CrtcHBlankEnd *= 2; 3886ab47cfaaSmrg mode->CrtcHTotal *= 2; 3887ab47cfaaSmrg mode->CrtcHSkew *= 2; 3888ab47cfaaSmrg mode->CrtcHAdjusted = TRUE; 3889ab47cfaaSmrg } 3890ab47cfaaSmrg 3891ab47cfaaSmrg if (!vgaHWInit(pScrn, mode)) 3892ab47cfaaSmrg return FALSE; 3893ab47cfaaSmrg 3894ab47cfaaSmrg new->mode = 0; 3895ab47cfaaSmrg 3896ab47cfaaSmrg /* We need to set CR67 whether or not we use the BIOS. */ 3897ab47cfaaSmrg 3898ab47cfaaSmrg dclk = mode->Clock; 3899ab47cfaaSmrg new->CR67 = 0x00; 3900ab47cfaaSmrg 3901ab47cfaaSmrg switch( pScrn->depth ) { 3902ab47cfaaSmrg case 8: 3903ab47cfaaSmrg if( (psav->Chipset == S3_SAVAGE2000) && (dclk >= 230000) ) 3904ab47cfaaSmrg new->CR67 = 0x10; /* 8bpp, 2 pixels/clock */ 3905ab47cfaaSmrg else 3906ab47cfaaSmrg new->CR67 = 0x00; /* 8bpp, 1 pixel/clock */ 3907ab47cfaaSmrg break; 3908ab47cfaaSmrg case 15: 3909ab47cfaaSmrg if( 3910ab47cfaaSmrg S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || 3911ab47cfaaSmrg ((psav->Chipset == S3_SAVAGE2000) && (dclk >= 230000)) 3912ab47cfaaSmrg ) 3913ab47cfaaSmrg new->CR67 = 0x30; /* 15bpp, 2 pixel/clock */ 3914ab47cfaaSmrg else 3915ab47cfaaSmrg new->CR67 = 0x20; /* 15bpp, 1 pixels/clock */ 3916ab47cfaaSmrg break; 3917ab47cfaaSmrg case 16: 3918ab47cfaaSmrg if( 3919ab47cfaaSmrg S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || 3920ab47cfaaSmrg ((psav->Chipset == S3_SAVAGE2000) && (dclk >= 230000)) 3921ab47cfaaSmrg ) 3922ab47cfaaSmrg new->CR67 = 0x50; /* 16bpp, 2 pixel/clock */ 3923ab47cfaaSmrg else 3924ab47cfaaSmrg new->CR67 = 0x40; /* 16bpp, 1 pixels/clock */ 3925ab47cfaaSmrg break; 3926ab47cfaaSmrg case 24: 3927ab47cfaaSmrg if (psav->primStreamBpp == 24 ) 3928ab47cfaaSmrg new->CR67 = 0x70; 3929ab47cfaaSmrg else 3930ab47cfaaSmrg new->CR67 = 0xd0; 3931ab47cfaaSmrg break; 3932ab47cfaaSmrg } 3933ab47cfaaSmrg 3934ab47cfaaSmrg 3935ab47cfaaSmrg if( psav->UseBIOS ) { 3936ab47cfaaSmrg int refresh; 3937ab47cfaaSmrg unsigned int newmode=0, newrefresh=0; 3938ab47cfaaSmrg 3939ab47cfaaSmrg refresh = SavageGetRefresh(mode); 3940ab47cfaaSmrg 3941ab47cfaaSmrg SavageMatchBiosMode(pScrn,mode->HDisplay,mode->VDisplay,refresh, 3942ab47cfaaSmrg &newmode,&newrefresh); 3943ab47cfaaSmrg new->mode = newmode; 3944ab47cfaaSmrg new->refresh = newrefresh; 3945ab47cfaaSmrg } 3946ab47cfaaSmrg 3947ab47cfaaSmrg if( !new->mode ) { 3948ab47cfaaSmrg /* 3949ab47cfaaSmrg * Either BIOS use is disabled, or we failed to find a suitable 3950ab47cfaaSmrg * match. Fall back to traditional register-crunching. 3951ab47cfaaSmrg */ 3952ab47cfaaSmrg 3953ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x3a); 3954ab47cfaaSmrg tmp = VGAIN8(vgaCRReg); 3955ab47cfaaSmrg if (psav->pci_burst) 3956ab47cfaaSmrg new->CR3A = (tmp & 0x7f) | 0x15; 3957ab47cfaaSmrg else 3958ab47cfaaSmrg new->CR3A = tmp | 0x95; 3959ab47cfaaSmrg 3960ab47cfaaSmrg new->CR53 = 0x00; 3961ab47cfaaSmrg new->CR31 = 0x8c; 3962ab47cfaaSmrg new->CR66 = 0x89; 3963ab47cfaaSmrg 3964ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x58); 3965ab47cfaaSmrg new->CR58 = VGAIN8(vgaCRReg) & 0x80; 3966ab47cfaaSmrg new->CR58 |= 0x13; 3967ab47cfaaSmrg 3968ab47cfaaSmrg#if 0 3969ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x55); 3970ab47cfaaSmrg new->CR55 = VGAIN8(vgaCRReg); 3971ab47cfaaSmrg if (psav->hwcursor) 3972ab47cfaaSmrg new->CR55 |= 0x10; 3973ab47cfaaSmrg#endif 3974ab47cfaaSmrg 3975ab47cfaaSmrg new->SR15 = 0x03 | 0x80; 3976ab47cfaaSmrg new->SR18 = 0x00; 3977ab47cfaaSmrg 3978ab47cfaaSmrg 3979ab47cfaaSmrg /* enable gamma correction */ 3980ab47cfaaSmrg if( pScrn->depth == 24 ) 3981ab47cfaaSmrg new->SR1B = 0x18; 3982ab47cfaaSmrg else 3983ab47cfaaSmrg new->SR1B = 0x00; 3984ab47cfaaSmrg 3985ab47cfaaSmrg /* set 8-bit CLUT */ 3986ab47cfaaSmrg new->SR1B |= 0x10; 3987ab47cfaaSmrg 3988ab47cfaaSmrg new->CR43 = new->CR45 = new->CR65 = 0x00; 3989ab47cfaaSmrg 3990ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x40); 3991ab47cfaaSmrg new->CR40 = VGAIN8(vgaCRReg) & ~0x01; 3992ab47cfaaSmrg 3993ab47cfaaSmrg new->MMPR0 = 0x010400; 3994ab47cfaaSmrg new->MMPR1 = 0x00; 3995ab47cfaaSmrg new->MMPR2 = 0x0808; 3996ab47cfaaSmrg new->MMPR3 = 0x08080810; 3997ab47cfaaSmrg 3998ab47cfaaSmrg if (psav->fifo_aggressive || psav->fifo_moderate || 3999ab47cfaaSmrg psav->fifo_conservative) { 4000ab47cfaaSmrg new->MMPR1 = 0x0200; 4001ab47cfaaSmrg new->MMPR2 = 0x1808; 4002ab47cfaaSmrg new->MMPR3 = 0x08081810; 4003ab47cfaaSmrg } 4004ab47cfaaSmrg 4005ab47cfaaSmrg if (psav->MCLK <= 0) { 4006ab47cfaaSmrg new->SR10 = 255; 4007ab47cfaaSmrg new->SR11 = 255; 4008ab47cfaaSmrg } 4009ab47cfaaSmrg 4010ab47cfaaSmrg psav->NeedSTREAMS = FALSE; 4011ab47cfaaSmrg 4012ab47cfaaSmrg SavageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, 4013ab47cfaaSmrg &m, &n, &r); 4014ab47cfaaSmrg new->SR12 = (r << 6) | (n & 0x3f); 4015ab47cfaaSmrg new->SR13 = m & 0xff; 4016ab47cfaaSmrg new->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; 4017ab47cfaaSmrg 4018ab47cfaaSmrg if (psav->fifo_moderate) { 4019ab47cfaaSmrg if (psav->primStreamBpp < 24) 4020ab47cfaaSmrg new->MMPR0 -= 0x8000; 4021ab47cfaaSmrg else 4022ab47cfaaSmrg new->MMPR0 -= 0x4000; 4023ab47cfaaSmrg } else if (psav->fifo_aggressive) { 4024ab47cfaaSmrg if (psav->primStreamBpp < 24) 4025ab47cfaaSmrg new->MMPR0 -= 0xc000; 4026ab47cfaaSmrg else 4027ab47cfaaSmrg new->MMPR0 -= 0x6000; 4028ab47cfaaSmrg } 4029ab47cfaaSmrg 4030ab47cfaaSmrg if (mode->Flags & V_INTERLACE) 4031ab47cfaaSmrg new->CR42 = 0x20; 4032ab47cfaaSmrg else 4033ab47cfaaSmrg new->CR42 = 0x00; 4034ab47cfaaSmrg 4035ab47cfaaSmrg new->CR34 = 0x10; 4036ab47cfaaSmrg 4037ab47cfaaSmrg i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) | 4038ab47cfaaSmrg ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) | 4039ab47cfaaSmrg ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) | 4040ab47cfaaSmrg ((mode->CrtcHSyncStart & 0x800) >> 7); 4041ab47cfaaSmrg 4042ab47cfaaSmrg if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 64) 4043ab47cfaaSmrg i |= 0x08; 4044ab47cfaaSmrg if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32) 4045ab47cfaaSmrg i |= 0x20; 4046ab47cfaaSmrg j = (vganew->CRTC[0] + ((i & 0x01) << 8) + 4047ab47cfaaSmrg vganew->CRTC[4] + ((i & 0x10) << 4) + 1) / 2; 4048ab47cfaaSmrg if (j - (vganew->CRTC[4] + ((i & 0x10) << 4)) < 4) { 4049ab47cfaaSmrg if (vganew->CRTC[4] + ((i & 0x10) << 4) + 4 <= 4050ab47cfaaSmrg vganew->CRTC[0] + ((i & 0x01) << 8)) 4051ab47cfaaSmrg j = vganew->CRTC[4] + ((i & 0x10) << 4) + 4; 4052ab47cfaaSmrg else 4053ab47cfaaSmrg j = vganew->CRTC[0] + ((i & 0x01) << 8) + 1; 4054ab47cfaaSmrg } 4055ab47cfaaSmrg 4056ab47cfaaSmrg new->CR3B = j & 0xff; 4057ab47cfaaSmrg i |= (j & 0x100) >> 2; 4058ab47cfaaSmrg new->CR3C = (vganew->CRTC[0] + ((i & 0x01) << 8)) / 2 ; 4059ab47cfaaSmrg new->CR5D = i; 4060ab47cfaaSmrg new->CR5E = (((mode->CrtcVTotal - 2) & 0x400) >> 10) | 4061ab47cfaaSmrg (((mode->CrtcVDisplay - 1) & 0x400) >> 9) | 4062ab47cfaaSmrg (((mode->CrtcVSyncStart) & 0x400) >> 8) | 4063ab47cfaaSmrg (((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40; 4064ab47cfaaSmrg width = (pScrn->displayWidth * (psav->primStreamBpp / 8)) >> 3; 4065ab47cfaaSmrg new->CR91 = vganew->CRTC[19] = 0xff & width; 4066ab47cfaaSmrg new->CR51 = (0x300 & width) >> 4; 4067ab47cfaaSmrg new->CR90 = 0x80 | (width >> 8); 4068ab47cfaaSmrg vganew->MiscOutReg |= 0x0c; 4069ab47cfaaSmrg 4070ab47cfaaSmrg /* Set frame buffer description. */ 4071ab47cfaaSmrg 4072ab47cfaaSmrg if (psav->primStreamBpp <= 8) 4073ab47cfaaSmrg new->CR50 = 0; 4074ab47cfaaSmrg else if (psav->primStreamBpp <= 16) 4075ab47cfaaSmrg new->CR50 = 0x10; 4076ab47cfaaSmrg else 4077ab47cfaaSmrg new->CR50 = 0x30; 4078ab47cfaaSmrg 4079ab47cfaaSmrg if (pScrn->displayWidth == 640) 4080ab47cfaaSmrg new->CR50 |= 0x40; 4081ab47cfaaSmrg else if (pScrn->displayWidth == 800) 4082ab47cfaaSmrg new->CR50 |= 0x80; 4083ab47cfaaSmrg else if (pScrn->displayWidth == 1024) 4084ab47cfaaSmrg new->CR50 |= 0x00; 4085ab47cfaaSmrg else if (pScrn->displayWidth == 1152) 4086ab47cfaaSmrg new->CR50 |= 0x01; 4087ab47cfaaSmrg else if (pScrn->displayWidth == 1280) 4088ab47cfaaSmrg new->CR50 |= 0xc0; 4089ab47cfaaSmrg else if (pScrn->displayWidth == 1600) 4090ab47cfaaSmrg new->CR50 |= 0x81; 4091ab47cfaaSmrg else 4092ab47cfaaSmrg new->CR50 |= 0xc1; /* Use GBD */ 4093ab47cfaaSmrg 4094ab47cfaaSmrg if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) 4095ab47cfaaSmrg new->CR33 = 0x00; 4096ab47cfaaSmrg else 4097ab47cfaaSmrg new->CR33 = 0x08; 4098ab47cfaaSmrg 4099ab47cfaaSmrg vganew->CRTC[0x17] = 0xeb; 4100ab47cfaaSmrg 4101ab47cfaaSmrg new->CR67 |= 1; 4102ab47cfaaSmrg 4103ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x36); 4104ab47cfaaSmrg new->CR36 = VGAIN8(vgaCRReg); 4105ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x68); 4106ab47cfaaSmrg new->CR68 = VGAIN8(vgaCRReg); 4107ab47cfaaSmrg 4108ab47cfaaSmrg new->CR69 = 0; 4109ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x6f); 4110ab47cfaaSmrg new->CR6F = VGAIN8(vgaCRReg); 4111ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x86); 4112ab47cfaaSmrg new->CR86 = VGAIN8(vgaCRReg) | 0x08; 4113ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x88); 4114ab47cfaaSmrg new->CR88 = VGAIN8(vgaCRReg) | DISABLE_BLOCK_WRITE_2D; 4115ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0xb0); 4116ab47cfaaSmrg new->CRB0 = VGAIN8(vgaCRReg) | 0x80; 4117ab47cfaaSmrg } 4118ab47cfaaSmrg 4119ab47cfaaSmrg pScrn->vtSema = TRUE; 4120ab47cfaaSmrg 4121ab47cfaaSmrg /* do it! */ 4122ab47cfaaSmrg SavageWriteMode(pScrn, vganew, new, TRUE); 4123ab47cfaaSmrg 4124ab47cfaaSmrg if (psav->FBStart2nd) { 4125ab47cfaaSmrg SavageStreamsOn(pScrn); 4126ab47cfaaSmrg SavageInitSecondaryStream(pScrn); 4127ab47cfaaSmrg } 4128ab47cfaaSmrg 4129ab47cfaaSmrg SavageAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 4130ab47cfaaSmrg 4131ab47cfaaSmrg return TRUE; 4132ab47cfaaSmrg} 4133ab47cfaaSmrg 4134ab47cfaaSmrg 4135ab47cfaaSmrgstatic Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen) 4136ab47cfaaSmrg{ 4137ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4138ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 4139ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4140ab47cfaaSmrg vgaRegPtr vgaSavePtr = &hwp->SavedReg; 4141ab47cfaaSmrg SavageRegPtr SavageSavePtr = &psav->SavedReg; 4142ab47cfaaSmrg 4143ab47cfaaSmrg TRACE(("SavageCloseScreen\n")); 4144ab47cfaaSmrg 4145ab47cfaaSmrg#ifdef XF86DRI 4146ab47cfaaSmrg if (psav->directRenderingEnabled) { 4147ab47cfaaSmrg SAVAGEDRICloseScreen(pScreen); 4148ab47cfaaSmrg /* reset shadow values */ 4149ab47cfaaSmrg SavageInitShadowStatus(pScrn); 4150ab47cfaaSmrg psav->directRenderingEnabled=FALSE; 4151ab47cfaaSmrg } 4152ab47cfaaSmrg#endif 4153ab47cfaaSmrg 4154ab47cfaaSmrg if (psav->EXADriverPtr) { 4155ab47cfaaSmrg exaDriverFini(pScreen); 4156ab47cfaaSmrg psav->EXADriverPtr = NULL; 4157ab47cfaaSmrg } 4158ab47cfaaSmrg 4159ab47cfaaSmrg if( psav->AccelInfoRec ) { 4160ab47cfaaSmrg XAADestroyInfoRec( psav->AccelInfoRec ); 4161ab47cfaaSmrg psav->AccelInfoRec = NULL; 4162ab47cfaaSmrg } 4163ab47cfaaSmrg 4164ab47cfaaSmrg if( psav->DGAModes ) { 4165ab47cfaaSmrg xfree( psav->DGAModes ); 4166ab47cfaaSmrg psav->DGAModes = NULL; 4167ab47cfaaSmrg psav->numDGAModes = 0; 4168ab47cfaaSmrg } 4169ab47cfaaSmrg 4170ab47cfaaSmrg if (pScrn->vtSema) { 4171ab47cfaaSmrg if (psav->FBStart2nd) 4172ab47cfaaSmrg SavageStreamsOff(pScrn); 4173ab47cfaaSmrg SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE); 4174ab47cfaaSmrg SavageResetStreams(pScrn); 4175ab47cfaaSmrg vgaHWLock(hwp); 4176ab47cfaaSmrg SavageUnmapMem(pScrn, 0); 4177ab47cfaaSmrg } 4178ab47cfaaSmrg 4179ab47cfaaSmrg if (psav->pVbe) 4180ab47cfaaSmrg vbeFree(psav->pVbe); 4181ab47cfaaSmrg psav->pVbe = NULL; 4182ab47cfaaSmrg 4183ab47cfaaSmrg pScrn->vtSema = FALSE; 4184ab47cfaaSmrg pScreen->CloseScreen = psav->CloseScreen; 4185ab47cfaaSmrg 4186ab47cfaaSmrg return (*pScreen->CloseScreen)(scrnIndex, pScreen); 4187ab47cfaaSmrg} 4188ab47cfaaSmrg 4189ab47cfaaSmrg 4190ab47cfaaSmrgstatic Bool SavageSaveScreen(ScreenPtr pScreen, int mode) 4191ab47cfaaSmrg{ 4192ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 4193ab47cfaaSmrg 4194ab47cfaaSmrg TRACE(("SavageSaveScreen(0x%x)\n", mode)); 4195ab47cfaaSmrg 4196ab47cfaaSmrg if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor && SAVPTR(pScrn)->hwc_on ) 4197ab47cfaaSmrg { 4198ab47cfaaSmrg if( xf86IsUnblank(mode) ) 4199ab47cfaaSmrg SavageShowCursor( pScrn ); 4200ab47cfaaSmrg else 4201ab47cfaaSmrg SavageHideCursor( pScrn ); 4202ab47cfaaSmrg SAVPTR(pScrn)->hwc_on = TRUE; /*restore */ 4203ab47cfaaSmrg } 4204ab47cfaaSmrg 4205ab47cfaaSmrg return vgaHWSaveScreen(pScreen, mode); 4206ab47cfaaSmrg} 4207ab47cfaaSmrg 4208ab47cfaaSmrgvoid SavageAdjustFrame(int scrnIndex, int x, int y, int flags) 4209ab47cfaaSmrg{ 4210ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4211ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4212ab47cfaaSmrg 4213ab47cfaaSmrg if (psav->IsSecondary) { 4214ab47cfaaSmrg SavageDoAdjustFrame(pScrn, x, y, TRUE); 4215ab47cfaaSmrg } else { 4216ab47cfaaSmrg SavageDoAdjustFrame(pScrn, x, y, FALSE); 4217ab47cfaaSmrg } 4218ab47cfaaSmrg 4219ab47cfaaSmrg} 4220ab47cfaaSmrg 4221ab47cfaaSmrgvoid 4222ab47cfaaSmrgSavageDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int crtc2) 4223ab47cfaaSmrg{ 4224ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4225ab47cfaaSmrg int address=0,top=0,left=0,tile_height,tile_size; 4226ab47cfaaSmrg 4227ab47cfaaSmrg TRACE(("SavageDoAdjustFrame(%d,%d,%x)\n", x, y, flags)); 4228ab47cfaaSmrg 4229ab47cfaaSmrg if (psav->Chipset == S3_SAVAGE2000) { 4230ab47cfaaSmrg tile_height = TILEHEIGHT_2000; /* 32 */ 4231ab47cfaaSmrg tile_size = TILE_SIZE_BYTE_2000; /* 4096 */ 4232ab47cfaaSmrg } else { 4233ab47cfaaSmrg tile_height = TILEHEIGHT; /* 16 */ 4234ab47cfaaSmrg tile_size = TILE_SIZE_BYTE; /* 2048 */ 4235ab47cfaaSmrg } 4236ab47cfaaSmrg 4237ab47cfaaSmrg if (!psav->bTiled) { 4238ab47cfaaSmrg left = x - x % 64; 4239ab47cfaaSmrg top = y; 4240ab47cfaaSmrg address = (top * psav->lDelta) + left * (pScrn->bitsPerPixel >> 3); 4241ab47cfaaSmrg address = (address >> 5) << 5; 4242ab47cfaaSmrg } else { 4243ab47cfaaSmrg top = y - y % tile_height; 4244ab47cfaaSmrg if (pScrn->bitsPerPixel == 16) { 4245ab47cfaaSmrg left = x - x % TILEWIDTH_16BPP; 4246ab47cfaaSmrg address = top * psav->lDelta + left * tile_size / TILEWIDTH_16BPP; 4247ab47cfaaSmrg } else if (pScrn->bitsPerPixel == 32) { 4248ab47cfaaSmrg left = x - x % TILEWIDTH_32BPP; 4249ab47cfaaSmrg address = top * psav->lDelta + left * tile_size / TILEWIDTH_32BPP; 4250ab47cfaaSmrg } 4251ab47cfaaSmrg } 4252ab47cfaaSmrg 4253ab47cfaaSmrg address += pScrn->fbOffset; 4254ab47cfaaSmrg 4255ab47cfaaSmrg if (psav->Chipset == S3_SAVAGE_MX) { 4256ab47cfaaSmrg if (!crtc2) { 4257ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0, address & 0xFFFFFFFC); 4258ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR1, address & 0xFFFFFFFC);/* IGA1 */ 4259ab47cfaaSmrg } else { 4260ab47cfaaSmrg OUTREG32(PRI_STREAM2_FBUF_ADDR0, address & 0xFFFFFFFC);/* IGA2 */ 4261ab47cfaaSmrg OUTREG32(PRI_STREAM2_FBUF_ADDR1, address & 0xFFFFFFFC); 4262ab47cfaaSmrg } 4263ab47cfaaSmrg } else if (psav->Chipset == S3_SUPERSAVAGE) { 4264ab47cfaaSmrg if (!crtc2) { 4265ab47cfaaSmrg /* IGA1 */ 4266ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0, 0x80000000); 4267ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR1, address & 0xFFFFFFF8); 4268ab47cfaaSmrg } else { 4269ab47cfaaSmrg /* IGA2 */ 4270ab47cfaaSmrg OUTREG32(PRI_STREAM2_FBUF_ADDR0, ((address & 0xFFFFFFF8) | 0x80000000)); 4271ab47cfaaSmrg OUTREG32(PRI_STREAM2_FBUF_ADDR1, address & 0xFFFFFFF8); 4272ab47cfaaSmrg } 4273ab47cfaaSmrg } else if (psav->Chipset == S3_SAVAGE2000) { 4274ab47cfaaSmrg /* certain Y values seems to cause havoc, not sure why */ 4275ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0, (address & 0xFFFFFFF8)); 4276ab47cfaaSmrg OUTREG32(PRI_STREAM2_FBUF_ADDR0, (address & 0xFFFFFFF8)); 4277ab47cfaaSmrg } else { 4278ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0,address | 0xFFFFFFFC); 4279ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR1,address | 0x80000000); 4280ab47cfaaSmrg } 4281ab47cfaaSmrg 4282ab47cfaaSmrg return; 4283ab47cfaaSmrg} 4284ab47cfaaSmrg 4285ab47cfaaSmrgBool SavageSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 4286ab47cfaaSmrg{ 4287ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4288ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4289ab47cfaaSmrg Bool success; 4290ab47cfaaSmrg 4291ab47cfaaSmrg TRACE(("SavageSwitchMode\n")); 4292ab47cfaaSmrg 4293ab47cfaaSmrg if (psav->FBStart2nd || (psav->videoFlags & VF_STREAMS_ON)) 4294ab47cfaaSmrg SavageStreamsOff(xf86Screens[scrnIndex]); 4295ab47cfaaSmrg 4296ab47cfaaSmrg success = SavageModeInit(xf86Screens[scrnIndex], mode); 4297ab47cfaaSmrg 4298ab47cfaaSmrg /* switching mode on primary will reset secondary. it needs to be reset as well*/ 4299ab47cfaaSmrg if (psav->IsPrimary) { 4300ab47cfaaSmrg DevUnion* pPriv; 4301ab47cfaaSmrg SavageEntPtr pSavEnt; 4302ab47cfaaSmrg pPriv = xf86GetEntityPrivate(pScrn->entityList[0], 4303ab47cfaaSmrg gSavageEntityIndex); 4304ab47cfaaSmrg pSavEnt = pPriv->ptr; 4305ab47cfaaSmrg SavageModeInit(pSavEnt->pSecondaryScrn, pSavEnt->pSecondaryScrn->currentMode); 4306ab47cfaaSmrg } 43078697ee19Smrg SavagePanningCheck(pScrn, mode); 4308ab47cfaaSmrg 4309ab47cfaaSmrg return success; 4310ab47cfaaSmrg} 4311ab47cfaaSmrg 4312ab47cfaaSmrg 4313ab47cfaaSmrgvoid SavageEnableMMIO(ScrnInfoPtr pScrn) 4314ab47cfaaSmrg{ 4315ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 4316ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4317ab47cfaaSmrg int vgaCRIndex, vgaCRReg; 4318ab47cfaaSmrg unsigned char val; 4319ab47cfaaSmrg 4320ab47cfaaSmrg TRACE(("SavageEnableMMIO\n")); 4321ab47cfaaSmrg 4322ab47cfaaSmrg vgaHWSetStdFuncs(hwp); 4323ab47cfaaSmrg vgaHWSetMmioFuncs(hwp, psav->MapBase, 0x8000); 4324ab47cfaaSmrg val = VGAIN8(0x3c3); 4325ab47cfaaSmrg VGAOUT8(0x3c3, val | 0x01); 4326ab47cfaaSmrg val = VGAIN8(VGA_MISC_OUT_R); 4327ab47cfaaSmrg VGAOUT8(VGA_MISC_OUT_W, val | 0x01); 4328ab47cfaaSmrg vgaCRIndex = psav->vgaIOBase + 4; 4329ab47cfaaSmrg vgaCRReg = psav->vgaIOBase + 5; 4330ab47cfaaSmrg 4331ab47cfaaSmrg if( psav->Chipset >= S3_SAVAGE4 ) 4332ab47cfaaSmrg { 4333ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x40); 4334ab47cfaaSmrg val = VGAIN8(vgaCRReg); 4335ab47cfaaSmrg VGAOUT8(vgaCRReg, val | 1); 4336ab47cfaaSmrg } 4337ab47cfaaSmrg 4338ab47cfaaSmrg return; 4339ab47cfaaSmrg} 4340ab47cfaaSmrg 4341ab47cfaaSmrg 4342ab47cfaaSmrgvoid SavageDisableMMIO(ScrnInfoPtr pScrn) 4343ab47cfaaSmrg{ 4344ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 4345ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4346ab47cfaaSmrg int vgaCRIndex, vgaCRReg; 4347ab47cfaaSmrg unsigned char val; 4348ab47cfaaSmrg 4349ab47cfaaSmrg TRACE(("SavageDisableMMIO\n")); 4350ab47cfaaSmrg 4351ab47cfaaSmrg vgaCRIndex = psav->vgaIOBase + 4; 4352ab47cfaaSmrg vgaCRReg = psav->vgaIOBase + 5; 4353ab47cfaaSmrg 4354ab47cfaaSmrg if( psav->Chipset >= S3_SAVAGE4 ) 4355ab47cfaaSmrg { 4356ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x40); 4357ab47cfaaSmrg val = VGAIN8(vgaCRReg); 4358ab47cfaaSmrg VGAOUT8(vgaCRReg, val | 1); 4359ab47cfaaSmrg } 4360ab47cfaaSmrg 4361ab47cfaaSmrg vgaHWSetStdFuncs(hwp); 4362ab47cfaaSmrg 4363ab47cfaaSmrg return; 4364ab47cfaaSmrg} 4365ab47cfaaSmrg 4366ab47cfaaSmrgvoid SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, 4367ab47cfaaSmrg LOCO *colors, VisualPtr pVisual) 4368ab47cfaaSmrg{ 4369ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4370ab47cfaaSmrg int i, index; 4371ab47cfaaSmrg int updateKey = -1; 4372ab47cfaaSmrg unsigned char byte = 0; 4373ab47cfaaSmrg 4374ab47cfaaSmrg /* choose CLUT */ 4375ab47cfaaSmrg if (psav->IsPrimary) { 4376ab47cfaaSmrg /* enable CLUT 1 */ 4377ab47cfaaSmrg VGAOUT8(0x3c4, 0x21); 4378ab47cfaaSmrg byte = VGAIN8(0x3c5); 4379ab47cfaaSmrg VGAOUT8(0x3c5, (byte & ~0x01)); 4380ab47cfaaSmrg /* select CLUT 1 */ 4381ab47cfaaSmrg VGAOUT8(0x3c4, 0x47); 4382ab47cfaaSmrg byte = VGAIN8(0x3c5); 4383ab47cfaaSmrg VGAOUT8(0x3c5, (byte & ~0x03) | 0x01); /* CLUT 1 */ 4384ab47cfaaSmrg } else if (psav->IsSecondary) { 4385ab47cfaaSmrg /* enable CLUT 2 */ 4386ab47cfaaSmrg VGAOUT8(0x3c4, 0x21); 4387ab47cfaaSmrg byte = VGAIN8(0x3c5); 4388ab47cfaaSmrg VGAOUT8(0x3c5, (byte & ~0x10)); 4389ab47cfaaSmrg /* select CLUT 2 */ 4390ab47cfaaSmrg VGAOUT8(0x3c4, 0x47); 4391ab47cfaaSmrg byte = VGAIN8(0x3c5); 4392ab47cfaaSmrg VGAOUT8(0x3c5, (byte & ~0x03) | 0x02); /* CLUT 2 */ 4393ab47cfaaSmrg } 4394ab47cfaaSmrg 4395ab47cfaaSmrg for (i=0; i<numColors; i++) { 4396ab47cfaaSmrg index = indicies[i]; 4397ab47cfaaSmrg if (index == pScrn->colorKey) updateKey = index; 4398ab47cfaaSmrg VGAOUT8(0x3c8, index); 4399ab47cfaaSmrg VGAOUT8(0x3c9, colors[index].red); 4400ab47cfaaSmrg VGAOUT8(0x3c9, colors[index].green); 4401ab47cfaaSmrg VGAOUT8(0x3c9, colors[index].blue); 4402ab47cfaaSmrg } 4403ab47cfaaSmrg 4404ab47cfaaSmrg /* restore saved CLUT index value */ 4405ab47cfaaSmrg if (psav->IsPrimary || psav->IsSecondary) { 4406ab47cfaaSmrg VGAOUT8(0x3c4, 0x47); 4407ab47cfaaSmrg VGAOUT8(0x3c5, byte); 4408ab47cfaaSmrg } 4409ab47cfaaSmrg 4410ab47cfaaSmrg if (updateKey != -1) 4411ab47cfaaSmrg SavageUpdateKey(pScrn, colors[updateKey].red, colors[updateKey].green, 4412ab47cfaaSmrg colors[updateKey].blue); 4413ab47cfaaSmrg} 4414ab47cfaaSmrg 4415ab47cfaaSmrg#define Shift(v,d) ((d) < 0 ? ((v) >> (-d)) : ((v) << (d))) 4416ab47cfaaSmrg 4417ab47cfaaSmrgstatic void 4418ab47cfaaSmrgSavageUpdateKey(ScrnInfoPtr pScrn, int r, int g, int b) 4419ab47cfaaSmrg{ 4420ab47cfaaSmrg ScreenPtr pScreen; 4421ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4422ab47cfaaSmrg FbOverlayScrPrivPtr pScrOvlPriv; 4423ab47cfaaSmrg CARD32 key; 4424ab47cfaaSmrg int ul = 0, ol = 1; 4425ab47cfaaSmrg 4426ab47cfaaSmrg if (pScrn->depth != 8) { 4427ab47cfaaSmrg ul = 1; 4428ab47cfaaSmrg ol = 0; 4429ab47cfaaSmrg } 4430ab47cfaaSmrg if (!(pScreen = pScrn->pScreen) 4431ab47cfaaSmrg || !(pScrOvlPriv = fbOverlayGetScrPriv(pScreen))) 4432ab47cfaaSmrg return; 4433ab47cfaaSmrg key = ((Shift(r,psav->overlay.redShift) & psav->overlay.redMask) 4434ab47cfaaSmrg | (Shift(g,psav->overlay.greenShift) & psav->overlay.greenMask) 4435ab47cfaaSmrg | (Shift(b,psav->overlay.blueShift) & psav->overlay.blueMask)); 4436ab47cfaaSmrg if (pScrOvlPriv->layer[ol].key != key) { 4437ab47cfaaSmrg pScrOvlPriv->layer[ol].key = key; 4438ab47cfaaSmrg (*pScrOvlPriv->PaintKey) (&pScrOvlPriv->layer[ol].u.run.pixmap->drawable, 4439ab47cfaaSmrg &pScrOvlPriv->layer[ul].u.run.region, 4440ab47cfaaSmrg pScrOvlPriv->layer[ol].key, ol); 4441ab47cfaaSmrg } 4442ab47cfaaSmrg} 4443ab47cfaaSmrg 4444ab47cfaaSmrg#if 0 4445ab47cfaaSmrg#define inStatus1() (hwp->readST01( hwp )) 4446ab47cfaaSmrg#endif 4447ab47cfaaSmrg 4448ab47cfaaSmrgvoid SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies, 4449ab47cfaaSmrg LOCO *colors, VisualPtr pVisual) 4450ab47cfaaSmrg{ 4451ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4452ab47cfaaSmrg int i, index; 4453ab47cfaaSmrg int updateKey = -1; 4454ab47cfaaSmrg 4455ab47cfaaSmrg VerticalRetraceWait(); 4456ab47cfaaSmrg 4457ab47cfaaSmrg for (i=0; i<numColors; i++) { 4458ab47cfaaSmrg if (!(inStatus1()) & 0x08) 4459ab47cfaaSmrg VerticalRetraceWait(); 4460ab47cfaaSmrg index = indicies[i]; 4461ab47cfaaSmrg VGAOUT8(0x3c8, index); 4462ab47cfaaSmrg VGAOUT8(0x3c9, colors[index].red); 4463ab47cfaaSmrg VGAOUT8(0x3c9, colors[index].green); 4464ab47cfaaSmrg VGAOUT8(0x3c9, colors[index].blue); 4465ab47cfaaSmrg if (index == pScrn->colorKey) updateKey = index; 4466ab47cfaaSmrg } 4467ab47cfaaSmrg if (updateKey != -1) 4468ab47cfaaSmrg SavageUpdateKey(pScrn, colors[updateKey].red, colors[updateKey].green, 4469ab47cfaaSmrg colors[updateKey].blue); 4470ab47cfaaSmrg} 4471ab47cfaaSmrg 4472ab47cfaaSmrgstatic void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, 4473ab47cfaaSmrg int min_n2, int max_n2, long freq_min, 4474ab47cfaaSmrg long freq_max, unsigned int *mdiv, 4475ab47cfaaSmrg unsigned int *ndiv, unsigned int *r) 4476ab47cfaaSmrg{ 4477ab47cfaaSmrg double ffreq, ffreq_min, ffreq_max; 4478ab47cfaaSmrg double div, diff, best_diff; 4479ab47cfaaSmrg unsigned int m; 4480ab47cfaaSmrg unsigned char n1, n2, best_n1=16+2, best_n2=2, best_m=125+2; 4481ab47cfaaSmrg 4482ab47cfaaSmrg ffreq = freq / 1000.0 / BASE_FREQ; 4483ab47cfaaSmrg ffreq_max = freq_max / 1000.0 / BASE_FREQ; 4484ab47cfaaSmrg ffreq_min = freq_min / 1000.0 / BASE_FREQ; 4485ab47cfaaSmrg 4486ab47cfaaSmrg if (ffreq < ffreq_min / (1 << max_n2)) { 4487ab47cfaaSmrg ErrorF("invalid frequency %1.3f Mhz\n", 4488ab47cfaaSmrg ffreq*BASE_FREQ); 4489ab47cfaaSmrg ffreq = ffreq_min / (1 << max_n2); 4490ab47cfaaSmrg } 4491ab47cfaaSmrg if (ffreq > ffreq_max / (1 << min_n2)) { 4492ab47cfaaSmrg ErrorF("invalid frequency %1.3f Mhz\n", 4493ab47cfaaSmrg ffreq*BASE_FREQ); 4494ab47cfaaSmrg ffreq = ffreq_max / (1 << min_n2); 4495ab47cfaaSmrg } 4496ab47cfaaSmrg 4497ab47cfaaSmrg /* work out suitable timings */ 4498ab47cfaaSmrg 4499ab47cfaaSmrg best_diff = ffreq; 4500ab47cfaaSmrg 4501ab47cfaaSmrg for (n2=min_n2; n2<=max_n2; n2++) { 4502ab47cfaaSmrg for (n1=min_n1+2; n1<=max_n1+2; n1++) { 4503ab47cfaaSmrg m = (int)(ffreq * n1 * (1 << n2) + 0.5); 4504ab47cfaaSmrg if (m < min_m+2 || m > 127+2) 4505ab47cfaaSmrg continue; 4506ab47cfaaSmrg div = (double)(m) / (double)(n1); 4507ab47cfaaSmrg if ((div >= ffreq_min) && 4508ab47cfaaSmrg (div <= ffreq_max)) { 4509ab47cfaaSmrg diff = ffreq - div / (1 << n2); 4510ab47cfaaSmrg if (diff < 0.0) 4511ab47cfaaSmrg diff = -diff; 4512ab47cfaaSmrg if (diff < best_diff) { 4513ab47cfaaSmrg best_diff = diff; 4514ab47cfaaSmrg best_m = m; 4515ab47cfaaSmrg best_n1 = n1; 4516ab47cfaaSmrg best_n2 = n2; 4517ab47cfaaSmrg } 4518ab47cfaaSmrg } 4519ab47cfaaSmrg } 4520ab47cfaaSmrg } 4521ab47cfaaSmrg 4522ab47cfaaSmrg *ndiv = best_n1 - 2; 4523ab47cfaaSmrg *r = best_n2; 4524ab47cfaaSmrg *mdiv = best_m - 2; 4525ab47cfaaSmrg} 4526ab47cfaaSmrg 4527ab47cfaaSmrg 4528ab47cfaaSmrgvoid SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file) 4529ab47cfaaSmrg{ 4530ab47cfaaSmrg unsigned char cr66; 4531ab47cfaaSmrg int r, success = 0; 4532ab47cfaaSmrg CARD32 fifo_control = 0, miu_control = 0; 4533ab47cfaaSmrg CARD32 streams_timeout = 0, misc_timeout = 0; 4534ab47cfaaSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 4535ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4536ab47cfaaSmrg int vgaCRIndex, vgaCRReg, vgaIOBase; 4537ab47cfaaSmrg 4538ab47cfaaSmrg TRACE(("SavageGEReset(%d,%s)\n", line, file)); 4539ab47cfaaSmrg 4540ab47cfaaSmrg vgaIOBase = hwp->IOBase; 4541ab47cfaaSmrg vgaCRIndex = vgaIOBase + 4; 4542ab47cfaaSmrg vgaCRReg = vgaIOBase + 5; 4543ab47cfaaSmrg 4544ab47cfaaSmrg if (from_timeout) { 4545ab47cfaaSmrg if (psav->GEResetCnt++ < 10 || xf86GetVerbosity() > 1) 4546ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4547ab47cfaaSmrg "SavageGEReset called from %s line %d\n", file, line); 4548ab47cfaaSmrg } else 4549ab47cfaaSmrg psav->WaitIdleEmpty(psav); 4550ab47cfaaSmrg 4551ab47cfaaSmrg if (from_timeout && !S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) { 4552ab47cfaaSmrg fifo_control = INREG(FIFO_CONTROL_REG); 4553ab47cfaaSmrg miu_control = INREG(MIU_CONTROL_REG); 4554ab47cfaaSmrg streams_timeout = INREG(STREAMS_TIMEOUT_REG); 4555ab47cfaaSmrg misc_timeout = INREG(MISC_TIMEOUT_REG); 4556ab47cfaaSmrg } 4557ab47cfaaSmrg 4558ab47cfaaSmrg VGAOUT8(vgaCRIndex, 0x66); 4559ab47cfaaSmrg cr66 = VGAIN8(vgaCRReg); 4560ab47cfaaSmrg 4561ab47cfaaSmrg usleep(10000); 4562ab47cfaaSmrg for (r=1; r<10; r++) { 4563ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66 | 0x02); 4564ab47cfaaSmrg usleep(10000); 4565ab47cfaaSmrg VGAOUT8(vgaCRReg, cr66 & ~0x02); 4566ab47cfaaSmrg usleep(10000); 4567ab47cfaaSmrg 4568ab47cfaaSmrg if (!from_timeout) 4569ab47cfaaSmrg psav->WaitIdleEmpty(psav); 4570ab47cfaaSmrg OUTREG(DEST_SRC_STR, psav->Bpl << 16 | psav->Bpl); 4571ab47cfaaSmrg 4572ab47cfaaSmrg usleep(10000); 4573ab47cfaaSmrg switch(psav->Chipset) { 4574ab47cfaaSmrg case S3_SAVAGE3D: 4575ab47cfaaSmrg case S3_SAVAGE_MX: 4576ab47cfaaSmrg success = (STATUS_WORD0 & 0x0008ffff) == 0x00080000; 4577ab47cfaaSmrg break; 4578ab47cfaaSmrg case S3_SAVAGE4: 4579ab47cfaaSmrg case S3_PROSAVAGE: 4580ab47cfaaSmrg case S3_PROSAVAGEDDR: 4581ab47cfaaSmrg case S3_TWISTER: 4582ab47cfaaSmrg case S3_SUPERSAVAGE: 4583ab47cfaaSmrg success = (ALT_STATUS_WORD0 & 0x0081ffff) == 0x00800000; 4584ab47cfaaSmrg break; 4585ab47cfaaSmrg case S3_SAVAGE2000: 4586ab47cfaaSmrg success = (ALT_STATUS_WORD0 & 0x008fffff) == 0; 4587ab47cfaaSmrg break; 4588ab47cfaaSmrg } 4589ab47cfaaSmrg if(!success) { 4590ab47cfaaSmrg usleep(10000); 4591ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4592ab47cfaaSmrg "restarting S3 graphics engine reset %2d ...\n", r); 4593ab47cfaaSmrg } 4594ab47cfaaSmrg else 4595ab47cfaaSmrg break; 4596ab47cfaaSmrg } 4597ab47cfaaSmrg 4598ab47cfaaSmrg /* At this point, the FIFO is empty and the engine is idle. */ 4599ab47cfaaSmrg 4600ab47cfaaSmrg if (from_timeout && !S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) { 4601ab47cfaaSmrg OUTREG(FIFO_CONTROL_REG, fifo_control); 4602ab47cfaaSmrg OUTREG(MIU_CONTROL_REG, miu_control); 4603ab47cfaaSmrg OUTREG(STREAMS_TIMEOUT_REG, streams_timeout); 4604ab47cfaaSmrg OUTREG(MISC_TIMEOUT_REG, misc_timeout); 4605ab47cfaaSmrg } 4606ab47cfaaSmrg 4607ab47cfaaSmrg OUTREG(SRC_BASE, 0); 4608ab47cfaaSmrg OUTREG(DEST_BASE, 0); 4609ab47cfaaSmrg OUTREG(CLIP_L_R, ((0) << 16) | pScrn->displayWidth); 4610ab47cfaaSmrg OUTREG(CLIP_T_B, ((0) << 16) | psav->ScissB); 4611ab47cfaaSmrg OUTREG(MONO_PAT_0, ~0); 4612ab47cfaaSmrg OUTREG(MONO_PAT_1, ~0); 4613ab47cfaaSmrg 4614ab47cfaaSmrg SavageSetGBD(pScrn); 4615ab47cfaaSmrg 4616ab47cfaaSmrg} 4617ab47cfaaSmrg 4618ab47cfaaSmrg 4619ab47cfaaSmrg 4620ab47cfaaSmrg/* This function is used to debug, it prints out the contents of s3 regs */ 4621ab47cfaaSmrg 4622ab47cfaaSmrgvoid 4623ab47cfaaSmrgSavagePrintRegs(ScrnInfoPtr pScrn) 4624ab47cfaaSmrg{ 4625ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4626ab47cfaaSmrg unsigned char i; 4627ab47cfaaSmrg int vgaCRIndex = 0x3d4; 4628ab47cfaaSmrg int vgaCRReg = 0x3d5; 4629ab47cfaaSmrg 4630ab47cfaaSmrg ErrorF( "SR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF" ); 4631ab47cfaaSmrg 4632ab47cfaaSmrg for( i = 0; i < 0x70; i++ ) { 4633ab47cfaaSmrg if( !(i % 16) ) 4634ab47cfaaSmrg ErrorF( "\nSR%xx ", i >> 4 ); 4635ab47cfaaSmrg VGAOUT8( 0x3c4, i ); 4636ab47cfaaSmrg ErrorF( " %02x", VGAIN8(0x3c5) ); 4637ab47cfaaSmrg } 4638ab47cfaaSmrg 4639ab47cfaaSmrg ErrorF( "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF" ); 4640ab47cfaaSmrg 4641ab47cfaaSmrg for( i = 0; i < 0xB7; i++ ) { 4642ab47cfaaSmrg if( !(i % 16) ) 4643ab47cfaaSmrg ErrorF( "\nCR%xx ", i >> 4 ); 4644ab47cfaaSmrg VGAOUT8( vgaCRIndex, i ); 4645ab47cfaaSmrg ErrorF( " %02x", VGAIN8(vgaCRReg) ); 4646ab47cfaaSmrg } 4647ab47cfaaSmrg 4648ab47cfaaSmrg ErrorF("\n\n"); 4649ab47cfaaSmrg} 4650ab47cfaaSmrg 4651ab47cfaaSmrgstatic void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags) 4652ab47cfaaSmrg{ 4653ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4654ab47cfaaSmrg unsigned char sr8 = 0x00, srd = 0x00; 4655ab47cfaaSmrg 4656ab47cfaaSmrg TRACE(("SavageDPMS(%d,%x)\n", mode, flags)); 4657ab47cfaaSmrg 4658ab47cfaaSmrg if (psav->DisplayType == MT_CRT) { 4659ab47cfaaSmrg VGAOUT8(0x3c4, 0x08); 4660ab47cfaaSmrg sr8 = VGAIN8(0x3c5); 4661ab47cfaaSmrg sr8 |= 0x06; 4662ab47cfaaSmrg VGAOUT8(0x3c5, sr8); 4663ab47cfaaSmrg 4664ab47cfaaSmrg VGAOUT8(0x3c4, 0x0d); 4665ab47cfaaSmrg srd = VGAIN8(0x3c5); 4666ab47cfaaSmrg 4667ab47cfaaSmrg srd &= 0x03; 4668ab47cfaaSmrg 4669ab47cfaaSmrg switch (mode) { 4670ab47cfaaSmrg case DPMSModeOn: 4671ab47cfaaSmrg break; 4672ab47cfaaSmrg case DPMSModeStandby: 4673ab47cfaaSmrg srd |= 0x10; 4674ab47cfaaSmrg break; 4675ab47cfaaSmrg case DPMSModeSuspend: 4676ab47cfaaSmrg srd |= 0x40; 4677ab47cfaaSmrg break; 4678ab47cfaaSmrg case DPMSModeOff: 4679ab47cfaaSmrg srd |= 0x50; 4680ab47cfaaSmrg break; 4681ab47cfaaSmrg default: 4682ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode); 4683ab47cfaaSmrg break; 4684ab47cfaaSmrg } 4685ab47cfaaSmrg 4686ab47cfaaSmrg VGAOUT8(0x3c4, 0x0d); 4687ab47cfaaSmrg VGAOUT8(0x3c5, srd); 4688ab47cfaaSmrg } 4689ab47cfaaSmrg 4690ab47cfaaSmrg if (psav->DisplayType == MT_LCD || psav->DisplayType == MT_DFP) { 4691ab47cfaaSmrg if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) && psav->UseBIOS) { 4692ab47cfaaSmrg SavageSetPanelEnabled(psav, (mode == DPMSModeOn)); 4693ab47cfaaSmrg } else { 4694ab47cfaaSmrg switch (mode) { 4695ab47cfaaSmrg case DPMSModeOn: 4696ab47cfaaSmrg VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */ 4697ab47cfaaSmrg VGAOUT8(0x3c5, VGAIN8(0x3c5) | 0x10); 4698ab47cfaaSmrg break; 4699ab47cfaaSmrg case DPMSModeStandby: 4700ab47cfaaSmrg case DPMSModeSuspend: 4701ab47cfaaSmrg case DPMSModeOff: 4702ab47cfaaSmrg VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */ 4703ab47cfaaSmrg VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x10); 4704ab47cfaaSmrg break; 4705ab47cfaaSmrg default: 4706ab47cfaaSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode); 4707ab47cfaaSmrg break; 4708ab47cfaaSmrg } 4709ab47cfaaSmrg } 4710ab47cfaaSmrg } 4711ab47cfaaSmrg 4712ab47cfaaSmrg return; 4713ab47cfaaSmrg} 4714ab47cfaaSmrg 4715ab47cfaaSmrgstatic void 4716ab47cfaaSmrgSavageProbeDDC(ScrnInfoPtr pScrn, int index) 4717ab47cfaaSmrg{ 4718ab47cfaaSmrg vbeInfoPtr pVbe; 4719ab47cfaaSmrg 4720ab47cfaaSmrg if (xf86LoadSubModule(pScrn, "vbe")) { 4721ab47cfaaSmrg xf86LoaderReqSymLists(vbeSymbols, NULL); 4722ab47cfaaSmrg pVbe = VBEInit(NULL, index); 4723ab47cfaaSmrg ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 4724ab47cfaaSmrg vbeFree(pVbe); 4725ab47cfaaSmrg } 4726ab47cfaaSmrg} 4727ab47cfaaSmrg 4728ab47cfaaSmrgstatic unsigned int 4729ab47cfaaSmrgSavageDDC1Read(ScrnInfoPtr pScrn) 4730ab47cfaaSmrg{ 4731ab47cfaaSmrg register unsigned char tmp; 4732ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4733ab47cfaaSmrg 4734ab47cfaaSmrg UnLockExtRegs(); 4735ab47cfaaSmrg 4736ab47cfaaSmrg VerticalRetraceWait(); 4737ab47cfaaSmrg 4738ab47cfaaSmrg InI2CREG(tmp,psav->I2CPort); 4739ab47cfaaSmrg 4740ab47cfaaSmrg return ((unsigned int) (tmp & 0x08)); 4741ab47cfaaSmrg} 4742ab47cfaaSmrg 4743ab47cfaaSmrgstatic Bool 4744ab47cfaaSmrgSavageDDC1(int scrnIndex) 4745ab47cfaaSmrg{ 4746ab47cfaaSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4747ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4748ab47cfaaSmrg unsigned char byte; 4749ab47cfaaSmrg xf86MonPtr pMon; 4750ab47cfaaSmrg 4751ab47cfaaSmrg UnLockExtRegs(); 4752ab47cfaaSmrg 4753ab47cfaaSmrg /* initialize chipset */ 4754ab47cfaaSmrg InI2CREG(byte,psav->I2CPort); 4755ab47cfaaSmrg OutI2CREG(byte | 0x12,psav->I2CPort); 4756ab47cfaaSmrg 4757ab47cfaaSmrg pMon = xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeedWeak(),SavageDDC1Read); 4758ab47cfaaSmrg if (!pMon) 4759ab47cfaaSmrg return FALSE; 4760ab47cfaaSmrg 4761ab47cfaaSmrg xf86PrintEDID(pMon); 4762ab47cfaaSmrg 47638697ee19Smrg if (!psav->IgnoreEDID) 47648697ee19Smrg xf86SetDDCproperties(pScrn,pMon); 4765ab47cfaaSmrg 4766ab47cfaaSmrg /* undo initialization */ 4767ab47cfaaSmrg OutI2CREG(byte,psav->I2CPort); 4768ab47cfaaSmrg 4769ab47cfaaSmrg return TRUE; 4770ab47cfaaSmrg} 4771ab47cfaaSmrg 4772ab47cfaaSmrgstatic void 4773ab47cfaaSmrgSavageGetTvMaxSize(SavagePtr psav) 4774ab47cfaaSmrg{ 4775ab47cfaaSmrg if( psav->PAL ) { 4776ab47cfaaSmrg psav->TVSizeX = 800; 4777ab47cfaaSmrg psav->TVSizeY = 600; 4778ab47cfaaSmrg } 4779ab47cfaaSmrg else { 4780ab47cfaaSmrg psav->TVSizeX = 640; 4781ab47cfaaSmrg psav->TVSizeY = 480; 4782ab47cfaaSmrg } 4783ab47cfaaSmrg} 4784ab47cfaaSmrg 4785ab47cfaaSmrg 4786ab47cfaaSmrgstatic Bool 47878697ee19SmrgSavagePanningCheck(ScrnInfoPtr pScrn, DisplayModePtr pMode) 4788ab47cfaaSmrg{ 4789ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4790ab47cfaaSmrg psav->iResX = pMode->CrtcHDisplay; 4791ab47cfaaSmrg psav->iResY = pMode->CrtcVDisplay; 4792ab47cfaaSmrg 4793ab47cfaaSmrg if ((psav->iResX < psav->PanelX || psav->iResY < psav->PanelY)) 4794ab47cfaaSmrg psav->FPExpansion = TRUE; 4795ab47cfaaSmrg else 4796ab47cfaaSmrg psav->FPExpansion = FALSE; 4797ab47cfaaSmrg 4798ab47cfaaSmrg if( psav->iResX < pScrn->virtualX || psav->iResY < pScrn->virtualY ) 4799ab47cfaaSmrg return TRUE; 4800ab47cfaaSmrg else 4801ab47cfaaSmrg return FALSE; 4802ab47cfaaSmrg} 4803ab47cfaaSmrg 4804ab47cfaaSmrgstatic void 4805ab47cfaaSmrgSavageResetStreams(ScrnInfoPtr pScrn) 4806ab47cfaaSmrg{ 4807ab47cfaaSmrg SavagePtr psav = SAVPTR(pScrn); 4808ab47cfaaSmrg unsigned char cr67; 4809ab47cfaaSmrg unsigned char cr69; 4810ab47cfaaSmrg 4811ab47cfaaSmrg /* disable streams */ 4812ab47cfaaSmrg switch (psav->Chipset) { 4813ab47cfaaSmrg case S3_SAVAGE_MX: 4814ab47cfaaSmrg case S3_SUPERSAVAGE: 4815ab47cfaaSmrg OUTREG32(PRI_STREAM_STRIDE,0); 4816ab47cfaaSmrg OUTREG32(PRI_STREAM2_STRIDE, 0); 4817ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000); 4818ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000); 4819ab47cfaaSmrg OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x00000000); 4820ab47cfaaSmrg OUTREG32(PRI_STREAM2_FBUF_ADDR1,0x00000000); 4821ab47cfaaSmrg OUTREG8(CRT_ADDRESS_REG, 0x67); 4822ab47cfaaSmrg cr67 = INREG8(CRT_DATA_REG); 4823ab47cfaaSmrg cr67 &= ~0x08; /* CR67[3] = 1 : Mem-mapped regs */ 4824ab47cfaaSmrg cr67 &= ~0x04; /* CR67[2] = 1 : enable stream 1 */ 4825ab47cfaaSmrg cr67 &= ~0x02; /* CR67[1] = 1 : enable stream 2 */ 4826ab47cfaaSmrg OUTREG8(CRT_DATA_REG, cr67); 4827ab47cfaaSmrg break; 4828ab47cfaaSmrg case S3_SAVAGE3D: 4829ab47cfaaSmrg case S3_SAVAGE4: 4830ab47cfaaSmrg case S3_TWISTER: 4831ab47cfaaSmrg case S3_PROSAVAGE: 4832ab47cfaaSmrg case S3_PROSAVAGEDDR: 4833ab47cfaaSmrg OUTREG32(PRI_STREAM_STRIDE,0); 4834ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0,0); 4835ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR1,0); 4836ab47cfaaSmrg OUTREG8(CRT_ADDRESS_REG, 0x67); 4837ab47cfaaSmrg cr67 = INREG8(CRT_DATA_REG); 4838ab47cfaaSmrg cr67 &= ~0x0c; /* CR67[2] = 1 : enable stream 1 */ 4839ab47cfaaSmrg OUTREG8(CRT_DATA_REG, cr67); 4840ab47cfaaSmrg OUTREG8(CRT_ADDRESS_REG, 0x69); 4841ab47cfaaSmrg cr69 = INREG8(CRT_DATA_REG); 4842ab47cfaaSmrg cr69 &= ~0x80; /* CR69[0] = 1 : Mem-mapped regs */ 4843ab47cfaaSmrg OUTREG8(CRT_DATA_REG, cr69); 4844ab47cfaaSmrg break; 4845ab47cfaaSmrg case S3_SAVAGE2000: 4846ab47cfaaSmrg OUTREG32(PRI_STREAM_STRIDE,0); 4847ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000); 4848ab47cfaaSmrg OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000); 4849ab47cfaaSmrg OUTREG8(CRT_ADDRESS_REG, 0x67); 4850ab47cfaaSmrg cr67 = INREG8(CRT_DATA_REG); 4851ab47cfaaSmrg cr67 &= ~0x08; /* CR67[3] = 1 : Mem-mapped regs */ 4852ab47cfaaSmrg cr67 &= ~0x04; /* CR67[2] = 1 : enable stream 1 */ 4853ab47cfaaSmrg cr67 &= ~0x02; /* CR67[1] = 1 : enable stream 2 */ 4854ab47cfaaSmrg OUTREG8(CRT_DATA_REG, cr67); 4855ab47cfaaSmrg break; 4856ab47cfaaSmrg default: 4857ab47cfaaSmrg break; 4858ab47cfaaSmrg } 4859ab47cfaaSmrg 4860ab47cfaaSmrg} 4861