summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c815
1 files changed, 512 insertions, 303 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c
index 4227e11c7..ba7cf5adc 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.6 2000/12/12 16:50:48 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.11 2001/02/15 20:00:19 eich Exp $ */
/*
* vim: sw=4 ts=8 ai ic:
*
@@ -15,11 +15,13 @@
#include "xf86RAC.h"
#include "shadowfb.h"
-#ifdef DPMSExtension
#include "globals.h"
#define DPMS_SERVER
#include "extensions/dpms.h"
-#endif /* DPMSExtension */
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#endif
#include "savage_driver.h"
#include "savage_bci.h"
@@ -41,7 +43,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags);
static Bool SavageEnterVT(int scrnIndex, int flags);
static void SavageLeaveVT(int scrnIndex, int flags);
static void SavageSave(ScrnInfoPtr pScrn);
-static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr, SavageRegPtr);
+static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr, SavageRegPtr, Bool);
static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
char **argv);
@@ -49,9 +51,10 @@ static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen);
static ModeStatus SavageValidMode(int index, DisplayModePtr mode,
Bool verbose, int flags);
+void SavageDGAInit(ScreenPtr);
static Bool SavageMapMMIO(ScrnInfoPtr pScrn);
static Bool SavageMapFB(ScrnInfoPtr pScrn);
-static void SavageUnmapMem(ScrnInfoPtr pScrn);
+static void SavageUnmapMem(ScrnInfoPtr pScrn, int All);
static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool SavageSaveScreen(ScreenPtr pScreen, int mode);
@@ -64,24 +67,32 @@ static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1,
unsigned int *ndiv, unsigned int *r);
void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file);
void SavagePrintRegs(ScrnInfoPtr pScrn);
-#ifdef DPMSExtension
static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags);
-#endif
+static Bool SavageDDC1(int scrnIndex);
+static unsigned int SavageDDC1Read(ScrnInfoPtr pScrn);
+static void SavageProbeDDC(ScrnInfoPtr pScrn, int index);
-static int pix24bpp = 0;
+extern ScrnInfoPtr gpScrn;
#define iabs(a) ((int)(a)>0?(a):(-(a)))
#define DRIVER_NAME "savage"
-#define DRIVER_VERSION "1.1.0"
+#define DRIVER_VERSION "1.1.12"
#define VERSION_MAJOR 1
#define VERSION_MINOR 1
-#define PATCHLEVEL 0
+#define PATCHLEVEL 12
#define SAVAGE_VERSION ((VERSION_MAJOR << 24) | \
(VERSION_MINOR << 16) | \
PATCHLEVEL)
+/* #define TRACEON */
+#ifdef TRACEON
+#define TRACE(prms) ErrorF prms
+#else
+#define TRACE(prms)
+#endif
+
DriverRec SAVAGE =
{
SAVAGE_VERSION,
@@ -107,6 +118,9 @@ static SymTabRec SavageChips[] = {
{ PCI_CHIP_SAVAGE_IX, "Savage/IX" },
{ PCI_CHIP_PROSAVAGE_PM, "ProSavage PM133" },
{ PCI_CHIP_PROSAVAGE_KM, "ProSavage KM133" },
+ /* Twister is a code name; hope I get the real name soon. */
+ { PCI_CHIP_TWISTER_P, "TwisterP" },
+ { PCI_CHIP_TWISTER_K, "TwisterK" },
{ -1, NULL }
};
@@ -132,22 +146,18 @@ static PciChipsets SavagePciChipsets[] = {
{ S3_SAVAGE_MX, PCI_CHIP_SAVAGE_IX, RES_SHARED_VGA },
{ S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_PM, RES_SHARED_VGA },
{ S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_KM, RES_SHARED_VGA },
+ { S3_PROSAVAGE, PCI_CHIP_TWISTER_P, RES_SHARED_VGA },
+ { S3_PROSAVAGE, PCI_CHIP_TWISTER_K, RES_SHARED_VGA },
{ -1, -1, RES_UNDEFINED }
};
typedef enum {
- OPTION_SLOW_EDODRAM,
- OPTION_SLOW_DRAM,
- OPTION_FAST_DRAM,
- OPTION_FPM_VRAM,
OPTION_PCI_BURST,
OPTION_FIFO_CONSERV,
OPTION_FIFO_MODERATE,
OPTION_FIFO_AGGRESSIVE,
OPTION_PCI_RETRY,
OPTION_NOACCEL,
- OPTION_EARLY_RAS_PRECHARGE,
- OPTION_LATE_RAS_PRECHARGE,
OPTION_LCD_CENTER,
OPTION_LCDCLOCK,
OPTION_MCLK,
@@ -157,23 +167,23 @@ typedef enum {
OPTION_HWCURSOR,
OPTION_SHADOW_FB,
OPTION_ROTATE,
- OPTION_USEBIOS
+ OPTION_USEBIOS,
+ OPTION_STATUS_DELAY,
+ OPTION_STATUS_HACK
} SavageOpts;
static OptionInfoRec SavageOptions[] =
{
- { OPTION_SLOW_EDODRAM, "slow_edodram", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_SLOW_DRAM, "slow_dram", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_FAST_DRAM, "fast_dram", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_FPM_VRAM, "fpm_vram", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE },
- /* finish later... */
+ { OPTION_LCDCLOCK, "LCDClock", OPTV_FREQ, {0}, FALSE },
+ { OPTION_STATUS_DELAY, "StatusDelay", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_STATUS_HACK, "StatusHack", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -208,6 +218,7 @@ static const char *vbeSymbols[] = {
"VBEInit",
"vbeDoEDID",
"vbeFree",
+ "VBESetVBEMode",
NULL
};
@@ -216,6 +227,12 @@ static const char *ddcSymbols[] = {
NULL
};
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
static const char *xaaSymbols[] = {
"XAACopyROP",
"XAACopyROP_PM",
@@ -224,6 +241,7 @@ static const char *xaaSymbols[] = {
"XAAHelpPatternROP",
"XAAHelpSolidROP",
"XAAInit",
+ "XAAFillSolidRects",
"XAAScreenIndex",
NULL
};
@@ -242,14 +260,9 @@ static const char *int10Symbols[] = {
NULL
};
-static const char *cfbSymbols[] = {
- "cfbScreenInit",
- "cfb16ScreenInit",
- "cfb24ScreenInit",
- "cfb24_32ScreenInit",
- "cfb32ScreenInit",
- "cfb16BresS",
- "cfb24BresS",
+static const char *fbSymbols[] = {
+ "fbScreenInit",
+ "fbPictureInit",
NULL
};
@@ -280,9 +293,9 @@ static pointer SavageSetup(pointer module, pointer opts, int *errmaj,
if (!setupDone) {
setupDone = TRUE;
xf86AddDriver(&SAVAGE, module, 0);
- LoaderRefSymLists(vgaHWSymbols, cfbSymbols, ramdacSymbols,
+ LoaderRefSymLists(vgaHWSymbols, fbSymbols, ramdacSymbols,
xaaSymbols, shadowSymbols, vbeSymbols,
- ddcSymbols, NULL);
+ int10Symbols, i2cSymbols, ddcSymbols, NULL);
return (pointer) 1;
} else {
if (errmaj)
@@ -395,8 +408,6 @@ WaitIdleEmpty2K(SavagePtr psav)
{
int loop = 0;
mem_barrier();
- /* CAUTION! How do we insure this read isn't optimized away? */
- /* Is the "volatile" enough to do that? */
loop &= ALT_STATUS_WORD0;
while( ((ALT_STATUS_WORD0 & 0x009fffff) != 0) && (loop++ < MAXLOOP) )
;
@@ -482,11 +493,12 @@ static Bool SavageGetRec(ScrnInfoPtr pScrn)
static void SavageFreeRec(ScrnInfoPtr pScrn)
{
+ TRACE(( "SavageFreeRec(%x)\n", pScrn->driverPrivate ));
if (!pScrn->driverPrivate)
return;
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
- SavageUnmapMem(pScrn);
+ SavageUnmapMem(pScrn, 1);
}
@@ -499,7 +511,7 @@ static OptionInfoPtr SavageAvailableOptions(int chipid, int busid)
static void SavageIdentify(int flags)
{
xf86PrintChipsets("SAVAGE",
- "driver (version " DRIVER_VERSION " for S3 Savage chipsets",
+ "driver (version " DRIVER_VERSION ") for S3 Savage chipsets",
SavageChips);
}
@@ -507,7 +519,7 @@ static void SavageIdentify(int flags)
static Bool SavageProbe(DriverPtr drv, int flags)
{
int i;
- GDevPtr *devSections;
+ GDevPtr *devSections = NULL;
int *usedChips;
int numDevSections;
int numUsed;
@@ -523,7 +535,9 @@ static Bool SavageProbe(DriverPtr drv, int flags)
SavageChipsets, SavagePciChipsets,
devSections, numDevSections, drv,
&usedChips);
- xfree(devSections);
+ if (devSections)
+ xfree(devSections);
+ devSections = NULL;
if (numUsed <= 0)
return FALSE;
@@ -574,23 +588,28 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
MessageType from = X_DEFAULT;
int i;
ClockRangePtr clockRanges;
- char *mod = NULL;
char *s = NULL;
- const char *reqSym = NULL;
unsigned char config1, m, n, n1, n2, sr8, cr66 = 0, tmp;
int mclk;
vgaHWPtr hwp;
int vgaCRIndex, vgaCRReg, vgaIOBase;
+ pointer ddc;
- if (flags & PROBE_DETECT)
- return FALSE;
+ TRACE(("SavagePreInit(%d)\n", flags));
+
+ gpScrn = pScrn;
+
+ if (flags & PROBE_DETECT) {
+ SavageProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
+ return TRUE;
+ }
if (!xf86LoadSubModule(pScrn, "vgahw"))
- return FALSE;
+ return FALSE;
xf86LoaderReqSymLists(vgaHWSymbols, NULL);
if (!vgaHWGetHWRec(pScrn))
- return FALSE;
+ return FALSE;
#if 0
/* Here we can alter the number of registers saved and restored by the
@@ -609,24 +628,36 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support32bppFb))
return FALSE;
else {
+ int requiredBpp;
+
switch (pScrn->depth) {
case 8:
- case 15:
case 16:
+ requiredBpp = pScrn->depth;
+ break;
+ case 15:
+ requiredBpp = 16;
+ break;
case 24:
- /* OK */
+ requiredBpp = 32;
break;
+
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Given depth (%d) is not supported by this driver\n",
pScrn->depth);
return FALSE;
}
+
+ if( pScrn->bitsPerPixel != requiredBpp ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Depth %d must specify %d bpp; %d was given\n",
+ pScrn->depth, requiredBpp, pScrn->bitsPerPixel );
+ return FALSE;
+ }
}
- xf86PrintDepthBpp(pScrn);
- if (pScrn->depth == 24 && pix24bpp == 0)
- pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+ xf86PrintDepthBpp(pScrn);
if (pScrn->depth > 8) {
rgb zeros = {0, 0, 0};
@@ -664,11 +695,13 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, SavageOptions);
- if (xf86ReturnOptValBool(SavageOptions, OPTION_PCI_BURST, FALSE)) {
- psav->pci_burst = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_burst - PCI burst read enabled\n");
- } else
- psav->pci_burst = FALSE;
+ xf86GetOptValBool(SavageOptions, OPTION_PCI_BURST, &psav->pci_burst);
+
+ if (psav->pci_burst) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option: pci_burst - PCI burst read enabled\n");
+ }
+
psav->NoPCIRetry = 1; /* default */
if (xf86ReturnOptValBool(SavageOptions, OPTION_PCI_RETRY, FALSE)) {
if (xf86ReturnOptValBool(SavageOptions, OPTION_PCI_BURST, FALSE)) {
@@ -677,48 +710,26 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
} else
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"pci_retry\" option requires \"pci_burst\"\n");
}
- if (xf86IsOptionSet(SavageOptions, OPTION_FIFO_CONSERV)) {
- psav->fifo_conservative = TRUE;
+
+ xf86GetOptValBool( SavageOptions, OPTION_FIFO_CONSERV, &psav->fifo_conservative );
+ if (psav->fifo_conservative) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo conservative set\n");
- } else
- psav->fifo_conservative = FALSE;
- if (xf86IsOptionSet(SavageOptions, OPTION_FIFO_MODERATE)) {
- psav->fifo_moderate = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_moderate set\n");
- } else
- psav->fifo_moderate = FALSE;
- if (xf86IsOptionSet(SavageOptions, OPTION_FIFO_AGGRESSIVE)) {
- psav->fifo_aggressive = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_aggressive set\n");
- } else
- psav->fifo_aggressive = FALSE;
- if (xf86IsOptionSet(SavageOptions, OPTION_SLOW_EDODRAM)) {
- psav->slow_edodram = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: slow_edodram_set\n");
- } else
- psav->slow_edodram = FALSE;
- if (xf86IsOptionSet(SavageOptions, OPTION_SLOW_DRAM)) {
- psav->slow_dram = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: slow_dram set\n");
- } else
- psav->slow_dram = FALSE;
- if (xf86IsOptionSet(SavageOptions, OPTION_FAST_DRAM)) {
- psav->fast_dram = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fast_dram set\n");
- } else
- psav->fast_dram = FALSE;
- if (xf86IsOptionSet(SavageOptions, OPTION_FPM_VRAM)) {
- psav->fpm_vram = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fpm_vram set\n");
- } else
- psav->fpm_vram = FALSE;
+ }
- if (xf86IsOptionSet(SavageOptions, OPTION_SHADOW_FB)) {
- psav->shadowFB = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: ShadowFB %s.\n",
- psav->shadowFB ? "enabled" : "disabled");
- } else
- psav->shadowFB = FALSE;
+ xf86GetOptValBool( SavageOptions, OPTION_FIFO_CONSERV, &psav->fifo_moderate );
+ if (psav->fifo_moderate) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo moderate set\n");
+ }
+
+ xf86GetOptValBool( SavageOptions, OPTION_FIFO_CONSERV, &psav->fifo_aggressive );
+ if (psav->fifo_aggressive) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo aggressive set\n");
+ }
+
+ xf86GetOptValBool( SavageOptions, OPTION_SHADOW_FB, &psav->shadowFB );
+ if (psav->shadowFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: shadow FB enabled\n");
+ }
if ((s = xf86GetOptValString(SavageOptions, OPTION_ROTATE))) {
if(!xf86NameCmp(s, "CW")) {
@@ -740,11 +751,9 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
}
}
- if (xf86ReturnOptValBool(SavageOptions, OPTION_NOACCEL, FALSE)) {
- psav->NoAccel = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - Acceleration Disabled\n");
- } else
- psav->NoAccel = FALSE;
+ if (xf86GetOptValBool(SavageOptions, OPTION_NOACCEL, &psav->NoAccel))
+ xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
+ "Option: NoAccel - Acceleration Disabled\n");
if (psav->shadowFB && !psav->NoAccel) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -752,19 +761,14 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->NoAccel = TRUE;
}
- if (xf86ReturnOptValBool(SavageOptions, OPTION_EARLY_RAS_PRECHARGE, FALSE)) {
- psav->early_ras_precharge = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: early_ras_precharge set\n");
- } else
- psav->early_ras_precharge = FALSE;
-
/*
* The SWCursor setting takes priority over HWCursor. The default
- * if neither is specified is HW.
+ * if neither is specified is HW, unless ShadowFB is specified,
+ * then SW.
*/
from = X_DEFAULT;
- psav->hwcursor = TRUE;
+ psav->hwcursor = psav->shadowFB ? FALSE : TRUE;
if (xf86GetOptValBool(SavageOptions, OPTION_HWCURSOR, &psav->hwcursor))
from = X_CONFIG;
if (xf86ReturnOptValBool(SavageOptions, OPTION_SWCURSOR, FALSE)) {
@@ -776,20 +780,27 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
from = X_DEFAULT;
psav->UseBIOS = TRUE;
- if (xf86IsOptionSet(SavageOptions, OPTION_USEBIOS) )
- {
+ if (xf86GetOptValBool(SavageOptions, OPTION_USEBIOS, &psav->UseBIOS) )
from = X_CONFIG;
- xf86GetOptValBool(SavageOptions, OPTION_USEBIOS, &psav->UseBIOS);
- }
xf86DrvMsg(pScrn->scrnIndex, from, "%ssing video BIOS to set modes\n",
psav->UseBIOS ? "U" : "Not u" );
+ psav->LCDClock = 0.0;
+ if( xf86GetOptValFreq( SavageOptions, OPTION_LCDCLOCK, OPTUNITS_MHZ, &psav->LCDClock ) )
+ xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
+ "Option: LCDClock %1.2f MHz\n", psav->LCDClock );
- /* DO OTHERS HERE LATER!!!!!!!!!!!!!! */
+ psav->StatusDelay = 0;
+ if( xf86GetOptValInteger( SavageOptions, OPTION_STATUS_DELAY, &psav->StatusDelay ) )
+ xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
+ "Option: StatusDelay %d microseconds\n", psav->StatusDelay );
- from = X_DEFAULT;
+ if( xf86GetOptValBool( SavageOptions, OPTION_STATUS_HACK, &psav->StatusHack))
+ xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
+ "Option: StatusHack enabled\n" );
+ /* Add more options here. */
if (pScrn->numEntities > 1) {
SavageFreeRec(pScrn);
@@ -804,23 +815,23 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
}
psav->EntityIndex = pEnt->index;
- if (psav->UseBIOS) {
- if (xf86LoadSubModule(pScrn, "int10")) {
- xf86LoaderReqSymLists(int10Symbols, NULL);
- psav->pInt10 = xf86InitInt10(pEnt->index);
- }
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+ psav->pInt10 = xf86InitInt10(pEnt->index);
+ }
- if (xf86LoadSubModule(pScrn, "vbe")) {
- xf86LoaderReqSymLists(vbeSymbols, NULL);
- psav->pVbe = VBEInit(psav->pInt10, pEnt->index);
- }
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ psav->pVbe = VBEInit(psav->pInt10, pEnt->index);
}
+
psav->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
xf86RegisterResources(pEnt->index, NULL, ResNone);
xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr);
xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr);
+ from = X_DEFAULT;
if (pEnt->device->chipset && *pEnt->device->chipset) {
pScrn->chipset = pEnt->device->chipset;
psav->ChipId = pEnt->device->chipID;
@@ -842,6 +853,9 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->Chipset);
}
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Chip: id %04x, \"%s\"\n",
+ psav->ChipId, xf86TokenToString( SavageChips, psav->ChipId ) );
+
if (pEnt->device->chipRev >= 0) {
psav->ChipRev = pEnt->device->chipRev;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
@@ -853,7 +867,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
/* maybe throw in some more sanity checks here */
- xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+ xf86DrvMsg(pScrn->scrnIndex, from, "Engine: \"%s\"\n", pScrn->chipset);
psav->PciTag = pciTag(psav->PciInfo->bus, psav->PciInfo->device,
psav->PciInfo->func);
@@ -876,7 +890,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
/* unlock extended regs */
VGAOUT16(vgaCRIndex, 0x4838);
- VGAOUT16(vgaCRIndex, 0xa539);
+ VGAOUT16(vgaCRIndex, 0xa039);
VGAOUT16(0x3c4, 0x0608);
VGAOUT8(vgaCRIndex, 0x40);
@@ -917,6 +931,18 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
break;
case S3_SAVAGE4:
+ /*
+ * The Savage4 has one ugly special case to consider. On
+ * systems with 4 banks of 2Mx32 SDRAM, the BIOS says 4MB
+ * when it really means 8MB. Why do it the same when you
+ * can do it different...
+ */
+ VGAOUT8(vgaCRIndex, 0x68); /* memory control 1 */
+ if( (VGAIN8(vgaCRReg) & 0xC0) == (0x01 << 6) )
+ RamSavage4[1] = 8;
+
+ /*FALLTHROUGH*/
+
case S3_SAVAGE2000:
pScrn->videoRam = RamSavage4[ (config1 & 0xE0) >> 5 ] * 1024;
break;
@@ -1002,7 +1028,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
VGAOUT8(vgaCRReg, cr66 & ~0x02); /* clear reset flag */
usleep(10000);
- /* Set status word positions based on chip type. */
+ /* Set status word positions based on chip type. */
switch( psav->Chipset ) {
case S3_SAVAGE3D:
@@ -1028,8 +1054,42 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->myWaitCommandEmpty = WaitCommandEmpty2K;
break;
}
-
- /* savage ramdac speeds */
+
+ /* Do the DDC dance. */
+
+ ddc = xf86LoadSubModule(pScrn, "ddc");
+ if (ddc) {
+#if 0
+ xf86MonPtr pMon = NULL;
+#endif
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+#if 0
+/*
+ * On many machines, the attempt to read DDC information via VBE puts the
+ * BIOS access into a state which prevents me from reading mode information.
+ * This is a complete mystery to me.
+ */
+ if ((psav->pVbe)
+ && ((pMon = xf86PrintEDID(vbeDoEDID(psav->pVbe, ddc))) != NULL))
+ xf86SetDDCproperties(pScrn,pMon);
+ else
+#endif
+ if (!SavageDDC1(pScrn->scrnIndex)) {
+ if ( xf86LoadSubModule(pScrn, "i2c") ) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ if (SavageI2CInit(pScrn)) {
+ CARD32 tmp = (INREG(DDC_REG));
+ OUTREG(DDC_REG,(tmp | 0x13));
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(
+ xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C)));
+ OUTREG(DDC_REG,tmp);
+ }
+ }
+ }
+ }
+
+ /* Savage ramdac speeds */
pScrn->numClocks = 4;
pScrn->clock[0] = 250000;
pScrn->clock[1] = 250000;
@@ -1047,7 +1107,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->dacSpeedBpp = pScrn->clock[0];
}
- /* set ramdac limits */
+ /* Set ramdac limits */
psav->maxClock = psav->dacSpeedBpp;
/* detect current mclk */
@@ -1067,25 +1127,99 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected current MCLK value of %1.3f MHz\n",
mclk / 1000.0);
- psav->minClock = 20000;
+ psav->minClock = 10000;
- pScrn->maxHValue = 2048;
- pScrn->maxVValue = 2048;
+ pScrn->maxHValue = 2048 << 3; /* 11 bits of h_total 8-pixel units */
+ pScrn->maxVValue = 2048; /* 11 bits of v_total */
pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+
+ /* Check LCD panel information */
+
+ if( psav->Chipset == S3_SAVAGE_MX )
+ {
+ unsigned char cr6b = hwp->readCrtc( hwp, 0x6b );
+
+ int panelX = (hwp->readSeq(hwp, 0x61) +
+ ((hwp->readSeq(hwp, 0x66) & 0x02) << 7) + 1) * 8;
+ int panelY = hwp->readSeq(hwp, 0x69) +
+ ((hwp->readSeq(hwp, 0x6e) & 0x70) << 4) + 1;
+
+ char * sTechnology = "Unknown";
+
+ /* OK, I admit it. I don't know how to limit the max dot clock
+ * for LCD panels of various sizes. I thought I copied the formula
+ * from the BIOS, but many users have informed me of my folly.
+ *
+ * Instead, I'll abandon any attempt to automatically limit the
+ * clock, and add an LCDClock option to XF86Config. Some day,
+ * I should come back to this.
+ */
+
+ enum ACTIVE_DISPLAYS { /* These are the bits in CR6B */
+ ActiveCRT = 0x01,
+ ActiveLCD = 0x02,
+ ActiveTV = 0x04,
+ ActiveCRT2 = 0x20,
+ ActiveDUO = 0x80
+ };
+
+ if( (hwp->readSeq( hwp, 0x39 ) & 0x03) == 0 )
+ {
+ sTechnology = "TFT";
+ }
+ else if( (hwp->readSeq( hwp, 0x30 ) & 0x01) == 0 )
+ {
+ sTechnology = "DSTN";
+ }
+ else
+ {
+ sTechnology = "STN";
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%dx%d %s LCD panel detected %s\n",
+ panelX, panelY, sTechnology,
+ cr6b & ActiveLCD ? "and active" : "but not active");
+ if( cr6b & ActiveLCD ) {
+ /* If the LCD is active and panel expansion is enabled, */
+ /* we probably want to kill the HW cursor. */
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "- Limiting video mode to %dx%d\n",
+ panelX, panelY );
+
+ if( pScrn->virtualX > panelX )
+ pScrn->virtualX = panelX;
+ if( pScrn->virtualY > panelY )
+ pScrn->virtualY = panelY;
+
+ if( psav->LCDClock > 0.0 )
+ {
+ psav->maxClock = psav->LCDClock * 1000.0;
+ xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
+ "- Limiting dot clock to %1.2f MHz\n",
+ psav->LCDClock );
+ }
+ }
+ }
+
clockRanges = xnfalloc(sizeof(ClockRange));
clockRanges->next = NULL;
clockRanges->minClock = psav->minClock;
clockRanges->maxClock = psav->maxClock;
clockRanges->clockIndex = -1;
clockRanges->interlaceAllowed = TRUE;
- clockRanges->doubleScanAllowed = FALSE;
+ clockRanges->doubleScanAllowed = TRUE;
+ clockRanges->ClockDivFactor = 1.0;
+ clockRanges->ClockMulFactor = 1.0;
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
pScrn->display->modes, clockRanges, NULL,
256, 2048, 16 * pScrn->bitsPerPixel,
128, 2048,
- pScrn->virtualX, pScrn->display->virtualY,
+ pScrn->virtualX, pScrn->virtualY,
psav->videoRambytes, LOOKUP_BEST_REFRESH);
if (i == -1) {
@@ -1111,15 +1245,14 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
SavageFreeBIOSModeTable( psav, &psav->ModeTable );
}
- psav->ModeTable = SavageGetBIOSModeTable( psav, pScrn->depth );
+ psav->ModeTable = SavageGetBIOSModeTable( psav, pScrn->bitsPerPixel );
if( !psav->ModeTable || !psav->ModeTable->NumModes ) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to fetch any BIOS modes.\n");
- SavageFreeRec(pScrn);
- return FALSE;
+ "Failed to fetch any BIOS modes. Disabling BIOS.\n");
+ psav->UseBIOS = FALSE;
}
-
+ else
/*if( xf86Verbose )*/
{
int i;
@@ -1151,28 +1284,12 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86PrintModes(pScrn);
xf86SetDpi(pScrn, 0, 0);
- /* load bpp-specific modules */
- switch (pScrn->bitsPerPixel) {
- case 8:
- mod = "cfb";
- reqSym = "cfbScreenInit";
- break;
- case 16:
- mod = "cfb16";
- reqSym = "cfb16ScreenInit";
- break;
- case 32:
- mod = "cfb32";
- reqSym = "cfb32ScreenInit";
- break;
- }
-
- if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ if (xf86LoadSubModule(pScrn, "fb") == NULL) {
SavageFreeRec(pScrn);
return FALSE;
}
- xf86LoaderReqSymbols(reqSym, NULL);
+ xf86LoaderReqSymbols("fbScreenInit", NULL);
if( !psav->NoAccel ) {
if( !xf86LoadSubModule(pScrn, "xaa") ) {
@@ -1205,7 +1322,10 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
static Bool SavageEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TRACE(("SavageEnterVT(%d)\n", flags));
+ gpScrn = pScrn;
+ SavageEnableMMIO(pScrn);
SavageSave(pScrn);
return SavageModeInit(pScrn, pScrn->currentMode);
}
@@ -1219,7 +1339,10 @@ static void SavageLeaveVT(int scrnIndex, int flags)
vgaRegPtr vgaSavePtr = &hwp->SavedReg;
SavageRegPtr SavageSavePtr = &psav->SavedReg;
- SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr);
+ TRACE(("SavageLeaveVT(%d)\n", flags));
+ gpScrn = pScrn;
+ SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
+ SavageDisableMMIO(pScrn);
}
@@ -1235,9 +1358,10 @@ static void SavageSave(ScrnInfoPtr pScrn)
vgaCRReg = vgaIOBase + 5;
vgaCRIndex = vgaIOBase + 4;
+ TRACE(("SavageSave()\n"));
VGAOUT16(vgaCRIndex, 0x4838);
- VGAOUT16(vgaCRIndex, 0xa539);
+ VGAOUT16(vgaCRIndex, 0xa039);
VGAOUT16(0x3c4, 0x0608);
VGAOUT8(vgaCRIndex, 0x66);
@@ -1371,10 +1495,12 @@ static void SavageSave(ScrnInfoPtr pScrn)
VGAOUT8(vgaCRReg, cr3a | 0x80);
/* now save MIU regs */
- save->MMPR0 = INREG(FIFO_CONTROL_REG);
- save->MMPR1 = INREG(MIU_CONTROL_REG);
- save->MMPR2 = INREG(STREAMS_TIMEOUT_REG);
- save->MMPR3 = INREG(MISC_TIMEOUT_REG);
+ if( psav->Chipset != S3_SAVAGE_MX ) {
+ save->MMPR0 = INREG(FIFO_CONTROL_REG);
+ save->MMPR1 = INREG(MIU_CONTROL_REG);
+ save->MMPR2 = INREG(STREAMS_TIMEOUT_REG);
+ save->MMPR3 = INREG(MISC_TIMEOUT_REG);
+ }
VGAOUT8(vgaCRIndex, 0x3a);
VGAOUT8(vgaCRReg, cr3a);
@@ -1397,18 +1523,19 @@ static void SavageSave(ScrnInfoPtr pScrn)
static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
- SavageRegPtr restore)
+ SavageRegPtr restore, Bool Entering)
{
unsigned char tmp, cr3a, cr66, cr67;
vgaHWPtr hwp = VGAHWPTR(pScrn);
SavagePtr psav = SAVPTR(pScrn);
int vgaCRIndex, vgaCRReg, vgaIOBase;
- Bool graphicsMode = FALSE;
vgaIOBase = hwp->IOBase;
vgaCRIndex = vgaIOBase + 4;
vgaCRReg = vgaIOBase + 5;
+
+ TRACE(("SavageWriteMode(%x)\n", restore->mode));
/*
* If we figured out a VESA mode number for this timing, just use
@@ -1447,15 +1574,18 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
/* Disable old MMIO. */
VGAOUT8(vgaCRIndex, 0x53);
- tmp = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, tmp & ~0x10);
+ VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) & ~0x10);
+
+ /* Set the color mode. */
+
+ VGAOUT8(vgaCRIndex, 0x67);
+ VGAOUT8(vgaCRReg, restore->CR67);
/* We may need TV/panel fixups here. See s3bios.c line 2904. */
/* Set FIFO fetch delay. */
VGAOUT8(vgaCRIndex, 0x85);
- tmp = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, (tmp & 0xf8) | 0x03);
+ VGAOUT8(vgaCRReg, (VGAIN8(vgaCRReg) & 0xf8) | 0x03);
/* Patch CR79. These values are magical. */
@@ -1516,16 +1646,11 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
/* Enable the graphics engine. */
VGAOUT16(vgaCRIndex, 0x0140);
- #if 0
- if( !psav->NoAccel )
- S3SAVInitialize2DEngine();
- #endif
/* Handle the pitch. */
VGAOUT8(vgaCRIndex, 0x50);
- tmp = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, tmp | 0xC1);
+ VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1);
width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3;
VGAOUT16(vgaCRIndex, ((width & 0xff) << 8) | 0x13 );
@@ -1533,22 +1658,23 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
/* Some non-S3 BIOSes enable block write even on non-SGRAM devices. */
- if( psav->Chipset == S3_SAVAGE2000 )
- {
- VGAOUT8(vgaCRIndex, 0x73);
- tmp = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, tmp & 0xdf );
- }
- else if( psav->Chipset != S3_SAVAGE_MX )
+ switch( psav->Chipset )
{
- VGAOUT8(vgaCRIndex, 0x68);
- if( !(VGAIN8(vgaCRReg) & 0x80) )
- {
- /* Not SGRAM; disable block write. */
- VGAOUT8(vgaCRIndex, 0x88);
- tmp = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, tmp | 0x10);
- }
+ case S3_SAVAGE2000:
+ VGAOUT8(vgaCRIndex, 0x73);
+ VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) & 0xdf );
+ break;
+
+ case S3_SAVAGE3D:
+ case S3_SAVAGE4:
+ VGAOUT8(vgaCRIndex, 0x68);
+ if( !(VGAIN8(vgaCRReg) & 0x80) )
+ {
+ /* Not SGRAM; disable block write. */
+ VGAOUT8(vgaCRIndex, 0x88);
+ VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0x10);
+ }
+ break;
}
if( !psav->NoAccel )
@@ -1563,7 +1689,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(0x3c2, 0x23);
VGAOUT16(vgaCRIndex, 0x4838);
- VGAOUT16(vgaCRIndex, 0xa539);
+ VGAOUT16(vgaCRIndex, 0xa039);
VGAOUT16(0x3c4, 0x0608);
vgaHWProtect(pScrn, TRUE);
@@ -1571,8 +1697,6 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
/* will we be reenabling STREAMS for the new mode? */
psav->STREAMSRunning = 0;
- graphicsMode = (restore->CR31 & 0x0a) ? TRUE : FALSE;
-
/* reset GE to make sure nothing is going on */
VGAOUT8(vgaCRIndex, 0x66);
if(VGAIN8(vgaCRReg) & 0x01)
@@ -1585,14 +1709,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
* switch to mode 3 here seems to eliminate the issue.
*/
-#define CLEAR_X86_REGS(pi) \
- (pi)->ax = (pi)->bx = (pi)->cx = (pi)->dx = (pi)->si = (pi)->di = 0
-
- if( !graphicsMode && psav->pInt10 ) {
- CLEAR_X86_REGS( psav->pInt10 );
- psav->pInt10->num = 0x10;
- psav->pInt10->ax = 0x0083;
- xf86ExecX86int10( psav->pInt10 );
+ if( ((restore->CR31 & 0x0a) == 0) && psav->pInt10 ) {
+ SavageSetTextMode( psav );
}
VGAOUT8(vgaCRIndex, 0x67);
@@ -1758,26 +1876,28 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
cr3a = VGAIN8(vgaCRReg);
VGAOUT8(vgaCRReg, cr3a | 0x80);
- if (graphicsMode)
+ if (psav->Entering)
SavageGEReset(pScrn,0,__LINE__,__FILE__);
- VerticalRetraceWait();
- OUTREG(FIFO_CONTROL_REG, restore->MMPR0);
- WaitIdle();
- OUTREG(MIU_CONTROL_REG, restore->MMPR1);
- WaitIdle();
- OUTREG(STREAMS_TIMEOUT_REG, restore->MMPR2);
- WaitIdle();
- OUTREG(MISC_TIMEOUT_REG, restore->MMPR3);
+ if( psav->Chipset != S3_SAVAGE_MX )
+ {
+ VerticalRetraceWait();
+ OUTREG(FIFO_CONTROL_REG, restore->MMPR0);
+ WaitIdle();
+ OUTREG(MIU_CONTROL_REG, restore->MMPR1);
+ WaitIdle();
+ OUTREG(STREAMS_TIMEOUT_REG, restore->MMPR2);
+ WaitIdle();
+ OUTREG(MISC_TIMEOUT_REG, restore->MMPR3);
+ }
/* If we're going into graphics mode and acceleration was enabled, */
/* go set up the BCI buffer and the global bitmap descriptor. */
- if( graphicsMode && (!psav->NoAccel) )
+ if( psav->Entering && (!psav->NoAccel) )
{
VGAOUT8(vgaCRIndex, 0x50);
- tmp = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, tmp | 0xC1);
+ VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1);
SavageInitialize2DEngine(pScrn);
}
@@ -1786,7 +1906,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(vgaCRIndex, 0x3a);
VGAOUT8(vgaCRReg, cr3a);
- if( graphicsMode )
+ if( psav->Entering )
SavageSetGBD(pScrn);
vgaHWProtect(pScrn, FALSE);
@@ -1800,6 +1920,8 @@ static Bool SavageMapMMIO(ScrnInfoPtr pScrn)
SavagePtr psav;
vgaHWPtr hwp;
+ TRACE(("SavageMapMMIO()\n"));
+
psav = SAVPTR(pScrn);
if( S3_SAVAGE3D_SERIES(psav->Chipset) ) {
@@ -1845,6 +1967,8 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn)
{
SavagePtr psav = SAVPTR(pScrn);
+ TRACE(("SavageMapFB()\n"));
+
xf86DrvMsg( pScrn->scrnIndex, X_PROBED,
"mapping framebuffer @ 0x%x with size 0x%x\n",
psav->FrameBufferBase, psav->videoRambytes);
@@ -1868,24 +1992,33 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn)
}
-static void SavageUnmapMem(ScrnInfoPtr pScrn)
+static void SavageUnmapMem(ScrnInfoPtr pScrn, int All)
{
SavagePtr psav;
psav = SAVPTR(pScrn);
+ TRACE(("SavageUnmapMem(%x,%x)\n", psav->MapBase, psav->FBBase));
+
if (psav->PrimaryVidMapped) {
vgaHWUnmapMem(pScrn);
psav->PrimaryVidMapped = FALSE;
}
SavageDisableMMIO(pScrn);
- if (psav->MapBase)
+
+ if (All && psav->MapBase) {
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->MapBase,
SAVAGE_NEWMMIO_REGSIZE);
- if (psav->FBBase)
+ psav->MapBase = 0;
+ }
+
+ if (psav->FBBase) {
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->FBBase,
psav->videoRambytes);
+ psav->FBBase = 0;
+ }
+
#if 0
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)psav->MapBaseDense,
0x8000);
@@ -1902,9 +2035,13 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
SavagePtr psav;
int ret;
+ TRACE(("SavageScreenInit()\n"));
+
pScrn = xf86Screens[pScreen->myNum];
psav = SAVPTR(pScrn);
+ SavageEnableMMIO(pScrn);
+
if (!SavageMapFB(pScrn))
return FALSE;
@@ -1921,10 +2058,18 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
pScrn->rgbBits, pScrn->defaultVisual))
return FALSE;
+#if 0
+ if (!miSetPixmapDepths ())
+ return FALSE;
+#endif
} else {
if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
pScrn->rgbBits, pScrn->defaultVisual))
return FALSE;
+#if 0
+ if (!miSetPixmapDepths ())
+ return FALSE;
+#endif
}
ret = SavageInternalScreenInit(scrnIndex, pScreen);
@@ -1956,9 +2101,8 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
-#if 0
- SavageDGAInit(pScreen);
-#endif
+ if( !psav->numDGAModes )
+ SavageDGAInit(pScreen);
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
@@ -2002,9 +2146,12 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
pScreen->SaveScreen = SavageSaveScreen;
pScreen->CloseScreen = SavageCloseScreen;
-#ifdef DPMSExtension
if (xf86DPMSInit(pScreen, SavageDPMS, 0) == FALSE)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed\n");
+
+#ifdef XvExtension
+ if( !psav->NoAccel )
+ SavageInitVideo( pScreen );
#endif
if (serverGeneration == 1)
@@ -2022,6 +2169,8 @@ static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen)
int width, height, displayWidth;
unsigned char *FBStart;
+ TRACE(("SavageInternalScreenInit()\n"));
+
pScrn = xf86Screens[pScreen->myNum];
psav = SAVPTR(pScrn);
@@ -2046,29 +2195,12 @@ static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen)
FBStart = psav->FBStart;
}
- switch (pScrn->bitsPerPixel) {
- case 8:
- ret = cfbScreenInit(pScreen, FBStart, width, height,
- pScrn->xDpi, pScrn->yDpi,
- displayWidth);
- break;
- case 16:
- ret = cfb16ScreenInit(pScreen, FBStart, width, height,
- pScrn->xDpi, pScrn->yDpi,
- displayWidth);
- break;
- case 32:
- ret = cfb32ScreenInit(pScreen, FBStart, width, height,
- pScrn->xDpi, pScrn->yDpi,
- displayWidth);
- break;
- default:
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Internal error: invalid bpp (%d) in SavageScreenInit\n",
- pScrn->bitsPerPixel);
- ret = FALSE;
- break;
- }
+ ret = fbScreenInit(pScreen, FBStart, width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth,
+ pScrn->bitsPerPixel);
+ if (ret)
+ fbPictureInit (pScreen, 0, 0);
return ret;
}
@@ -2078,6 +2210,7 @@ static ModeStatus SavageValidMode(int index, DisplayModePtr mode,
Bool verbose, int flags)
{
/* TODO check modes */
+ TRACE(("SavageValidMode\n"));
return MODE_OK;
}
@@ -2096,6 +2229,9 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
vgaCRIndex = vgaIOBase + 4;
vgaCRReg = vgaIOBase + 5;
+ TRACE(("SavageModeInit(%dx%d, %dHz)\n",
+ mode->HDisplay, mode->VDisplay, mode->Clock));
+
#if 0
ErrorF("Clock = %d, HDisplay = %d, HSStart = %d\n",
mode->Clock, mode->HDisplay, mode->HSyncStart);
@@ -2139,6 +2275,35 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
new->mode = 0;
+ /* We need to set CR67 whether or not we use the BIOS. */
+
+ dclk = mode->Clock;
+ new->CR67 = 0x00;
+
+ switch( pScrn->depth ) {
+ case 8:
+ if( (dclk <= 110000) && (psav->Chipset != S3_SAVAGE_MX) )
+ new->CR67 = 0x10; /* 8bpp, 135Mhz */
+ else
+ new->CR67 = 0x00; /* 8bpp, 220Mhz */
+ break;
+ case 15:
+ if( (dclk <= 110000) && (psav->Chipset != S3_SAVAGE_MX) )
+ new->CR67 = 0x20; /* 15bpp, 135Mhz */
+ else
+ new->CR67 = 0x30; /* 15bpp, 220Mhz */
+ break;
+ case 16:
+ if( (dclk <= 110000) && (psav->Chipset != S3_SAVAGE_MX) )
+ new->CR67 = 0x40; /* 16bpp, 135Mhz */
+ else
+ new->CR67 = 0x50; /* 16bpp, 220Mhz */
+ break;
+ case 24:
+ new->CR67 = 0xd0;
+ break;
+ }
+
if( psav->UseBIOS ) {
int refresh;
SavageModeEntryPtr pmt;
@@ -2222,8 +2387,6 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
new->CR55 |= 0x10;
#endif
- dclk = mode->Clock;
- new->CR67 = 0x00;
new->SR15 = 0x03 | 0x80;
new->SR18 = 0x00;
new->CR43 = new->CR45 = new->CR65 = 0x00;
@@ -2250,31 +2413,6 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
psav->NeedSTREAMS = FALSE;
- /****
- * TODO
- * old code uses the "dclk<=110000" path for all non-MX/IX, and the
- * >110000 path for MX/IX. What does this mean?
- ****/
-
- if (pScrn->bitsPerPixel == 8) {
- if (dclk <= 110000)
- new->CR67 = 0x00; /* 8bpp, 135Mhz */
- else
- new->CR67 = 0x10; /* 8bpp, 220Mhz */
- } else if ((pScrn->bitsPerPixel == 16) && (pScrn->weight.green == 5)) {
- if (dclk <= 110000)
- new->CR67 = 0x20; /* 15bpp, 135Mhz */
- else
- new->CR67 = 0x30; /* 15bpp, 220Mhz */
- } else if (pScrn->bitsPerPixel == 16) {
- if (dclk <= 110000)
- new->CR67 = 0x40; /* 16bpp, 135Mhz */
- else
- new->CR67 = 0x50; /* 16bpp, 220Mhz */
- } else if (pScrn->bitsPerPixel == 32) {
- new->CR67 = 0xd0;
- }
-
SavageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000,
&m, &n, &r);
new->SR12 = (r << 6) | (n & 0x3f);
@@ -2342,17 +2480,17 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
else
new->CR50 = 0x30;
- if (pScrn->displayWidth <= 640)
+ if (pScrn->displayWidth == 640)
new->CR50 |= 0x40;
- else if (pScrn->displayWidth <= 800)
+ else if (pScrn->displayWidth == 800)
new->CR50 |= 0x80;
- else if (pScrn->displayWidth <= 1024)
+ else if (pScrn->displayWidth == 1024)
new->CR50 |= 0x00;
- else if (pScrn->displayWidth <= 1152)
+ else if (pScrn->displayWidth == 1152)
new->CR50 |= 0x01;
- else if (pScrn->displayWidth <= 1280)
+ else if (pScrn->displayWidth == 1280)
new->CR50 |= 0xc0;
- else if (pScrn->displayWidth <= 1600)
+ else if (pScrn->displayWidth == 1600)
new->CR50 |= 0x81;
else
new->CR50 |= 0xc1; /* Use GBD */
@@ -2382,7 +2520,7 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
pScrn->vtSema = TRUE;
/* do it! */
- SavageWriteMode(pScrn, vganew, new);
+ SavageWriteMode(pScrn, vganew, new, TRUE);
SavageAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
return TRUE;
@@ -2397,28 +2535,17 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
vgaRegPtr vgaSavePtr = &hwp->SavedReg;
SavageRegPtr SavageSavePtr = &psav->SavedReg;
+ TRACE(("SavageCloseScreen\n"));
+
if( psav->AccelInfoRec ) {
XAADestroyInfoRec( psav->AccelInfoRec );
psav->AccelInfoRec = NULL;
}
-#if 0
- if( psav->pInt10 ) {
- xf86FreeInt10( psav->pInt10 );
- psav->pInt10 = NULL;
- }
-
- if (psav->pVbe)
- {
- vbeFree(psav->pVbe);
- psav->pVbe = NULL;
- }
-#endif
-
if (pScrn->vtSema) {
- SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr);
+ SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
vgaHWLock(hwp);
- SavageUnmapMem(pScrn);
+ SavageUnmapMem(pScrn, 0);
}
pScrn->vtSema = FALSE;
@@ -2430,6 +2557,17 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
static Bool SavageSaveScreen(ScreenPtr pScreen, int mode)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRACE(("SavageSaveScreen(0x%x)\n", mode));
+
+ if( SAVPTR(pScrn)->hwcursor )
+ {
+ if( xf86IsUnblank(mode) )
+ SavageShowCursor( pScrn );
+ else
+ SavageHideCursor( pScrn );
+ }
+
return vgaHWSaveScreen(pScreen, mode);
}
@@ -2445,10 +2583,12 @@ void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
vgaCRIndex = vgaIOBase + 4;
vgaCRReg = vgaIOBase + 5;
+ TRACE(("SavageAdjustFrame(%d,%d,%x)\n", x, y, flags));
+
if (psav->ShowCache && y)
y += pScrn->virtualY - 1;
- Base = ((y * pScrn->displayWidth + x) *
+ Base = ((y * pScrn->displayWidth + (x&~1)) *
(pScrn->bitsPerPixel / 8)) >> 2;
/* now program the start address registers */
VGAOUT16(vgaCRIndex, (Base & 0x00ff00) | 0x0c);
@@ -2462,6 +2602,7 @@ void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
Bool SavageSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
+ TRACE(("SavageSwitchMode\n"));
return SavageModeInit(xf86Screens[scrnIndex], mode);
}
@@ -2473,6 +2614,9 @@ void SavageEnableMMIO(ScrnInfoPtr pScrn)
int vgaCRIndex, vgaCRReg;
unsigned char val;
+ TRACE(("SavageEnableMMIO\n"));
+
+ vgaHWSetStdFuncs(hwp);
vgaHWSetMmioFuncs(hwp, psav->MapBase, 0x8000);
val = VGAIN8(0x3c3);
VGAOUT8(0x3c3, val | 0x01);
@@ -2482,9 +2626,12 @@ void SavageEnableMMIO(ScrnInfoPtr pScrn)
vgaCRIndex = hwp->IOBase + 4;
vgaCRReg = hwp->IOBase + 5;
- VGAOUT8(vgaCRIndex, 0x40);
- val = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, val | 1);
+ if( psav->Chipset >= S3_SAVAGE4 )
+ {
+ VGAOUT8(vgaCRIndex, 0x40);
+ val = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, val | 1);
+ }
return;
}
@@ -2497,13 +2644,20 @@ void SavageDisableMMIO(ScrnInfoPtr pScrn)
int vgaCRIndex, vgaCRReg;
unsigned char val;
+ TRACE(("SavageDisableMMIO\n"));
+
vgaHWGetIOBase(hwp);
vgaCRIndex = hwp->IOBase + 4;
vgaCRReg = hwp->IOBase + 5;
- VGAOUT8(vgaCRIndex, 0x40);
- val = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, val | 1);
+ if( psav->Chipset >= S3_SAVAGE4 )
+ {
+ VGAOUT8(vgaCRIndex, 0x40);
+ val = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, val | 1);
+ }
+
+ vgaHWSetStdFuncs(hwp);
return;
}
@@ -2527,6 +2681,9 @@ void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies,
static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1,
+
+ /* Make sure linear addressing is enabled after the BIOS call. */
+ /* Note that we must use an I/O port to do this. */
int min_n2, int max_n2, long freq_min,
long freq_max, unsigned int *mdiv,
unsigned int *ndiv, unsigned int *r)
@@ -2592,6 +2749,8 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
SavagePtr psav = SAVPTR(pScrn);
int vgaCRIndex, vgaCRReg, vgaIOBase;
+ TRACE(("SavageGEReset(%d,%s)\n", line, file));
+
vgaIOBase = hwp->IOBase;
vgaCRIndex = vgaIOBase + 4;
vgaCRReg = vgaIOBase + 5;
@@ -2603,7 +2762,7 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
} else
WaitIdleEmpty();
- if (from_timeout) {
+ if (from_timeout && (psav->Chipset != S3_SAVAGE_MX) ) {
fifo_control = INREG(FIFO_CONTROL_REG);
miu_control = INREG(MIU_CONTROL_REG);
streams_timeout = INREG(STREAMS_TIMEOUT_REG);
@@ -2647,7 +2806,7 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
break;
}
- if (from_timeout) {
+ if (from_timeout && (psav->Chipset != S3_SAVAGE_MX) ) {
OUTREG(FIFO_CONTROL_REG, fifo_control);
OUTREG(MIU_CONTROL_REG, miu_control);
OUTREG(STREAMS_TIMEOUT_REG, streams_timeout);
@@ -2700,12 +2859,13 @@ SavagePrintRegs(ScrnInfoPtr pScrn)
}
-#ifdef DPMSExtension
static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags)
{
SavagePtr psav = SAVPTR(pScrn);
unsigned char sr8 = 0x00, srd = 0x00;
+ TRACE(("SavageDPMS(%d,%x)\n", mode, flags));
+
VGAOUT8(0x3c4, 0x08);
sr8 = VGAIN8(0x3c5);
sr8 |= 0x06;
@@ -2738,4 +2898,53 @@ static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags)
return;
}
-#endif /* DPMSExtension */
+
+
+static unsigned int
+SavageDDC1Read(ScrnInfoPtr pScrn)
+{
+ register vgaHWPtr hwp = VGAHWPTR(pScrn);
+ register CARD32 tmp;
+ SavagePtr psav = SAVPTR(pScrn);
+
+ while (hwp->readST01(hwp)&0x8) {};
+ while (!(hwp->readST01(hwp)&0x8)) {};
+
+ tmp = (INREG(DDC_REG));
+ return ((unsigned int) (tmp & 0x08));
+}
+
+static Bool
+SavageDDC1(int scrnIndex)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SavagePtr psav = SAVPTR(pScrn);
+ CARD32 tmp;
+ Bool success = FALSE;
+ xf86MonPtr pMon;
+
+ /* initialize chipset */
+ tmp = INREG(DDC_REG);
+ OUTREG(DDC_REG,(tmp | 0x12));
+
+ if ((pMon = xf86PrintEDID(
+ xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,SavageDDC1Read))) != NULL)
+ success = TRUE;
+ xf86SetDDCproperties(pScrn,pMon);
+
+ /* undo initialization */
+ OUTREG(DDC_REG,(tmp));
+ return success;
+}
+
+
+static void
+SavageProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ pVbe = VBEInit(NULL,index);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ }
+}
+