summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c574
1 files changed, 332 insertions, 242 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
index ec2729055..55de9b066 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
@@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c,v 1.30 2000/03/06 23:54:13 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c,v 1.39 2000/06/23 23:43:45 alanh Exp $ */
/*
* Authors:
@@ -35,10 +35,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* This server does not support these XFree 4.0 features yet
- * DDC1 & DDC2 (requires I2C)
+ * DDC2 (requires I2C)
* shadowFb (if requested or acceleration is off)
* Overlay planes
- * DGA
*/
/*
@@ -75,17 +74,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Required for line biases */
#include "miline.h"
-/* Drivers using cfb need: */
-
-#define PSZ 8
-#include "cfb.h"
-#undef PSZ
-
-/* Drivers supporting bpp 16, 24 or 32 with cfb need one or more of: */
-
-#include "cfb16.h"
-#include "cfb24.h"
-#include "cfb32.h"
+#include "fb.h"
/* !!! These need to be checked !!! */
#if 0
@@ -110,6 +99,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Required Functions: */
+static OptionInfoPtr TDFXAvailableOptions(int chipid, int busid);
/* Print a driver identifying message. */
static void TDFXIdentify(int flags);
@@ -147,23 +137,18 @@ static void TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn,
int PowerManagermentMode, int flags);
#endif
-#define VERSION 4000
-#define TDFX_NAME "TDFX"
-#define TDFX_DRIVER_NAME "tdfx"
-#define TDFX_MAJOR_VERSION 1
-#define TDFX_MINOR_VERSION 0
-#define TDFX_PATCHLEVEL 0
#define PCI_SUBDEVICE_ID_VOODOO3_2000 0x0036
#define PCI_SUBDEVICE_ID_VOODOO3_3000 0x003a
DriverRec TDFX = {
- VERSION,
+ TDFX_VERSION,
TDFX_DRIVER_NAME,
#if 0
- "Accelerated driver for 3dfx Voodoo Banshee and Voodoo3 cards",
+ "Accelerated driver for 3dfx cards",
#endif
TDFXIdentify,
TDFXProbe,
+ TDFXAvailableOptions,
NULL,
0
};
@@ -172,12 +157,14 @@ DriverRec TDFX = {
static SymTabRec TDFXChipsets[] = {
{ PCI_CHIP_BANSHEE, "3dfx Banshee"},
{ PCI_CHIP_VOODOO3, "3dfx Voodoo3"},
+ { PCI_CHIP_VOODOO5, "3dfx Voodoo5"},
{ -1, NULL }
};
static PciChipsets TDFXPciChipsets[] = {
{ PCI_CHIP_BANSHEE, PCI_CHIP_BANSHEE, RES_SHARED_VGA },
{ PCI_CHIP_VOODOO3, PCI_CHIP_VOODOO3, RES_SHARED_VGA },
+ { PCI_CHIP_VOODOO5, PCI_CHIP_VOODOO5, RES_SHARED_VGA },
{ -1, -1, RES_UNDEFINED }
};
@@ -187,13 +174,15 @@ static PciChipsets TDFXPciChipsets[] = {
typedef enum {
OPTION_NOACCEL,
OPTION_SW_CURSOR,
- OPTION_USE_PIO
+ OPTION_USE_PIO,
+ OPTION_NO_SLI
} TDFXOpts;
static OptionInfoRec TDFXOptions[] = {
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_USE_PIO, "UsePIO", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_NO_SLI, "NoSLI", OPTV_BOOLEAN, {0}, FALSE},
{ -1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -214,13 +203,8 @@ static const char *vgahwSymbols[] = {
0
};
-static const char *cfbSymbols[] = {
- "cfbScreenInit",
- "cfb16ScreenInit",
- "cfb24ScreenInit",
- "cfb32ScreenInit",
- "cfb8_32ScreenInit",
- "cfb24_32ScreenInit",
+static const char *fbSymbols[] = {
+ "fbScreenInit",
NULL
};
@@ -271,6 +255,8 @@ static const char *drmSymbols[] = {
"drmMapBufs",
"drmMarkBufs",
"drmUnmapBufs",
+ "drmFreeVersion",
+ "drmGetVersion",
NULL
};
@@ -287,6 +273,7 @@ static const char *driSymbols[] = {
"DRIUnlock",
"DRIGetSAREAPrivate",
"DRIGetContext",
+ "DRIQueryVersion",
"GlxSetVisualConfigs",
NULL
};
@@ -333,7 +320,7 @@ tdfxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
* Tell the loader about symbols from other modules that this module
* might refer to.
*/
- LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
xf8_32bppSymbols, ramdacSymbols, vbeSymbols,
#ifdef XF86DRI
drmSymbols, driSymbols,
@@ -388,6 +375,26 @@ TDFXIdentify(int flags) {
xf86PrintChipsets(TDFX_NAME, "Driver for 3dfx Banshee/Voodoo3 chipsets", TDFXChipsets);
}
+static
+OptionInfoPtr
+TDFXAvailableOptions(int chipid, int busid)
+{
+ return TDFXOptions;
+}
+
+void
+TDFXProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ vbeInfoPtr pVbe;
+#ifdef XFree86LOADER
+ if (xf86LoadSubModule(pScrn, "vbe"))
+#endif
+ {
+ pVbe = VBEInit(NULL,index);
+ vbeDoEDID(pVbe, NULL);
+ }
+}
+
/*
* TDFXProbe --
*
@@ -420,9 +427,9 @@ TDFXProbe(DriverPtr drv, int flags) {
TDFXChipsets, TDFXPciChipsets,
devSections, numDevSections,
drv, &usedChips);
+
if (devSections)
xfree(devSections);
- devSections=NULL;
if (numUsed<=0) return FALSE;
if (flags & PROBE_DETECT)
@@ -431,23 +438,24 @@ TDFXProbe(DriverPtr drv, int flags) {
ScrnInfoPtr pScrn;
/* Allocate new ScrnInfoRec and claim the slot */
- pScrn = xf86AllocateScreen(drv, 0);
-
- pScrn->driverVersion = VERSION;
- pScrn->driverName = TDFX_DRIVER_NAME;
- pScrn->name = TDFX_NAME;
- pScrn->Probe = TDFXProbe;
- pScrn->PreInit = TDFXPreInit;
- pScrn->ScreenInit = TDFXScreenInit;
- pScrn->SwitchMode = TDFXSwitchMode;
- pScrn->AdjustFrame = TDFXAdjustFrame;
- pScrn->EnterVT = TDFXEnterVT;
- pScrn->LeaveVT = TDFXLeaveVT;
- pScrn->FreeScreen = TDFXFreeScreen;
- pScrn->ValidMode = TDFXValidMode;
- foundScreen = TRUE;
-
- xf86ConfigActivePciEntity(pScrn, usedChips[i], TDFXPciChipsets, 0, 0, 0, 0, 0);
+ pScrn = NULL;
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ TDFXPciChipsets, 0, 0, 0, 0, 0))) {
+
+ pScrn->driverVersion = TDFX_VERSION;
+ pScrn->driverName = TDFX_DRIVER_NAME;
+ pScrn->name = TDFX_NAME;
+ pScrn->Probe = TDFXProbe;
+ pScrn->PreInit = TDFXPreInit;
+ pScrn->ScreenInit = TDFXScreenInit;
+ pScrn->SwitchMode = TDFXSwitchMode;
+ pScrn->AdjustFrame = TDFXAdjustFrame;
+ pScrn->EnterVT = TDFXEnterVT;
+ pScrn->LeaveVT = TDFXLeaveVT;
+ pScrn->FreeScreen = TDFXFreeScreen;
+ pScrn->ValidMode = TDFXValidMode;
+ foundScreen = TRUE;
+ }
}
xfree(usedChips);
@@ -463,10 +471,11 @@ TDFXCountRam(ScrnInfoPtr pScrn) {
pTDFX = TDFXPTR(pScrn);
TDFXTRACE("TDFXCountRam start\n");
memSize=0;
- if (pTDFX->PIOBase) {
+ if (pTDFX->PIOBase[0]) {
CARD32
partSize, /* size of SGRAM chips in Mbits */
nChips, /* # chips of SDRAM/SGRAM */
+ banks, /* Number of banks of chips */
dramInit0_strap,
dramInit1_strap,
dramInit1,
@@ -492,23 +501,28 @@ TDFXCountRam(ScrnInfoPtr pScrn) {
/* determine memory size from strapping pins (dramInit0 and dramInit1) */
dramInit0_strap = pTDFX->readLong(pTDFX, DRAMINIT0);
- dramInit0_strap &= SST_SGRAM_TYPE | SST_SGRAM_NUM_CHIPSETS;
-
- if ( memType == MEM_TYPE_SDRAM ) {
- memSize = 16;
- } else {
- nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS) == 0) ? 4 : 8;
-
- if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_8MBIT ) {
- partSize = 8;
- } else if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_16MBIT) {
- partSize = 16;
+ if (pTDFX->ChipType<=PCI_CHIP_VOODOO3) { /* Banshee/V3 */
+ if (memType == MEM_TYPE_SDRAM) {
+ memSize = 16;
} else {
- ErrorF("Invalid sgram type = 0x%x",
- (dramInit0_strap & SST_SGRAM_TYPE) << SST_SGRAM_TYPE_SHIFT );
- return 0;
+ nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS) == 0) ? 4 : 8;
+
+ if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_8MBIT ) {
+ partSize = 8;
+ } else if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_16MBIT) {
+ partSize = 16;
+ } else {
+ ErrorF("Invalid sgram type = 0x%x",
+ (dramInit0_strap & SST_SGRAM_TYPE) << SST_SGRAM_TYPE_SHIFT );
+ return 0;
+ }
+ memSize = (nChips * partSize) / 8; /* in MBytes */
}
- memSize = (nChips * partSize) / 8; /* in MBytes */
+ } else { /* V4, V5 */
+ nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS)==0) ? 4 : 8;
+ partSize=1<<((dramInit0_strap&0x38000000)>>28);
+ banks=((dramInit0_strap&BIT(30))==0) ? 2 : 4;
+ memSize=nChips*partSize*banks;
}
TDFXTRACEREG("dramInit0 = %x dramInit1 = %x\n", dramInit0_strap, dramInit1_strap);
TDFXTRACEREG("MemConfig %d chips %d size %d total\n", nChips, partSize, memSize);
@@ -528,18 +542,85 @@ TDFXCountRam(ScrnInfoPtr pScrn) {
return memSize*1024;
}
-extern xf86MonPtr ConfiguredMonitor;
+static int TDFXCfgToSize(int cfg)
+{
+ if (cfg<4) return 0x8000000<<cfg;
+ return 0x4000000>>(cfg-4);
+}
-void
-TDFXProbeDDC(ScrnInfoPtr pScrn, int index)
+static int TDFXSizeToCfg(int size)
{
- vbeInfoPtr pVbe;
- if (xf86LoadSubModule(pScrn, "vbe")) {
- pVbe = VBEInit(NULL,index);
- ConfiguredMonitor = vbeDoEDID(pVbe);
+ switch (size) {
+ case 0x40000000: return 3;
+ case 0x20000000: return 2;
+ case 0x10000000: return 1;
+ case 0x08000000: return 0;
+ case 0x04000000: return 4;
+ case 0x02000000: return 5;
+ case 0x01000000: return 6;
+ case 0x00800000: return 7;
+ case 0x00400000: return 8;
+ default:
+ return -1;
+ }
+}
+
+static void
+TDFXFindChips(ScrnInfoPtr pScrn, pciVideoPtr match)
+{
+ TDFXPtr pTDFX;
+ pciVideoPtr *ppPci;
+
+ pTDFX=TDFXPTR(pScrn);
+ pTDFX->numChips=0;
+ pTDFX->ChipType=match->chipType;
+ for (ppPci = xf86GetPciVideoInfo(); *ppPci != NULL; ppPci++) {
+ if ((*ppPci)->bus == match->bus &&
+ (*ppPci)->device == match->device) {
+ pTDFX->PciTag[pTDFX->numChips] = pciTag((*ppPci)->bus,
+ (*ppPci)->device,
+ (*ppPci)->func);
+ pTDFX->PIOBase[pTDFX->numChips] = (*ppPci)->ioBase[2]&0xFFFFFFFC;
+ pTDFX->numChips++;
}
+ }
+ /* Disable the secondary chips for now */
+ pTDFX->numChips=1;
}
+static void
+TDFXInitChips(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX;
+ int i, cfgbits, initbits;
+ int mem0base, mem1base, mem0size, mem0bits, mem1size, mem1bits;
+
+ pTDFX=TDFXPTR(pScrn);
+ cfgbits=pciReadLong(pTDFX->PciTag[0], CFG_PCI_DECODE);
+ mem0base=pciReadLong(pTDFX->PciTag[0], CFG_MEM0BASE);
+ mem1base=pciReadLong(pTDFX->PciTag[0], CFG_MEM1BASE);
+ mem0size=32*1024*1024; /* Registers are always 32MB */
+ mem1size=pScrn->videoRam*1024*2; /* Linear mapping is 2x memory */
+ mem0bits=TDFXSizeToCfg(mem0size);
+ mem1bits=TDFXSizeToCfg(mem1size)<<4;
+ cfgbits=(cfgbits&~(0xFF))|mem0bits|mem1bits;
+ for (i=0; i<pTDFX->numChips; i++) {
+ initbits=pciReadLong(pTDFX->PciTag[i], CFG_INIT_ENABLE);
+ initbits|=BIT(10);
+ pciWriteLong(pTDFX->PciTag[i], CFG_INIT_ENABLE, initbits);
+ pTDFX->MMIOAddr[i]=mem0base+i*mem0size;
+ pciWriteLong(pTDFX->PciTag[i], CFG_MEM0BASE, 0xFFFFFFFF);
+ pciWriteLong(pTDFX->PciTag[i], CFG_MEM0BASE, pTDFX->MMIOAddr[i]);
+ pTDFX->MMIOAddr[i]&=0xFFFFFF00;
+ pTDFX->LinearAddr[i]=mem1base+i*mem1size;
+ pciWriteLong(pTDFX->PciTag[i], CFG_MEM1BASE, 0xFFFFFFFF);
+ pciWriteLong(pTDFX->PciTag[i], CFG_MEM1BASE, pTDFX->LinearAddr[i]);
+ pTDFX->LinearAddr[i]&=0xFFFFFF00;
+ pciWriteLong(pTDFX->PciTag[i], CFG_PCI_DECODE, cfgbits);
+ initbits&=~BIT(10);
+ pciWriteLong(pTDFX->PciTag[i], CFG_INIT_ENABLE, initbits);
+ }
+}
/*
* TDFXPreInit --
@@ -549,8 +630,8 @@ TDFXProbeDDC(ScrnInfoPtr pScrn, int index)
*
*/
static Bool
-TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
- vgaHWPtr hwp;
+TDFXPreInit(ScrnInfoPtr pScrn, int flags)
+{
TDFXPtr pTDFX;
ClockRangePtr clockRanges;
int i;
@@ -558,6 +639,7 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
char *mod=0, *reqSym=0;
int flags24;
rgb defaultWeight = {0, 0, 0};
+ pciVideoPtr match;
TDFXTRACE("TDFXPreInit start\n");
if (pScrn->numEntities != 1) return FALSE;
@@ -569,10 +651,29 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
pTDFX = TDFXPTR(pScrn);
+ pTDFX->initDone=FALSE;
pTDFX->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (flags & PROBE_DETECT) {
+ TDFXProbeDDC(pScrn, pTDFX->pEnt->index);
+ return TRUE;
+ }
+
if (pTDFX->pEnt->location.type != BUS_PCI) return FALSE;
+ if (flags & PROBE_DETECT) {
+ TDFXProbeDDC(pScrn, pTDFX->pEnt->index);
+ return FALSE;
+ }
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* Allocate a vgaHWRec */
+ if (!vgaHWGetHWRec(pScrn)) return FALSE;
+
if (xf86LoadSubModule(pScrn, "int10")) {
xf86Int10InfoPtr pInt;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -591,9 +692,8 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
}
}
- pTDFX->PciInfo = xf86GetPciInfoForEntity(pTDFX->pEnt->index);
- pTDFX->PciTag = pciTag(pTDFX->PciInfo->bus, pTDFX->PciInfo->device,
- pTDFX->PciInfo->func);
+ match=pTDFX->PciInfo=xf86GetPciInfoForEntity(pTDFX->pEnt->index);
+ TDFXFindChips(pScrn, match);
if (xf86RegisterResources(pTDFX->pEnt->index, 0, ResNone))
return FALSE;
@@ -602,11 +702,6 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
else
pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
- if (flags & PROBE_DETECT) {
- TDFXProbeDDC(pScrn, pTDFX->pEnt->index);
- return FALSE;
- }
-
/* Set pScrn->monitor */
pScrn->monitor = pScrn->confScreen->monitor;
@@ -634,7 +729,6 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
return FALSE;
}
- pScrn->rgbBits=8;
if (!xf86SetDefaultVisual(pScrn, -1)) {
return FALSE;
} else {
@@ -647,18 +741,9 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
}
}
- /* The vgahw module should be loaded here when needed */
- if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE;
-
- xf86LoaderReqSymLists(vgahwSymbols, NULL);
-
- /* Allocate a vgaHWRec */
- if (!vgaHWGetHWRec(pScrn)) return FALSE;
-
/* We use a programamble clock */
pScrn->progClock = TRUE;
- hwp = VGAHWPTR(pScrn);
pTDFX->cpp = pScrn->bitsPerPixel/8;
/* Process the options */
@@ -679,7 +764,7 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
pTDFX->pEnt->device->chipID);
} else {
from = X_PROBED;
- pScrn->chipset = (char *)xf86TokenToString(TDFXChipsets, pTDFX->PciInfo->chipType);
+ pScrn->chipset = (char *)xf86TokenToString(TDFXChipsets, match->chipType);
}
if (pTDFX->pEnt->device->chipRev >= 0) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
@@ -689,11 +774,11 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
if (pTDFX->pEnt->device->MemBase != 0) {
- pTDFX->LinearAddr = pTDFX->pEnt->device->MemBase;
+ pTDFX->LinearAddr[0] = pTDFX->pEnt->device->MemBase;
from = X_CONFIG;
} else {
- if (pTDFX->PciInfo->memBase[1] != 0) {
- pTDFX->LinearAddr = pTDFX->PciInfo->memBase[1];
+ if (match->memBase[1] != 0) {
+ pTDFX->LinearAddr[0] = match->memBase[1];
from = X_PROBED;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -703,14 +788,14 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
}
}
xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
- (unsigned long)pTDFX->LinearAddr);
+ (unsigned long)pTDFX->LinearAddr[0]);
if (pTDFX->pEnt->device->IOBase != 0) {
- pTDFX->MMIOAddr = pTDFX->pEnt->device->IOBase;
+ pTDFX->MMIOAddr[0] = pTDFX->pEnt->device->IOBase;
from = X_CONFIG;
} else {
- if (pTDFX->PciInfo->memBase[0]) {
- pTDFX->MMIOAddr = pTDFX->PciInfo->memBase[0];
+ if (match->memBase[0]) {
+ pTDFX->MMIOAddr[0] = match->memBase[0];
from = X_PROBED;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -722,8 +807,8 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at addr 0x%lX\n",
(unsigned long)pTDFX->MMIOAddr);
- if (pTDFX->PciInfo->ioBase[2]) {
- pTDFX->PIOBase = pTDFX->PciInfo->ioBase[2]&0xFFFFFFFC;
+ if (match->ioBase[2]) {
+ pTDFX->PIOBase[0] = match->ioBase[2]&0xFFFFFFFC;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"No valid PIO address in PCI config space\n");
@@ -731,7 +816,7 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PIO registers at addr 0x%lX\n",
- (unsigned long)pTDFX->PIOBase);
+ (unsigned long)pTDFX->PIOBase[0]);
/* We have to use PIO to probe, because we haven't mappend yet */
TDFXSetPIOAccess(pTDFX);
@@ -744,6 +829,8 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
from = X_CONFIG;
}
+ TDFXInitChips(pScrn);
+
/* Multiple by two because tiled access requires more address space */
pTDFX->FbMapSize = pScrn->videoRam*1024*2;
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte Mapping %d kByte\n",
@@ -778,12 +865,12 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[0];
from = X_CONFIG;
} else {
- switch (pTDFX->PciInfo->chipType) {
+ switch (pTDFX->ChipType) {
case PCI_CHIP_BANSHEE:
pTDFX->MaxClock = 270000;
break;
case PCI_CHIP_VOODOO3:
- switch(pTDFX->PciInfo->subsysCard) {
+ switch(match->subsysCard) {
case PCI_SUBDEVICE_ID_VOODOO3_2000:
pTDFX->MaxClock = 300000;
break;
@@ -795,14 +882,17 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
break;
}
break;
+ case PCI_CHIP_VOODOO5:
+ pTDFX->MaxClock = 350000;
+ break;
}
}
- clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
clockRanges->next=NULL;
clockRanges->minClock= 12000; /* !!! What's the min clock? !!! */
clockRanges->maxClock=pTDFX->MaxClock;
clockRanges->clockIndex = -1;
- clockRanges->interlaceAllowed = TRUE;
+ clockRanges->interlaceAllowed = FALSE;
clockRanges->doubleScanAllowed = TRUE;
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
@@ -833,29 +923,11 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
xf86SetDpi(pScrn, 0, 0);
- switch (pScrn->bitsPerPixel) {
- case 8:
- mod = "cfb";
- reqSym = "cfbScreenInit";
- break;
- case 16:
- mod = "cfb16";
- reqSym = "cfb16ScreenInit";
- break;
- case 24:
- mod = "cfb24";
- reqSym = "cfb24ScreenInit";
- break;
- case 32:
- mod = "cfb32";
- reqSym = "cfb32ScreenInit";
- break;
- }
- if (mod && !xf86LoadSubModule(pScrn, mod)) {
+ if (!xf86LoadSubModule(pScrn, "fb")) {
TDFXFreeRec(pScrn);
return FALSE;
}
- xf86LoaderReqSymbols(reqSym, NULL);
+ xf86LoaderReqSymbols("fbScreenInit", NULL);
if (!xf86ReturnOptValBool(TDFXOptions, OPTION_NOACCEL, FALSE)) {
if (!xf86LoadSubModule(pScrn, "xaa")) {
@@ -883,25 +955,11 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
/* Initialize DDC1 if possible */
if (xf86LoadSubModule(pScrn, "vbe")) {
xf86MonPtr pMon;
- pMon = vbeDoEDID(VBEInit(NULL,pTDFX->pEnt->index));
+ pMon = vbeDoEDID(VBEInit(NULL,pTDFX->pEnt->index), NULL);
xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon));
}
-
- /* We wont be using the VGA access after the probe */
- if (!xf86ReturnOptValBool(TDFXOptions, OPTION_USE_PIO, FALSE)) {
- resRange vgaio[] = { {ResShrIoBlock,0x3B0,0x3BB},
- {ResShrIoBlock,0x3C0,0x3DF},
- _END };
- resRange vgamem[] = {{ResShrMemBlock,0xA0000,0xAFFFF},
- {ResShrMemBlock,0xB8000,0xBFFFF},
- {ResShrMemBlock,0xB0000,0xB7FFF},
- _END };
-
- pTDFX->usePIO=FALSE;
- xf86SetOperatingState(vgaio, pTDFX->pEnt->index, ResUnusedOpr);
- xf86SetOperatingState(vgamem, pTDFX->pEnt->index, ResDisableOpr);
- } else {
+ if (xf86ReturnOptValBool(TDFXOptions, OPTION_USE_PIO, FALSE)) {
pTDFX->usePIO=TRUE;
}
@@ -911,7 +969,7 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
static Bool
TDFXMapMem(ScrnInfoPtr pScrn)
{
- int mmioFlags;
+ int mmioFlags, i;
TDFXPtr pTDFX;
TDFXTRACE("TDFXMapMem start\n");
@@ -919,15 +977,18 @@ TDFXMapMem(ScrnInfoPtr pScrn)
mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
- pTDFX->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
- pTDFX->PciTag,
- pTDFX->MMIOAddr,
- TDFXIOMAPSIZE);
- if (!pTDFX->MMIOBase) return FALSE;
+ for (i=0; i<pTDFX->numChips; i++) {
+ pTDFX->MMIOBase[i] = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pTDFX->PciTag[i],
+ pTDFX->MMIOAddr[i],
+ TDFXIOMAPSIZE);
+
+ if (!pTDFX->MMIOBase[i]) return FALSE;
+ }
pTDFX->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
- pTDFX->PciTag,
- pTDFX->LinearAddr,
+ pTDFX->PciTag[0],
+ pTDFX->LinearAddr[0],
pTDFX->FbMapSize);
if (!pTDFX->FbBase) return FALSE;
@@ -938,12 +999,16 @@ static Bool
TDFXUnmapMem(ScrnInfoPtr pScrn)
{
TDFXPtr pTDFX;
+ int i;
TDFXTRACE("TDFXUnmapMem start\n");
pTDFX = TDFXPTR(pScrn);
- xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTDFX->MMIOBase, TDFXIOMAPSIZE);
- pTDFX->MMIOBase=0;
+ for (i=0; i<pTDFX->numChips; i++) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTDFX->MMIOBase[i],
+ TDFXIOMAPSIZE);
+ pTDFX->MMIOBase[i]=0;
+ }
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTDFX->FbBase, pTDFX->FbMapSize);
pTDFX->FbBase = 0;
@@ -1118,12 +1183,20 @@ TDFXRestore(ScrnInfoPtr pScrn) {
#define REFFREQ 14318.18
static int
-CalcPLL(int freq, int *f_out) {
+CalcPLL(int freq, int *f_out, int isBanshee) {
int m, n, k, best_m, best_n, best_k, f_cur, best_error;
+ int minm, maxm;
TDFXTRACE("CalcPLL start\n");
best_error=freq;
best_n=best_m=best_k=0;
+ if (isBanshee) {
+ minm=24;
+ maxm=24;
+ } else {
+ minm=1;
+ maxm=64;
+ }
for (n=1; n<256; n++) {
f_cur=REFFREQ*(n+2);
if (f_cur<freq) {
@@ -1136,7 +1209,7 @@ CalcPLL(int freq, int *f_out) {
continue;
}
}
- for (m=1; m<64; m++) {
+ for (m=minm; m<maxm; m++) {
for (k=0; k<4; k++) {
f_cur=REFFREQ*(n+2)/(m+2)/(1<<k);
if (abs(f_cur-freq)<best_error) {
@@ -1175,7 +1248,7 @@ SetupVidPLL(ScrnInfoPtr pScrn, DisplayModePtr mode) {
tdfxReg->dacmode|=SST_DAC_MODE_2X;
tdfxReg->vidcfg|=SST_VIDEO_2X_MODE_EN;
}
- tdfxReg->vidpll=CalcPLL(freq, &f_out);
+ tdfxReg->vidpll=CalcPLL(freq, &f_out, 0);
TDFXTRACEREG("Vid PLL freq=%d f_out=%d reg=%x\n", freq, f_out,
tdfxReg->vidpll);
return TRUE;
@@ -1207,7 +1280,10 @@ SetupGfxPLL(int freq) {
TDFXTRACE("SetupGfxPLL start\n");
pTDFX=TDFXPTR();
tdfxReg=(vgaTDFXPtr)vgaNewVideoState;
- tdfxReg->gfxpll=CalcPLL(freq, &f_out);
+ if (pTDFX->chipType==PCI_CHIP_BANSHEE)
+ tdfxReg->gfxpll=CalcPLL(freq, &f_out, 1);
+ else
+ tdfxReg->gfxpll=CalcPLL(freq, &f_out, 0);
pTDFX->writeLong(pTDFX, PLLCTRL2, tdfxReg->gfxpll);
TDFXTRACEREG("Gfx PLL freq=%d f_out=%d reg=%x\n", freq, f_out,
tdfxReg->gfxpll);
@@ -1218,14 +1294,13 @@ SetupGfxPLL(int freq) {
static Bool
TDFXInitVGA(ScrnInfoPtr pScrn)
{
- static Bool initDone=FALSE;
TDFXPtr pTDFX;
TDFXRegPtr tdfxReg;
TDFXTRACE("TDFXInitVGA start\n");
- if (initDone) return TRUE;
- initDone=TRUE;
pTDFX=TDFXPTR(pScrn);
+ if (pTDFX->initDone) return TRUE;
+ pTDFX->initDone=TRUE;
tdfxReg = &pTDFX->ModeReg;
tdfxReg->vgainit0 = 0;
tdfxReg->vgainit0 |= SST_VGA0_EXTENSIONS;
@@ -1240,8 +1315,9 @@ TDFXInitVGA(ScrnInfoPtr pScrn)
tdfxReg->vidcfg = SST_VIDEO_PROCESSOR_EN | SST_CURSOR_X11 | SST_DESKTOP_EN |
(pTDFX->cpp-1)<<SST_DESKTOP_PIXEL_FORMAT_SHIFT;
- if (pTDFX->cpp!=1) tdfxReg->vidcfg |= SST_DESKTOP_CLUT_BYPASS;
+ /* tdfxReg->vidcfg |= SST_DESKTOP_CLUT_BYPASS; */
+
tdfxReg->stride = pTDFX->stride;
tdfxReg->clip0min = tdfxReg->clip1min = 0;
@@ -1377,8 +1453,9 @@ TDFXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
#endif
DoRestore(pScrn, &hwp->ModeReg, &pTDFX->ModeReg, FALSE);
#ifdef XF86DRI
- if (pTDFX->directRenderingEnabled)
+ if (pTDFX->directRenderingEnabled) {
DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
+ }
#endif
return TRUE;
@@ -1388,30 +1465,37 @@ static void
TDFXLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
short visualClass) {
TDFXPtr pTDFX;
- vgaHWPtr hwp;
- int i, index;
- unsigned char r, g, b;
+ int i, j, index, v, repeat, max;
TDFXTRACE("TDFXLoadPalette16 start\n");
pTDFX = TDFXPTR(pScrn);
- hwp = VGAHWPTR(pScrn);
for (i=0; i<numColors; i++) {
- index=indices[i/2];
- r=colors[index].red;
- b=colors[index].blue;
index=indices[i];
- g=colors[index].green;
- hwp->writeDacWriteAddr(hwp, index<<2);
- hwp->writeDacData(hwp, r);
- hwp->writeDacData(hwp, g);
- hwp->writeDacData(hwp, b);
- i++;
- index=indices[i];
- g=colors[index].green;
- hwp->writeDacWriteAddr(hwp, index<<2);
- hwp->writeDacData(hwp, r);
- hwp->writeDacData(hwp, g);
- hwp->writeDacData(hwp, b);
+ v=(colors[index/2].red<<16)|(colors[index].green<<8)|colors[index/2].blue;
+ if (i<numColors-1) max=indices[i+1]<<2;
+ else max=256;
+ for (j=index<<2; j<max; j++) {
+ repeat=100;
+ do {
+ pTDFX->writeLong(pTDFX, DACADDR, j);
+ } while (--repeat && pTDFX->readLong(pTDFX, DACADDR)!=j);
+ if (!repeat) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac index, "
+ "bypassing CLUT\n");
+ pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS;
+ return;
+ }
+ repeat=100;
+ do {
+ pTDFX->writeLong(pTDFX, DACDATA, v);
+ } while (--repeat && pTDFX->readLong(pTDFX, DACDATA)!=v);
+ if (!repeat) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac value, "
+ "bypassing CLUT\n");
+ pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS;
+ return;
+ }
+ }
}
}
@@ -1419,23 +1503,33 @@ static void
TDFXLoadPalette24(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
short visualClass) {
TDFXPtr pTDFX;
- vgaHWPtr hwp;
- int i, index;
- unsigned char r, g, b;
+ int i, index, v, repeat;
TDFXTRACE("TDFXLoadPalette24 start\n");
pTDFX = TDFXPTR(pScrn);
- hwp = VGAHWPTR(pScrn);
for (i=0; i<numColors; i++) {
index=indices[i];
- r=colors[index].red;
- b=colors[index].blue;
- index=indices[i];
- g=colors[index].green;
- hwp->writeDacWriteAddr(hwp, index);
- hwp->writeDacData(hwp, r);
- hwp->writeDacData(hwp, g);
- hwp->writeDacData(hwp, b);
+ v=(colors[index].red<<16)|(colors[index].green<<8)|colors[index].blue;
+ repeat=100;
+ do {
+ pTDFX->writeLong(pTDFX, DACADDR, index);
+ } while (--repeat && pTDFX->readLong(pTDFX, DACADDR)!=index);
+ if (!repeat) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac index, "
+ "bypassing CLUT\n");
+ pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS;
+ return;
+ }
+ repeat=100;
+ do {
+ pTDFX->writeLong(pTDFX, DACDATA, v);
+ } while (--repeat && pTDFX->readLong(pTDFX, DACDATA)!=v);
+ if (!repeat) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac value, "
+ "bypassing CLUT\n");
+ pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS;
+ return;
+ }
}
}
@@ -1443,20 +1537,17 @@ TDFXLoadPalette24(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
#define TILE_HEIGHT 32
static int
-calcBufferStride(int xres, Bool tiled)
+calcBufferStride(int xres, Bool tiled, int cpp)
{
int strideInTiles;
if (tiled == TRUE) {
/* Calculate tile width stuff */
- strideInTiles = (xres << 1) >> 7;
- if ((xres << 1) & (TILE_WIDTH - 1))
- strideInTiles++;
+ strideInTiles = (xres+TILE_WIDTH-1)/TILE_WIDTH;
- return (strideInTiles * TILE_WIDTH);
-
+ return strideInTiles*cpp*TILE_WIDTH;
} else {
- return (xres << 1);
+ return xres*cpp;
}
} /* calcBufferStride */
@@ -1477,26 +1568,26 @@ calcBufferHeightInTiles(int yres)
} /* calcBufferHeightInTiles */
static int
-calcBufferSizeInTiles(int xres, int yres) {
+calcBufferSizeInTiles(int xres, int yres, int cpp) {
int bufSizeInTiles; /* Size of buffer in tiles */
bufSizeInTiles =
- calcBufferHeightInTiles(yres) * (calcBufferStride(xres, TRUE) >> 7);
+ calcBufferHeightInTiles(yres) * (calcBufferStride(xres, TRUE, cpp) >> 7);
return bufSizeInTiles;
} /* calcBufferSizeInTiles */
static int
-calcBufferSize(int xres, int yres, Bool tiled)
+calcBufferSize(int xres, int yres, Bool tiled, int cpp)
{
int stride, height, bufSize;
if (tiled) {
- stride = calcBufferStride(xres, tiled);
+ stride = calcBufferStride(xres, tiled, cpp);
height = TILE_HEIGHT * calcBufferHeightInTiles(yres);
} else {
- stride = xres << 1;
+ stride = xres*cpp;
height = yres;
}
@@ -1522,7 +1613,15 @@ static void allocateMemory(ScrnInfoPtr pScrn) {
/* Remove one scanline for page alignment */
memRemaining-=4095;
/* Remove the back and Z buffers */
- screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY, TRUE);
+ if (pTDFX->cpp!=3) {
+ screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY,
+ TRUE, pTDFX->cpp);
+ }
+ else {
+ /* cpp==3 needs to bump up to 4 */
+ screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY,
+ TRUE, 4);
+ }
memRemaining-=screenSizeInTiles*2;
/* Give all the rest to textures, rounded down to a page */
@@ -1578,20 +1677,26 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
hwp = VGAHWPTR(pScrn);
if (!TDFXMapMem(pScrn)) return FALSE;
- pScrn->memPhysBase = (int)pTDFX->LinearAddr;
+ pScrn->memPhysBase = (int)pTDFX->LinearAddr[0];
- if (!pTDFX->usePIO) {
- TDFXSetMMIOAccess(pTDFX);
- hwp->IOBase = ((hwp->readMiscOut(hwp) & 0x01) ?
- VGA_IOBASE_COLOR : VGA_IOBASE_MONO) + (unsigned long)pTDFX->MMIOBase -
- 0x300;
- } else {
- vgaHWGetIOBase(hwp);
- }
+ if (!pTDFX->usePIO) TDFXSetMMIOAccess(pTDFX);
+ vgaHWGetIOBase(hwp);
if (!vgaHWMapMem(pScrn)) return FALSE;
allocateMemory(pScrn);
+ if (pTDFX->numChips>1) {
+ if (xf86ReturnOptValBool(TDFXOptions, OPTION_NO_SLI, FALSE)) {
+ TDFXSetupSLI(pScrn, FALSE, 0);
+ } else {
+ TDFXSetupSLI(pScrn, TRUE, 0);
+ }
+ }
+
+ TDFXSetLFBConfig(pTDFX);
+
+ /* We initialize in the state that our FIFO is up to date */
+ pTDFX->syncDone=TRUE;
#ifdef PROP_3DFX
if (!TDFXInitPrivate(pScreen)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialize private\n");
@@ -1620,42 +1725,25 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
#ifdef XF86DRI
/*
- * Setup DRI after visuals have been established, but before cfbScreenInit
- * is called. cfbScreenInit will eventually call into the drivers
+ * Setup DRI after visuals have been established, but before fbScreenInit
+ * is called. fbScreenInit will eventually call into the drivers
* InitGLXVisuals call back.
*/
pTDFX->directRenderingEnabled = TDFXDRIScreenInit(pScreen);
/* Force the initialization of the context */
- TDFXLostContext(pScreen);
+ if (pTDFX->directRenderingEnabled)
+ TDFXLostContext(pScreen);
#endif
switch (pScrn->bitsPerPixel) {
case 8:
- if (!cfbScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth))
- return FALSE;
- break;
case 16:
- if (!cfb16ScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth))
- return FALSE;
- break;
case 24:
- if (!cfb24ScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth))
- return FALSE;
- break;
case 32:
- if (!cfb32ScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth))
+ if (!fbScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth, pScrn->bitsPerPixel))
return FALSE;
break;
default:
@@ -1732,14 +1820,13 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
#ifdef XF86DRI
if (pTDFX->directRenderingEnabled) {
- /* Now that mi, cfb, drm and others have done their thing,
+ /* Now that mi, fb, drm and others have done their thing,
* complete the DRI setup.
*/
pTDFX->directRenderingEnabled = TDFXDRIFinishScreenInit(pScreen);
}
if (pTDFX->directRenderingEnabled) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n");
- TDFXSetLFBConfig(pTDFX);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n");
}
@@ -1806,6 +1893,7 @@ TDFXEnterVT(int scrnIndex, int flags) {
if (pTDFX->directRenderingEnabled) {
pScreen = screenInfo.screens[scrnIndex];
DRIUnlock(pScreen);
+ TDFXLostContext(pScreen);
}
#endif
if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE;
@@ -1832,6 +1920,7 @@ TDFXLeaveVT(int scrnIndex, int flags) {
pTDFX = TDFXPTR(pScrn);
if (pTDFX->directRenderingEnabled) {
DRILock(pScreen, 0);
+ TDFXSwapContextPrivate(pScreen);
}
#endif
}
@@ -1978,3 +2067,4 @@ TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
pTDFX->writeLong(pTDFX, DACMODE, dacmode);
}
#endif
+