#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "xf86Version.h"
#include "xf86Resources.h"
#include "mipointer.h"
#include "mibstore.h"
#include "micmap.h"
#include "fb.h"
#include "xf86RAC.h"
#include "xf86cmap.h"
#include "tga_regs.h"
#include "BT.h"
#include "tga.h"
#define _XF86DGA_SERVER_
#include "extensions/xf86dgastr.h"
#include "globals.h"
#define DPMS_SERVER
#include "extensions/dpms.h"
#include "xf86xv.h"
#include "Xv.h"
static const OptionInfoRec * TGAAvailableOptions(int chipid, int busid);
static void TGAIdentify(int flags);
static Bool TGAProbe(DriverPtr drv, int flags);
static Bool TGAPreInit(ScrnInfoPtr pScrn, int flags);
static Bool TGAScreenInit(int Index, ScreenPtr pScreen, int argc,
char **argv);
static Bool TGAEnterVT(int scrnIndex, int flags);
static void TGALeaveVT(int scrnIndex, int flags);
static Bool TGACloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool TGASaveScreen(ScreenPtr pScreen, int mode);
static Bool TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
static void TGAAdjustFrame(int scrnIndex, int x, int y, int flags);
static void TGAFreeScreen(int scrnIndex, int flags);
static ModeStatus TGAValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flags);
static Bool TGAMapMem(ScrnInfoPtr pScrn);
static Bool TGAUnmapMem(ScrnInfoPtr pScrn);
static void TGASave(ScrnInfoPtr pScrn);
static void TGARestore(ScrnInfoPtr pScrn);
static Bool TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
static void TGARestoreHWCursor(ScrnInfoPtr pScrn);
static void TGADisplayPowerManagementSet(ScrnInfoPtr pScrn,
int PowerManagementMode,
int flags);
void TGASync(ScrnInfoPtr pScrn);
#define VERSION 4000
#define TGA_NAME "TGA"
#define TGA_DRIVER_NAME "tga"
#define TGA_MAJOR_VERSION 1
#define TGA_MINOR_VERSION 0
#define TGA_PATCHLEVEL 0
DriverRec TGA = {
VERSION,
TGA_DRIVER_NAME,
TGAIdentify,
TGAProbe,
TGAAvailableOptions,
NULL,
0
};
static SymTabRec TGAChipsets[] = {
{ PCI_CHIP_DEC21030, "tga" },
{ PCI_CHIP_TGA2, "tga2" },
{ -1, NULL }
};
static PciChipsets TGAPciChipsets[] = {
{ PCI_CHIP_DEC21030, PCI_CHIP_DEC21030, NULL },
{ PCI_CHIP_TGA2, PCI_CHIP_TGA2, NULL },
{ -1, -1, RES_UNDEFINED }
};
typedef enum {
OPTION_SW_CURSOR,
OPTION_HW_CURSOR,
OPTION_PCI_RETRY,
OPTION_RGB_BITS,
OPTION_NOACCEL,
OPTION_SYNC_ON_GREEN,
OPTION_DAC_6_BIT,
OPTION_NOXAAPOLYSEGMENT
} TGAOpts;
static const OptionInfoRec TGAOptions[] = {
{ OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DAC_6_BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_NOXAAPOLYSEGMENT, "NoXaaPolySegment",OPTV_BOOLEAN,{0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
static RamDacSupportedInfoRec BTramdacs[] = {
{ BT485_RAMDAC },
{ -1 }
};
static const char *ramdacSymbols[] = {
"BTramdacProbe",
"RamDacCreateInfoRec",
"RamDacDestroyInfoRec",
"RamDacFreeRec",
"RamDacGetHWIndex",
"RamDacHandleColormaps",
"RamDacInit",
"xf86CreateCursorInfoRec",
"xf86InitCursor",
NULL
};
static const char *xaaSymbols[] = {
"XAACreateInfoRec",
"XAADestroyInfoRec",
"XAAGCIndex",
"XAAInit",
NULL
};
static const char *fbSymbols[] = {
"fbPictureInit",
"fbScreenInit",
NULL
};
#ifdef XFree86LOADER
static MODULESETUPPROTO(tgaSetup);
static XF86ModuleVersionInfo tgaVersRec =
{
"tga",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XF86_VERSION_CURRENT,
TGA_MAJOR_VERSION, TGA_MINOR_VERSION, TGA_PATCHLEVEL,
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_VIDEODRV,
{0,0,0,0}
};
XF86ModuleData tgaModuleData = { &tgaVersRec, tgaSetup, NULL };
pointer
tgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = FALSE;
if (!setupDone) {
setupDone = TRUE;
xf86AddDriver(&TGA, module, 0);
LoaderRefSymLists(ramdacSymbols, fbSymbols, xaaSymbols, NULL);
return (pointer)1;
} else {
if (errmaj) *errmaj = LDR_ONCEONLY;
return NULL;
}
}
#endif
static unsigned int fb_offset_presets[4] = {
TGA_8PLANE_FB_OFFSET,
TGA_24PLANE_FB_OFFSET,
0xffffffff,
TGA_24PLUSZ_FB_OFFSET
};
static char *tga_cardnames[4] = {
"TGA 8 Plane",
"TGA 24 Plane",
NULL,
"TGA 24 Plane 3D"
};
static Bool
TGAGetRec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate != NULL)
return TRUE;
pScrn->driverPrivate = xnfcalloc(sizeof(TGARec), 1);
return TRUE;
}
static void
TGAFreeRec(ScrnInfoPtr pScrn)
{
TGAPtr pTga;
if (pScrn->driverPrivate == NULL)
return;
pTga = TGAPTR(pScrn);
if(pTga->buffers[0])
free(pTga->buffers[0]);
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
return;
}
static const OptionInfoRec *
TGAAvailableOptions(int chipid, int busid)
{
return TGAOptions;
}
static void
TGAIdentify(int flags)
{
xf86PrintChipsets(TGA_NAME, "driver for Digital chipsets", TGAChipsets);
return;
}
static Bool
TGAProbe(DriverPtr drv, int flags)
{
int i;
GDevPtr *devSections;
int *usedChips;
int numDevSections;
int numUsed;
Bool foundScreen = FALSE;
if ((numDevSections = xf86MatchDevice(TGA_DRIVER_NAME,
&devSections)) <= 0) {
return FALSE;
}
if (xf86GetPciVideoInfo() == NULL) {
return FALSE;
}
numUsed = xf86MatchPciInstances(TGA_NAME, PCI_VENDOR_DIGITAL,
TGAChipsets, TGAPciChipsets, devSections, numDevSections,
drv, &usedChips);
xfree(devSections);
if (numUsed <= 0)
return FALSE;
if (flags & PROBE_DETECT)
foundScreen = TRUE;
else for (i = 0; i < numUsed; i++) {
ScrnInfoPtr pScrn = NULL;
if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
TGAPciChipsets, NULL, NULL,
NULL, NULL, NULL))) {
pScrn->driverVersion = VERSION;
pScrn->driverName = TGA_DRIVER_NAME;
pScrn->name = TGA_NAME;
pScrn->Probe = TGAProbe;
pScrn->PreInit = TGAPreInit;
pScrn->ScreenInit = TGAScreenInit;
pScrn->SwitchMode = TGASwitchMode;
pScrn->AdjustFrame = TGAAdjustFrame;
pScrn->EnterVT = TGAEnterVT;
pScrn->LeaveVT = TGALeaveVT;
pScrn->FreeScreen = TGAFreeScreen;
pScrn->ValidMode = TGAValidMode;
foundScreen = TRUE;
}
}
xfree(usedChips);
return foundScreen;
}
#if 0
static int *
GetAccelPitchValues(ScrnInfoPtr pScrn)
{
int *linePitches = NULL;
int i, n = 0;
int *linep = NULL;
for (i = 0; linep[i] != 0; i++) {
if (linep[i] != -1) {
n++;
linePitches = xnfrealloc(linePitches, n * sizeof(int));
linePitches[n - 1] = i << 5;
}
}
if (n > 0) {
linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
linePitches[n] = 0;
}
return linePitches;
}
#endif
static Bool
TGAPreInit(ScrnInfoPtr pScrn, int flags)
{
pciVideoPtr pciPtr;
TGAPtr pTga;
MessageType from;
int i;
ClockRangePtr clockRanges;
pointer Base;
if (flags & PROBE_DETECT) return FALSE;
if (!xf86LoadSubModule(pScrn, "ramdac"))
return FALSE;
xf86LoaderReqSymLists(ramdacSymbols, NULL);
if (!TGAGetRec(pScrn)) {
return FALSE;
}
pTga = TGAPTR(pScrn);
pScrn->monitor = pScrn->confScreen->monitor;
if (pScrn->numEntities > 1)
return FALSE;
for (i = 0; i < pScrn->numEntities; i++) {
pTga->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
if (pTga->pEnt->resources) return FALSE;
pTga->Chipset = pTga->pEnt->chipset;
pScrn->chipset = (char *)xf86TokenToString(TGAChipsets,
pTga->pEnt->chipset);
if (pTga->pEnt->location.type == BUS_PCI) {
pciPtr = xf86GetPciInfoForEntity(pTga->pEnt->index);
pTga->PciInfo = pciPtr;
pTga->PciTag = pciTag(pTga->PciInfo->bus,
pTga->PciInfo->device,
pTga->PciInfo->func);
}
else
return FALSE;
}
if (pScrn->chipset == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"ChipID 0x%04X is not recognised\n", pTga->Chipset);
return FALSE;
}
if (pTga->Chipset < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Chipset \"%s\" is not recognised\n", pScrn->chipset);
return FALSE;
}
from = X_PROBED;
xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
pTga->PciTag = pciTag(pTga->PciInfo->bus, pTga->PciInfo->device,
pTga->PciInfo->func);
if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
return FALSE;
} else {
switch (pScrn->depth) {
case 8:
case 24:
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Given depth (%d) is not supported by this driver\n",
pScrn->depth);
return FALSE;
}
}
xf86CollectOptions(pScrn, NULL);
if (!(pTga->Options = xalloc(sizeof(TGAOptions))))
return FALSE;
memcpy(pTga->Options, TGAOptions, sizeof(TGAOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTga->Options);
if (xf86ReturnOptValBool(pTga->Options, OPTION_PCI_RETRY, FALSE)) {
pTga->UsePCIRetry = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
}
if(xf86ReturnOptValBool(pTga->Options, OPTION_SYNC_ON_GREEN, FALSE)) {
pTga->SyncOnGreen = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");
}
if(xf86ReturnOptValBool(pTga->Options, OPTION_DAC_6_BIT, FALSE)) {
pTga->Dac6Bit = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "6 bit DAC enabled\n");
}
if(xf86ReturnOptValBool(pTga->Options, OPTION_NOXAAPOLYSEGMENT, FALSE)) {
pTga->NoXaaPolySegment = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XAA PolySegment() disabled\n");
}
if (pScrn->depth > 8) {
rgb zeros = {0, 0, 0};
if (!xf86SetWeight(pScrn, zeros, zeros)) {
return FALSE;
} else {
;
}
}
if (!xf86SetDefaultVisual(pScrn, -1)) {
return FALSE;
} else {
if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
" (%s) is not supported at depth %d\n",
xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
return FALSE;
}
}
{
Gamma zeros = {0.0, 0.0, 0.0};
if (!xf86SetGamma(pScrn, zeros)) {
return FALSE;
}
}
if (pScrn->depth == 8) {
pScrn->rgbBits = 8;
if(pTga->Dac6Bit)
pScrn->rgbBits = 6;
}
from = X_DEFAULT;
pTga->HWCursor = TRUE;
if (xf86GetOptValBool(pTga->Options, OPTION_HW_CURSOR, &pTga->HWCursor))
from = X_CONFIG;
if (xf86ReturnOptValBool(pTga->Options, OPTION_SW_CURSOR, FALSE)) {
from = X_CONFIG;
pTga->HWCursor = FALSE;
}
if(pScrn->depth != 8) {
pTga->HWCursor = FALSE;
from = X_WARNING;
xf86DrvMsg(pScrn->scrnIndex, from,
"Hardware cursor currently only works with BT485 ramdac\n");
}
xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
pTga->HWCursor ? "HW" : "SW");
if (xf86ReturnOptValBool(pTga->Options, OPTION_NOACCEL, FALSE)) {
pTga->NoAccel = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
}
if (pTga->pEnt->device->MemBase != 0) {
pTga->CardAddress = pTga->pEnt->device->MemBase;
from = X_CONFIG;
} else {
pTga->CardAddress = pTga->PciInfo->memBase[0] & 0xFFC00000;
}
pTga->FbAddress = pTga->CardAddress;
pTga->IOAddress = pTga->CardAddress + TGA_REGS_OFFSET;
if(pTga->pEnt->device->videoRam) {
switch(pTga->pEnt->device->videoRam) {
case 2048:
pTga->CardType = TYPE_TGA_8PLANE;
break;
case 8192:
pTga->CardType = TYPE_TGA_24PLANE;
break;
case 16384:
pTga->CardType = TYPE_TGA_24PLUSZ;
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"%d KB video RAM specified, driver only supports 2048, 8192, or 16384 KB cards\n",
pTga->pEnt->device->videoRam);
return FALSE;
}
}
else {
switch (pTga->Chipset)
{
case PCI_CHIP_TGA2:
Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
pTga->PciTag, pTga->IOAddress, 0x1000);
pTga->CardType = (*(unsigned int *)((char *)Base+TGA_REVISION_REG) >> 21) & 0x3;
pTga->CardType ^= (pTga->CardType == 1) ? 0 : 3;
xf86UnMapVidMem(pScrn->scrnIndex, Base, 0x1000);
break;
case PCI_CHIP_DEC21030:
Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
pTga->PciTag, pTga->FbAddress, 4);
pTga->CardType = (*(unsigned int *)Base >> 12) & 0xf;
xf86UnMapVidMem(pScrn->scrnIndex, Base, 4);
break;
}
}
switch (pTga->CardType) {
case TYPE_TGA_8PLANE:
case TYPE_TGA_24PLANE:
case TYPE_TGA_24PLUSZ:
xf86DrvMsg(pScrn->scrnIndex, from, "Card Name: \"%s\"\n",
tga_cardnames[pTga->CardType]);
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Card \"0x%02x\" is not recognised\n", pTga->CardType);
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Assuming 8 plane TGA with 2MB frame buffer\n");
pTga->CardType = TYPE_TGA_8PLANE;
break;
}
pTga->FbAddress += fb_offset_presets[pTga->CardType];
if (!(((pScrn->depth == 8) && (pTga->CardType == TYPE_TGA_8PLANE)) ||
((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLANE)) ||
((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLUSZ)))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Given depth (%d) is not supported by this card\n",
pScrn->depth);
return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
(unsigned long)pTga->FbAddress);
xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
(unsigned long)pTga->IOAddress);
if (xf86RegisterResources(pTga->pEnt->index, NULL, ResExclusive)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"xf86RegisterResources() found resource conflicts\n");
TGAFreeRec(pScrn);
return FALSE;
}
pTga->HwBpp = pScrn->bitsPerPixel;
if (pTga->pEnt->device->videoRam != 0) {
pScrn->videoRam = pTga->pEnt->device->videoRam;
from = X_CONFIG;
} else {
switch (pTga->CardType) {
case TYPE_TGA_8PLANE:
pScrn->videoRam = 2*1024;
break;
case TYPE_TGA_24PLANE:
pScrn->videoRam = 8*1024;
break;
case TYPE_TGA_24PLUSZ:
pScrn->videoRam = 16*1024;
break;
}
}
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
pScrn->videoRam);
pTga->FbMapSize = pScrn->videoRam * 1024;
if (xf86LoadSubModule(pScrn, "fb") == NULL) {
TGAFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(fbSymbols, NULL);
if (!pTga->NoAccel || pTga->HWCursor) {
if (!xf86LoadSubModule(pScrn, "xaa")) {
TGAFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(xaaSymbols, NULL);
}
pTga->RamDac = NULL;
if (pTga->CardType != TYPE_TGA_8PLANE) {
pTga->RamDacRec = NULL;
pTga->RamDac = NULL;
} else {
pTga->RamDacRec = RamDacCreateInfoRec();
switch (pTga->Chipset)
{
case PCI_CHIP_DEC21030:
pTga->RamDacRec->ReadDAC = tgaBTInIndReg;
pTga->RamDacRec->WriteDAC = tgaBTOutIndReg;
pTga->RamDacRec->ReadAddress = tgaBTReadAddress;
pTga->RamDacRec->WriteAddress = tgaBTWriteAddress;
pTga->RamDacRec->ReadData = tgaBTReadData;
pTga->RamDacRec->WriteData = tgaBTWriteData;
break;
case PCI_CHIP_TGA2:
pTga->RamDacRec->ReadDAC = tga2BTInIndReg;
pTga->RamDacRec->WriteDAC = tga2BTOutIndReg;
pTga->RamDacRec->ReadAddress = tga2BTReadAddress;
pTga->RamDacRec->WriteAddress = tga2BTWriteAddress;
pTga->RamDacRec->ReadData = tga2BTReadData;
pTga->RamDacRec->WriteData = tga2BTWriteData;
break;
}
if (!RamDacInit(pScrn, pTga->RamDacRec)) {
RamDacDestroyInfoRec(pTga->RamDacRec);
return FALSE;
}
TGAMapMem(pScrn);
pTga->RamDac = BTramdacProbe(pScrn, BTramdacs);
TGAUnmapMem(pScrn);
if (pTga->RamDac == NULL)
return FALSE;
}
pScrn->progClock = TRUE;
pTga->MinClock = 16250;
xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
pTga->MinClock / 1000);
if (pTga->pEnt->device->dacSpeeds[0]) {
int speed = 0;
switch (pScrn->bitsPerPixel) {
case 8:
speed = pTga->pEnt->device->dacSpeeds[DAC_BPP8];
break;
case 32:
speed = pTga->pEnt->device->dacSpeeds[DAC_BPP32];
break;
}
if (speed == 0)
pTga->MaxClock = pTga->pEnt->device->dacSpeeds[0];
else
pTga->MaxClock = speed;
from = X_CONFIG;
} else {
switch (pTga->Chipset) {
case PCI_CHIP_DEC21030:
pTga->MaxClock = 135000;
break;
case PCI_CHIP_TGA2:
pTga->MaxClock = 170000;
break;
}
}
xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
pTga->MaxClock / 1000);
clockRanges = xnfcalloc(sizeof(ClockRange), 1);
clockRanges->next = NULL;
clockRanges->minClock = pTga->MinClock;
clockRanges->maxClock = pTga->MaxClock;
clockRanges->clockIndex = -1;
clockRanges->interlaceAllowed = FALSE;
clockRanges->doubleScanAllowed = FALSE;
if(pScrn->display->virtualX || pScrn->display->virtualY) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"TGA does not support a virtual desktop\n");
pScrn->display->virtualX = 0;
pScrn->display->virtualY = 0;
}
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
pScrn->display->modes, clockRanges,
NULL, 256, 2048,
pScrn->bitsPerPixel, 128, 2048,
pScrn->display->virtualX,
pScrn->display->virtualY,
pTga->FbMapSize,
LOOKUP_BEST_REFRESH);
if (i == -1) {
TGAFreeRec(pScrn);
return FALSE;
}
xf86PruneDriverModes(pScrn);
if (i == 0 || pScrn->modes == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
TGAFreeRec(pScrn);
return FALSE;
}
if(i > 1) {
DisplayModePtr mp1 = NULL, mp2 = NULL;
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"TGA only supports one mode, using first mode.\n");
mp1 = pScrn->modes->next;
mp2 = mp1;
while(mp1 && mp1->next != mp1) {
mp1 = mp1->next;
xf86DeleteMode(&(pScrn->modes), mp2);
mp2 = mp1;
}
}
xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
pScrn->currentMode = pScrn->modes;
if (pTga->Chipset == PCI_CHIP_TGA2) {
TGA2SetupMode(pScrn);
}
xf86PrintModes(pScrn);
xf86SetDpi(pScrn, 0, 0);
return TRUE;
}
static Bool
TGAMapMem(ScrnInfoPtr pScrn)
{
TGAPtr pTga;
pTga = TGAPTR(pScrn);
pTga->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
pTga->PciTag,
pTga->IOAddress, 0x100000);
if (pTga->IOBase == NULL)
return FALSE;
pTga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
pTga->PciTag,
(unsigned long)pTga->FbAddress,
pTga->FbMapSize);
if (pTga->FbBase == NULL)
return FALSE;
if (pTga->Chipset == PCI_CHIP_DEC21030)
return TRUE;
pTga->ClkBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
pTga->PciTag,
(unsigned long)pTga->CardAddress + TGA2_CLOCK_OFFSET,
0x10000);
if (pTga->ClkBase == NULL)
return FALSE;
pTga->DACBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
pTga->PciTag,
(unsigned long)pTga->CardAddress + TGA2_RAMDAC_OFFSET,
0x10000);
if (pTga->DACBase == NULL)
return FALSE;
pTga->HACKBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
pTga->PciTag,
(unsigned long)pTga->FbAddress - getpagesize(),
getpagesize());
if (pTga->HACKBase == NULL)
return FALSE;
return TRUE;
}
static Bool
TGAUnmapMem(ScrnInfoPtr pScrn)
{
TGAPtr pTga;
pTga = TGAPTR(pScrn);
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->IOBase, 0x100000);
pTga->IOBase = NULL;
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->FbBase, pTga->FbMapSize);
pTga->FbBase = NULL;
if (pTga->Chipset == PCI_CHIP_DEC21030)
return TRUE;
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->ClkBase, 0x10000);
pTga->ClkBase = NULL;
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->DACBase, 0x10000);
pTga->DACBase = NULL;
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->HACKBase, getpagesize());
pTga->HACKBase = NULL;
return TRUE;
}
static void
TGASave(ScrnInfoPtr pScrn)
{
TGAPtr pTga;
TGARegPtr tgaReg;
RamDacHWRecPtr pBT;
RamDacRegRecPtr BTreg;
pTga = TGAPTR(pScrn);
tgaReg = &pTga->SavedReg;
DEC21030Save(pScrn, tgaReg);
if (pTga->RamDac) {
pBT = RAMDACHWPTR(pScrn);
BTreg = &pBT->SavedReg;
(*pTga->RamDac->Save)(pScrn, pTga->RamDacRec, BTreg);
} else switch (pTga->Chipset)
{
case PCI_CHIP_TGA2:
IBM561ramdacSave(pScrn, pTga->Ibm561saveReg);
break;
case PCI_CHIP_DEC21030:
BT463ramdacSave(pScrn, pTga->Bt463saveReg);
break;
}
}
static Bool
TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
int ret = -1;
TGAPtr pTga;
TGARegPtr tgaReg;
RamDacHWRecPtr pBT;
RamDacRegRecPtr BTreg;
pTga = TGAPTR(pScrn);
pScrn->vtSema = TRUE;
ret = DEC21030Init(pScrn, mode);
if (pTga->Chipset == PCI_CHIP_TGA2 && pTga->RamDac == NULL)
IBM561ramdacHWInit(pScrn);
if (!ret)
return FALSE;
tgaReg = &pTga->ModeReg;
DEC21030Restore(pScrn, tgaReg);
if (pTga->RamDac != NULL) {
pBT = RAMDACHWPTR(pScrn);
BTreg = &pBT->ModeReg;
(*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
if (pTga->Chipset == PCI_CHIP_TGA2) {
pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x0c);
}
pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff);
} else {
switch (pTga->Chipset) {
case PCI_CHIP_TGA2:
IBM561ramdacRestore(pScrn, pTga->Ibm561modeReg);
break;
case PCI_CHIP_DEC21030:
BT463ramdacRestore(pScrn, pTga->Bt463modeReg);
break;
}
}
return TRUE;
}
static void
TGARestore(ScrnInfoPtr pScrn)
{
TGAPtr pTga;
TGARegPtr tgaReg;
RamDacHWRecPtr pBT;
RamDacRegRecPtr BTreg;
pTga = TGAPTR(pScrn);
tgaReg = &pTga->SavedReg;
tgaReg->tgaRegs[0x0A] = 25175;
DEC21030Restore(pScrn, tgaReg);
if (pTga->RamDac != NULL) {
pBT = RAMDACHWPTR(pScrn);
BTreg = &pBT->SavedReg;
(*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
if (pTga->Chipset == PCI_CHIP_TGA2) {
pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x00);
}
pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff);
} else switch (pTga->Chipset) {
case PCI_CHIP_TGA2:
IBM561ramdacRestore(pScrn, pTga->Ibm561saveReg);
break;
case PCI_CHIP_DEC21030:
BT463ramdacRestore(pScrn, pTga->Bt463saveReg);
break;
}
if (pTga->HWCursor)
TGARestoreHWCursor(pScrn);
}
static Bool
TGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn;
TGAPtr pTga;
int ret;
VisualPtr visual;
pScrn = xf86Screens[pScreen->myNum];
pTga = TGAPTR(pScrn);
if (!TGAMapMem(pScrn))
return FALSE;
#if 1
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MODE 0x%x\n",
TGA_READ_REG(TGA_MODE_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VALID 0x%x\n",
TGA_READ_REG(TGA_VALID_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DEEP 0x%x\n",
TGA_READ_REG(TGA_DEEP_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXSH 0x%x\n",
TGA_READ_REG(TGA_PIXELSHIFT_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ROP 0x%x\n",
TGA_READ_REG(TGA_RASTEROP_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HORIZ 0x%x\n",
TGA_READ_REG(TGA_HORIZ_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VERT 0x%x\n",
TGA_READ_REG(TGA_VERT_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXMSK 0x%x\n",
TGA_READ_REG(TGA_PIXELMASK_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "REV 0x%x\n",
TGA_READ_REG(TGA_REVISION_REG));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VADDR 0x%x\n",
TGA_READ_REG(TGA_BASE_ADDR_REG));
#endif
TGASave(pScrn);
TGAModeInit(pScrn, pScrn->currentMode);
TGASaveScreen(pScreen, SCREEN_SAVER_ON);
miClearVisualTypes();
if (pScrn->bitsPerPixel > 8) {
if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
pScrn->defaultVisual))
return FALSE;
} else {
if (!miSetVisualTypes(pScrn->depth,
miGetDefaultVisualMask(pScrn->depth),
pScrn->rgbBits, pScrn->defaultVisual))
return FALSE;
}
miSetPixmapDepths ();
switch (pScrn->bitsPerPixel) {
case 8:
case 32:
ret = fbScreenInit(pScreen, pTga->FbBase, pScrn->virtualX,
pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
pScrn->displayWidth, pScrn->bitsPerPixel);
break;
default:
xf86DrvMsg(scrnIndex, X_ERROR,
"Internal error: invalid bpp (%d) in TGAScrnInit\n",
pScrn->bitsPerPixel);
ret = FALSE;
break;
}
if (!ret)
return FALSE;
xf86SetBlackWhitePixels(pScreen);
if (pScrn->bitsPerPixel > 8) {
visual = pScreen->visuals + pScreen->numVisuals;
while (--visual >= pScreen->visuals) {
if ((visual->class | DynamicClass) == DirectColor) {
visual->offsetRed = pScrn->offset.red;
visual->offsetGreen = pScrn->offset.green;
visual->offsetBlue = pScrn->offset.blue;
visual->redMask = pScrn->mask.red;
visual->greenMask = pScrn->mask.green;
visual->blueMask = pScrn->mask.blue;
}
}
}
fbPictureInit (pScreen, 0, 0);
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
xf86SetSilkenMouse(pScreen);
if (pScrn->bitsPerPixel == 8) {
TGA_WRITE_REG(SIMPLE | X11 | BPP8PACKED, TGA_MODE_REG);
TGA_WRITE_REG(0x3 | BPP8PACKED, TGA_RASTEROP_REG);
if (pTga->Chipset == PCI_CHIP_TGA2)
TGA_WRITE_REG(2 << 28, TGA_DEEP_REG);
} else {
TGA_WRITE_REG(SIMPLE | X11 | BPP24, TGA_MODE_REG);
TGA_WRITE_REG(0x3 | BPP24, TGA_RASTEROP_REG);
if (pTga->Chipset == PCI_CHIP_TGA2)
TGA_WRITE_REG((7 << 2) | 1 | (2 << 28), TGA_DEEP_REG);
}
TGA_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
TGA_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
if (!pTga->NoAccel) {
switch (pTga->Chipset)
{
case PCI_CHIP_TGA2:
case PCI_CHIP_DEC21030:
if(DEC21030AccelInit(pScreen) == FALSE) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"XAA Initialization failed\n");
return(FALSE);
}
break;
}
}
miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
if (pTga->HWCursor) {
if(!TGAHWCursorInit(pScreen)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Hardware cursor initialization failed\n");
return(FALSE);
}
}
if (!miCreateDefColormap(pScreen))
return FALSE;
if ((pScrn->bitsPerPixel==8) &&
(!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits,
CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)))
return FALSE;
pTga->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = TGACloseScreen;
pScreen->SaveScreen = TGASaveScreen;
if(xf86DPMSInit(pScreen, TGADisplayPowerManagementSet, 0) == FALSE)
ErrorF("DPMS initialization failed!\n");
{
XF86VideoAdaptorPtr *ptr;
int n;
pScrn->memPhysBase = pTga->FbAddress;
pScrn->fbOffset = 0;
n = xf86XVListGenericAdaptors(pScrn,&ptr);
if(n) {
xf86XVScreenInit(pScreen, ptr, n);
}
}
if (serverGeneration == 1) {
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
}
TGASaveScreen(pScreen, SCREEN_SAVER_OFF);
return TRUE;
}
static Bool
TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
return TGAModeInit(xf86Screens[scrnIndex], mode);
}
static void
TGAAdjustFrame(int scrnIndex, int x, int y, int flags)
{
return;
}
static Bool
TGAEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
if (!TGAModeInit(pScrn, pScrn->currentMode))
return FALSE;
return TRUE;
}
static void
TGALeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
TGARestore(pScrn);
return;
}
static Bool
TGACloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
TGAPtr pTga = TGAPTR(pScrn);
TGARestore(pScrn);
TGASync(pScrn);
TGAUnmapMem(pScrn);
if(pTga->AccelInfoRec)
XAADestroyInfoRec(pTga->AccelInfoRec);
pScrn->vtSema = FALSE;
pScreen->CloseScreen = pTga->CloseScreen;
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
static void
TGAFreeScreen(int scrnIndex, int flags)
{
RamDacFreeRec(xf86Screens[scrnIndex]);
TGAFreeRec(xf86Screens[scrnIndex]);
}
static ModeStatus
TGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
if (mode->Flags & V_INTERLACE)
return(MODE_BAD);
return(MODE_OK);
}
static Bool
TGASaveScreen(ScreenPtr pScreen, int mode)
{
TGAPtr pTga;
ScrnInfoPtr pScrn;
int valid_reg = 0;
Bool unblank;
pScrn = xf86Screens[pScreen->myNum];
pTga = TGAPTR(pScrn);
valid_reg = TGA_READ_REG(TGA_VALID_REG);
valid_reg &= 0xFFFFFFFC;
unblank = xf86IsUnblank(mode);
if(unblank == FALSE)
valid_reg |= 0x3;
else
valid_reg |= 0x1;
TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
return TRUE;
}
static void
TGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
int flags)
{
TGAPtr pTga;
int valid_reg = 0;
pTga = TGAPTR(pScrn);
valid_reg = TGA_READ_REG(TGA_VALID_REG);
valid_reg &= 0xFFFFFFFC;
switch(PowerManagementMode) {
case DPMSModeOn:
valid_reg |= 0x1;
break;
case DPMSModeStandby:
case DPMSModeSuspend:
valid_reg |= 0x3;
break;
case DPMSModeOff:
valid_reg |= 0x2;
break;
default:
ErrorF("Invalid PowerManagementMode %d passed to TGADisplayPowerManagementSet\n", PowerManagementMode);
break;
}
TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
return;
}
static void
TGARestoreHWCursor(ScrnInfoPtr pScrn)
{
unsigned char *p = NULL;
int i = 0;
TGAPtr pTga;
static const CARD32 tga_cursor_source[128] = {
0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
0x000000ff, 0x00000000,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
pTga = TGAPTR(pScrn);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, 0);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, 0);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, 0);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, 0);
pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x02);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
p = (unsigned char *)tga_cursor_source;
for(i = 0; i < 512; i++)
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *p++);
for(i = 0; i < 512; i++)
pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, 0xff);
return;
}
void
TGASync(ScrnInfoPtr pScrn)
{
TGAPtr pTga = TGAPTR(pScrn);
unsigned int stat;
switch (pTga->Chipset)
{
case PCI_CHIP_TGA2:
mem_barrier();
while((stat = TGA_READ_REG(TGA_CMD_STAT_REG))) {
if (((stat >> 8) & 0xff) == ((stat >> 16) & 0xff)) {
TGA_WRITE_REG(0, TGA_CMD_STAT_REG);
mem_barrier();
#if 0
ErrorF("TGASync: writing CMD_STATUS\n");
#endif
}
usleep(1000);
}
break;
case PCI_CHIP_DEC21030:
#if 0
while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01);
#endif
break;
}
return;
}