#include "fb.h"
#include "mibank.h"
#include "micmap.h"
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86Version.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "xf86cmap.h"
#include "shadowfb.h"
#include "vgaHW.h"
#include "xf86DDC.h"
#include "xf86RAC.h"
#include "xf86Resources.h"
#include "compiler.h"
#include "xf86int10.h"
#include "vbe.h"
#include "cyrix.h"
#define _XF86DGA_SERVER_
#include "extensions/xf86dgastr.h"
#include "opaque.h"
#define DPMS_SERVER
#include "extensions/dpms.h"
static const OptionInfoRec * CYRIXAvailableOptions(int chip, int busid);
static void CYRIXIdentify(int flags);
static Bool CYRIXProbe(DriverPtr drv, int flags);
static Bool CYRIXPreInit(ScrnInfoPtr pScrn, int flags);
static Bool CYRIXScreenInit(int Index, ScreenPtr pScreen, int argc,
char **argv);
static Bool CYRIXEnterVT(int scrnIndex, int flags);
static void CYRIXLeaveVT(int scrnIndex, int flags);
static Bool CYRIXCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool CYRIXSaveScreen(ScreenPtr pScreen, int mode);
static Bool CYRIXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
static void CYRIXAdjustFrame(int scrnIndex, int x, int y, int flags);
static void CYRIXFreeScreen(int scrnIndex, int flags);
static int CYRIXFindIsaDevice(GDevPtr dev);
static ModeStatus CYRIXValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flags);
static void CYRIXSave(ScrnInfoPtr pScrn);
static void CYRIXRestore(ScrnInfoPtr pScrn);
static Bool CYRIXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
static void CYRIXRestorePalette(ScrnInfoPtr pScrn);
static void CYRIXSavePalette(ScrnInfoPtr pScrn);
void CYRIXSetRead(int bank);
void CYRIXSetWrite(int bank);
void CYRIXSetReadWrite(int bank);
#define VERSION 4000
#define CYRIX_NAME "CYRIX"
#define CYRIX_DRIVER_NAME "cyrix"
#define CYRIX_MAJOR_VERSION 1
#define CYRIX_MINOR_VERSION 0
#define CYRIX_PATCHLEVEL 0
#define VGA_REGION 2
enum GenericTypes {
CHIP_CYRIXmediagx
};
DriverRec CYRIX = {
VERSION,
CYRIX_DRIVER_NAME,
CYRIXIdentify,
CYRIXProbe,
CYRIXAvailableOptions,
NULL,
0
};
static SymTabRec CYRIXChipsets[] = {
{ CHIP_CYRIXmediagx, "mediagx" },
{ -1, NULL }
};
static IsaChipsets CYRIXISAChipsets[] = {
{ CHIP_CYRIXmediagx, RES_EXCLUSIVE_VGA },
{ -1, 0 }
};
typedef enum {
OPTION_SW_CURSOR,
OPTION_HW_CURSOR,
OPTION_NOACCEL,
OPTION_NOCOMPRESS,
OPTION_SHADOW_FB,
OPTION_ROTATE
} CYRIXOpts;
static const OptionInfoRec CYRIXOptions[] = {
{ OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_NOCOMPRESS, "NoCompression",OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
static const char *vgahwSymbols[] = {
"vgaHWFreeHWRec",
"vgaHWGetHWRec",
"vgaHWGetIOBase",
"vgaHWGetIndex",
"vgaHWHandleColormaps",
"vgaHWInit",
"vgaHWLock",
"vgaHWMapMem",
"vgaHWProtect",
"vgaHWRestore",
"vgaHWSave",
"vgaHWSaveScreen",
"vgaHWUnlock",
NULL
};
static const char *fbSymbols[] = {
"fbScreenInit",
"fbPictureInit",
NULL
};
static const char *xaaSymbols[] = {
"XAACreateInfoRec",
"XAADestroyInfoRec",
NULL
};
static const char *shadowSymbols[] = {
"ShadowFBInit",
NULL
};
#ifdef XFree86LOADER
static const char *vbeSymbols[] = {
"VBEInit",
"vbeDoEDID",
"vbeFree",
NULL
};
#endif
#define ENTER TRUE
#define LEAVE FALSE
#ifdef XFree86LOADER
static MODULESETUPPROTO(cyrixSetup);
static XF86ModuleVersionInfo cyrixVersRec =
{
"cyrix",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XF86_VERSION_CURRENT,
CYRIX_MAJOR_VERSION, CYRIX_MINOR_VERSION, CYRIX_PATCHLEVEL,
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_VIDEODRV,
{0,0,0,0}
};
XF86ModuleData cyrixModuleData = { &cyrixVersRec, cyrixSetup, NULL };
pointer
cyrixSetup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = FALSE;
if (!setupDone) {
setupDone = TRUE;
xf86AddDriver(&CYRIX, module, 0);
LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, vbeSymbols, shadowSymbols, NULL);
return (pointer)TRUE;
}
if (errmaj) *errmaj = LDR_ONCEONLY;
return NULL;
}
#endif
static Bool
CYRIXGetRec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate != NULL)
return TRUE;
pScrn->driverPrivate = xnfcalloc(sizeof(CYRIXPrivate), 1);
if (pScrn->driverPrivate == NULL)
return FALSE;
return TRUE;
}
static void
CYRIXFreeRec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate == NULL)
return;
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
}
static void
CYRIXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
{
unsigned char DPMSCont, PMCont, temp;
outb(0x3C4, 0x0E);
temp = inb(0x3C5);
outb(0x3C5, 0xC2);
outb(0x83C8, 0x04);
PMCont = inb(0x83C6) & 0xFC;
outb(0x3CE, 0x23);
DPMSCont = inb(0x3CF) & 0xFC;
switch (PowerManagementMode)
{
case DPMSModeOn:
PMCont |= 0x03;
DPMSCont |= 0x00;
break;
case DPMSModeStandby:
PMCont |= 0x02;
DPMSCont |= 0x01;
break;
case DPMSModeSuspend:
PMCont |= 0x02;
DPMSCont |= 0x02;
break;
case DPMSModeOff:
PMCont |= 0x00;
DPMSCont |= 0x03;
break;
}
outb(0x3CF, DPMSCont);
outb(0x83C8, 0x04);
outb(0x83C6, PMCont);
outw(0x3C4, (temp<<8) | 0x0E);
}
static void
CYRIXIdentify(int flags)
{
xf86PrintChipsets(CYRIX_NAME, "driver for Cyrix MediaGX Processors", CYRIXChipsets);
}
static const OptionInfoRec *
CYRIXAvailableOptions(int chip, int busid)
{
return CYRIXOptions;
}
#define PCI_CHIP_CYRIX5510 0x0000
#define PCI_CHIP_CYRIX5520 0x0002
#define PCI_CHIP_CYRIX5530 0x0104
static PciChipsets CYRIXPCIchipsets[] = {
{ CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5510, RES_EXCLUSIVE_VGA },
{ CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5520, RES_EXCLUSIVE_VGA },
{ CHIP_CYRIXmediagx, PCI_CHIP_CYRIX5530, RES_EXCLUSIVE_VGA },
{ -1, -1, RES_UNDEFINED }
};
static Bool
CYRIXProbe(DriverPtr drv, int flags)
{
int i, numDevSections, numUsed, *usedChips;
GDevPtr *devSections;
ScrnInfoPtr pScrn;
Bool foundScreen = FALSE;
if ((numDevSections = xf86MatchDevice(CYRIX_DRIVER_NAME,
&devSections)) <= 0) {
#ifdef DEBUG
xf86ErrorFVerb(3,"%s: No Device section found.\n",CYRIX_NAME);
#endif
return FALSE;
}
#ifdef DEBUG
xf86ErrorFVerb(3,"%s: Device Sections found: %d\n",CYRIX_NAME, numDevSections);
#endif
if (xf86GetPciVideoInfo() ) {
numUsed = xf86MatchPciInstances(CYRIX_NAME, PCI_VENDOR_CYRIX,
CYRIXChipsets, CYRIXPCIchipsets,
devSections,numDevSections,
drv, &usedChips);
if (numUsed > 0) {
if (flags & PROBE_DETECT)
foundScreen = TRUE;
else for (i = 0; i < numUsed; i++) {
ScrnInfoPtr pScrn = NULL;
if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
CYRIXPCIchipsets,NULL, NULL,
NULL, NULL, NULL))) {
pScrn->driverVersion = VERSION;
pScrn->driverName = CYRIX_DRIVER_NAME;
pScrn->name = CYRIX_NAME;
pScrn->Probe = CYRIXProbe;
pScrn->PreInit = CYRIXPreInit;
pScrn->ScreenInit = CYRIXScreenInit;
pScrn->SwitchMode = CYRIXSwitchMode;
pScrn->AdjustFrame = CYRIXAdjustFrame;
pScrn->LeaveVT = CYRIXLeaveVT;
pScrn->EnterVT = CYRIXEnterVT;
pScrn->FreeScreen = CYRIXFreeScreen;
pScrn->ValidMode = CYRIXValidMode;
foundScreen = TRUE;
}
}
xfree(usedChips);
}
}
numUsed = xf86MatchIsaInstances(CYRIX_NAME,CYRIXChipsets,
CYRIXISAChipsets,drv,
CYRIXFindIsaDevice,devSections,
numDevSections,&usedChips);
if(numUsed > 0) {
foundScreen = TRUE;
xfree(devSections);
if (!(flags & PROBE_DETECT)) {
for (i=0; i < numUsed; i++) {
pScrn = NULL;
if ((pScrn = xf86ConfigIsaEntity(pScrn, 0, usedChips[i],
CYRIXISAChipsets, NULL,
NULL, NULL, NULL, NULL))){
pScrn->driverVersion = VERSION;
pScrn->driverName = CYRIX_DRIVER_NAME;
pScrn->name = CYRIX_NAME;
pScrn->Probe = CYRIXProbe;
pScrn->PreInit = CYRIXPreInit;
pScrn->ScreenInit = CYRIXScreenInit;
pScrn->SwitchMode = CYRIXSwitchMode;
pScrn->AdjustFrame = CYRIXAdjustFrame;
pScrn->LeaveVT = CYRIXLeaveVT;
pScrn->EnterVT = CYRIXEnterVT;
pScrn->FreeScreen = CYRIXFreeScreen;
pScrn->ValidMode = CYRIXValidMode;
}
}
}
}
xfree(usedChips);
return (foundScreen);
}
static int
CYRIXFindIsaDevice(GDevPtr dev)
{
CARD32 CurrentValue, TestValue;
unsigned char gcr;
int vgaIOBase = VGAHW_GET_IOBASE();
(void) inb(vgaIOBase + 0x0AU);
outb(0x3C0, 0x14 | 0x20);
CurrentValue = inb(0x3C1);
outb(0x3C0, CurrentValue ^ 0x0F);
outb(0x3C0, 0x14 | 0x20);
TestValue = inb(0x3C1);
outb(0x3C0, CurrentValue);
if ((CurrentValue ^ 0x0F) != TestValue)
return -1;
outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
outb(vgaIOBase + 5, 0x00);
if (inb(vgaIOBase + 5) != 0xFF) return -1;
outb(vgaIOBase + 5, 0x57);
outb(vgaIOBase + 5, 0x4C);
if (inb(vgaIOBase + 5) != 0x00) goto fail;
if (inb(vgaIOBase + 5) != 0x00) goto fail;
outb(GX_IOPORT_INDEX, GX_IOIDX_DIR0);
outb(GX_IOPORT_INDEX, GX_IOIDX_GCR);
gcr = inb(GX_IOPORT_DATA);
if (!(gcr & 12)) goto fail;
outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
outb(vgaIOBase + 5, 0x00);
return (int)CHIP_CYRIXmediagx;
fail:
outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
outb(vgaIOBase + 5, 0x00);
return -1;
}
static void
CYRIXProbeDDC(ScrnInfoPtr pScrn, int index)
{
vbeInfoPtr pVbe;
if (xf86LoadSubModule(pScrn, "vbe")) {
pVbe = VBEInit(NULL,index);
ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
vbeFree(pVbe);
}
}
static Bool
CYRIXPreInit(ScrnInfoPtr pScrn, int flags)
{
MessageType from;
CYRIXPrvPtr pCyrix;
int videoram;
int i;
ClockRangePtr clockRanges;
unsigned int physbase, padsize;
int device_step, device_revision;
int vgaIOBase;
unsigned char gcr;
static int accelWidths[3]= {2,1024, 2048};
const char *s;
if (!CYRIXGetRec(pScrn)) return FALSE;
pCyrix = CYRIXPTR(pScrn);
pCyrix->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (pCyrix->pEnt->location.type != BUS_PCI)
return FALSE;
if (flags & PROBE_DETECT) {
CYRIXProbeDDC(pScrn, pCyrix->pEnt->index);
return TRUE;
}
if (!xf86LoadSubModule(pScrn, "vgahw"))
return FALSE;
xf86LoaderReqSymLists(vgahwSymbols, NULL);
if (!vgaHWGetHWRec(pScrn))
return FALSE;
VGAHWPTR(pScrn)->MapSize = 0x10000;
if (!vgaHWMapMem(pScrn))
return FALSE;
vgaHWGetIOBase(VGAHWPTR(pScrn));
vgaIOBase = VGAHWPTR(pScrn)->IOBase;
outb(vgaIOBase + 4, CrtcExtendedRegisterLock);
outb(vgaIOBase + 5, 0x57);
outb(vgaIOBase + 5, 0x4C);
outb(GX_IOPORT_INDEX, GX_IOIDX_DIR0);
outb(GX_IOPORT_INDEX, GX_IOIDX_GCR);
gcr = inb(GX_IOPORT_DATA);
physbase = (gcr & 3) << 30;
padsize = (gcr & 12) ? (((gcr & 12) >> 2) + 1) : 0;
if (padsize == 0) return (FALSE);
xf86ErrorF("%s: GX_BASE: 0x%x\n", CYRIX_NAME, physbase);
xf86ErrorF("%s: Scratchpad size: %d kbytes\n", CYRIX_NAME, padsize);
outb(0x22, 0xFF);
device_step = device_revision = inb(0x23);
device_step >>= 8;
device_revision &= 0xFF;
xf86ErrorF("%s: MediaGX processor ID %d revision %d\n",
CYRIX_NAME, device_step, device_revision);
pCyrix->CYRIXbltBufSize = (padsize == 4) ? 1840 : (padsize == 3) ? 1328 : 816;
pCyrix->CYRIXbltBuf1Address = 0x0E60 - pCyrix->CYRIXbltBufSize;
pCyrix->CYRIXbltBuf0Address = pCyrix->CYRIXbltBuf1Address - pCyrix->CYRIXbltBufSize;
pCyrix->GXregisters = (char*)xf86MapVidMem(pScrn->scrnIndex,
VGA_REGION, (int )physbase, 0x9000);
if (!pCyrix->GXregisters) {
ErrorF("%s: Cannot map hardware registers\n", CYRIX_NAME);
return FALSE;
}
for (i = 0; i<pScrn->numEntities; i++) {
pCyrix->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
if (pCyrix->pEnt->resources) return FALSE;
pCyrix->Chipset = pCyrix->pEnt->chipset;
pScrn->chipset = (char *)xf86TokenToString(CYRIXChipsets,
pCyrix->pEnt->chipset);
}
pScrn->monitor = pScrn->confScreen->monitor;
if (!xf86SetDepthBpp(pScrn, 8, 0, 0, Support24bppFb)) {
return FALSE;
} else {
switch (pScrn->depth) {
case 1:
case 4:
case 8:
case 15:
case 16:
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Given depth (%d) is not supported by this driver\n",
pScrn->depth);
return FALSE;
}
}
if (pScrn->depth > 8) {
rgb zeros = {0, 0, 0};
if (!xf86SetWeight(pScrn, zeros, zeros)) {
return FALSE;
} else {
;
}
}
xf86PrintDepthBpp(pScrn);
{
Gamma zeros = {0.0, 0.0, 0.0};
if (!xf86SetGamma(pScrn, zeros)) {
return FALSE;
}
}
pScrn->progClock = TRUE;
if (!CYRIXGetRec(pScrn)) {
return FALSE;
}
pCyrix = CYRIXPTR(pScrn);
xf86CollectOptions(pScrn, NULL);
if (!(pCyrix->Options = xalloc(sizeof(CYRIXOptions))))
return FALSE;
memcpy(pCyrix->Options, CYRIXOptions, sizeof(CYRIXOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCyrix->Options);
pScrn->rgbBits = 6;
from = X_DEFAULT;
pCyrix->HWCursor = FALSE;
if (xf86IsOptionSet(pCyrix->Options, OPTION_HW_CURSOR)) {
from = X_CONFIG;
pCyrix->HWCursor = TRUE;
}
if (xf86IsOptionSet(pCyrix->Options, OPTION_SW_CURSOR)) {
from = X_CONFIG;
pCyrix->HWCursor = FALSE;
}
if (pCyrix->HWCursor == TRUE)
xf86DrvMsg(pScrn->scrnIndex, from, "Hardware cursor is disabled in this release\n");
if (xf86ReturnOptValBool(pCyrix->Options, OPTION_SHADOW_FB, FALSE)) {
pCyrix->ShadowFB = TRUE;
pCyrix->NoAccel = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"Using \"Shadow Framebuffer\" - acceleration disabled\n");
}
pCyrix->Rotate = 0;
if ((s = xf86GetOptValString(pCyrix->Options, OPTION_ROTATE))) {
if(!xf86NameCmp(s, "CW")) {
pCyrix->ShadowFB = TRUE;
pCyrix->NoAccel = TRUE;
pCyrix->HWCursor = FALSE;
pCyrix->Rotate = 1;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"Rotating screen clockwise - acceleration disabled\n");
} else
if(!xf86NameCmp(s, "CCW")) {
pCyrix->ShadowFB = TRUE;
pCyrix->NoAccel = TRUE;
pCyrix->HWCursor = FALSE;
pCyrix->Rotate = -1;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"Rotating screen counter clockwise - acceleration disabled\n");
} else {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"\"%s\" is not a valid value for Option \"Rotate\"\n", s);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Valid options are \"CW\" or \"CCW\"\n");
}
}
xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
pCyrix->HWCursor ? "HW" : "SW");
if (xf86IsOptionSet(pCyrix->Options, OPTION_NOACCEL)) {
pCyrix->NoAccel = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
}
pCyrix->NoCompress = FALSE;
if (xf86IsOptionSet(pCyrix->Options, OPTION_NOCOMPRESS)) {
pCyrix->NoCompress = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Compression disabled\n");
}
pCyrix->PciInfo = NULL;
pCyrix->RamDac = -1;
if (pScrn->chipset == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"ChipID 0x%04X is not recognised\n", pCyrix->Chipset);
return FALSE;
}
if (pCyrix->Chipset < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Chipset \"%s\" is not recognised\n", pScrn->chipset);
return FALSE;
}
pCyrix->EngineOperation = 0x00;
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", pScrn->chipset);
if (pCyrix->pEnt->device->MemBase != 0) {
pCyrix->FbAddress = pCyrix->pEnt->device->MemBase;
from = X_CONFIG;
} else {
from = X_PROBED;
pCyrix->FbAddress = 0x40800000;
}
xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
(unsigned long)pCyrix->FbAddress);
if (pCyrix->pEnt->device->IOBase != 0) {
pCyrix->IOAccelAddress = pCyrix->pEnt->device->IOBase;
from = X_CONFIG;
} else {
from = X_PROBED;
pCyrix->IOAccelAddress = 0x40008100;
}
xf86DrvMsg(pScrn->scrnIndex, from,"IO registers at 0x%lx\n",(unsigned long)pCyrix->IOAccelAddress);
pCyrix->HwBpp = pScrn->bitsPerPixel;
if (pCyrix->pEnt->device->videoRam != 0) {
pScrn->videoRam = pCyrix->pEnt->device->videoRam;
from = X_CONFIG;
} else {
from = X_PROBED;
outb(vgaIOBase + 4, CrtcGraphicsMemorySize);
videoram = (inb(vgaIOBase + 5) * 64);
pScrn->videoRam = videoram & 0xFFFFFC00;
}
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
pScrn->videoRam);
pCyrix->FbMapSize = pScrn->videoRam * 1024;
pCyrix->MinClock = 16250;
xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
pCyrix->MinClock / 1000);
pCyrix->MaxClock = 135000;
xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Max pixel clock is %d MHz\n",
pCyrix->MaxClock / 1000);
clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1);
clockRanges->next = NULL;
clockRanges->minClock = pCyrix->MinClock;
clockRanges->maxClock = pCyrix->MaxClock;
clockRanges->clockIndex = -1;
clockRanges->interlaceAllowed = TRUE;
clockRanges->doubleScanAllowed = FALSE;
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
pScrn->display->modes, clockRanges,
accelWidths, 256, 2048,
pScrn->bitsPerPixel, 128, 2048,
pScrn->display->virtualX,
pScrn->display->virtualY,
pCyrix->FbMapSize,
LOOKUP_BEST_REFRESH);
if (i == -1) {
CYRIXFreeRec(pScrn);
return FALSE;
}
xf86PruneDriverModes(pScrn);
if (i == 0 || pScrn->modes == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
CYRIXFreeRec(pScrn);
return FALSE;
}
xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
pScrn->currentMode = pScrn->modes;
xf86PrintModes(pScrn);
xf86SetDpi(pScrn, 0, 0);
switch (pScrn->bitsPerPixel) {
case 1:
case 4:
case 8:
pCyrix->EngineOperation |= 0x00;
break;
case 16:
pCyrix->EngineOperation |= 0x01;
break;
}
if (xf86LoadSubModule(pScrn, "fb") == NULL) {
CYRIXFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(fbSymbols, NULL);
if (!pCyrix->NoAccel) {
if (!xf86LoadSubModule(pScrn, "xaa")) {
CYRIXFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(xaaSymbols, NULL);
switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
case 512:
pCyrix->EngineOperation |= 0x00;
break;
case 1024:
pCyrix->EngineOperation |= 0x04;
break;
case 2048:
pCyrix->EngineOperation |= 0x08;
break;
}
}
if (pCyrix->ShadowFB) {
if (!xf86LoadSubModule(pScrn, "shadowfb")) {
CYRIXFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(shadowSymbols, NULL);
}
return TRUE;
}
static void
CYRIXSave(ScrnInfoPtr pScrn)
{
vgaRegPtr vgaReg;
CYRIXPrvPtr pCyrix;
CYRIXRegPtr cyrixReg;
pCyrix = CYRIXPTR(pScrn);
vgaReg = &VGAHWPTR(pScrn)->SavedReg;
cyrixReg = &pCyrix->SavedReg;
vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
CyrixSave(pScrn, cyrixReg);
CYRIXSavePalette(pScrn);
}
static Bool
CYRIXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
int ret = -1;
vgaHWPtr hwp;
CYRIXPrvPtr pCyrix;
CYRIXRegPtr cyrixReg;
hwp = VGAHWPTR(pScrn);
vgaHWUnlock(hwp);
if (!vgaHWInit(pScrn, mode))
return FALSE;
pScrn->vtSema = TRUE;
pCyrix = CYRIXPTR(pScrn);
ret = CyrixInit(pScrn, mode);
if (!ret)
return FALSE;
cyrixReg = &pCyrix->ModeReg;
CyrixRestore(pScrn, cyrixReg);
return TRUE;
}
static void
CYRIXRestore(ScrnInfoPtr pScrn)
{
vgaHWPtr hwp;
vgaRegPtr vgaReg;
;
hwp = VGAHWPTR(pScrn);
vgaReg = &hwp->SavedReg;
;
vgaHWProtect(pScrn, TRUE);
CYRIXRestorePalette(pScrn);
vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
vgaHWProtect(pScrn, FALSE);
}
static void
CYRIXLoadPalette(
ScrnInfoPtr pScrn,
int numColors,
int *indices,
LOCO *colors,
VisualPtr pVisual
){
int i;
unsigned int locked;
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
switch(pScrn->depth) {
case 15:
case 16:
return;
}
locked = GX_REG(DC_UNLOCK);
GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
for(i = 0; i < numColors; i++) {
unsigned int red, green, blue;
int index = indices[i];
red = colors[index].red;
green = colors[index].green;
blue = colors[index].blue;;
GX_REG(DC_PAL_ADDRESS) = index;
GX_REG(DC_PAL_DATA) = (red << 12) | (green << 6) | blue;
}
GX_REG(DC_UNLOCK) = locked;
}
static void CYRIXSavePalette(ScrnInfoPtr pScrn)
{
int i;
unsigned int locked;
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
locked = GX_REG(DC_UNLOCK);
GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
for(i = 0; i < 256; i++) {
GX_REG(DC_PAL_ADDRESS) = i;
pCyrix->SavedReg.Colormap[i] = GX_REG(DC_PAL_DATA);
}
GX_REG(DC_UNLOCK) = locked;
}
static void CYRIXRestorePalette(ScrnInfoPtr pScrn)
{
int i;
unsigned int locked;
CYRIXPrvPtr pCyrix = CYRIXPTR(pScrn);
locked = GX_REG(DC_UNLOCK);
GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
for(i = 0; i < 256; i++) {
GX_REG(DC_PAL_ADDRESS) = i;
GX_REG(DC_PAL_DATA) = pCyrix->SavedReg.Colormap[i];
}
GX_REG(DC_UNLOCK) = locked;
}
static Bool
CYRIXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn;
vgaHWPtr hwp;
CYRIXPrvPtr pCyrix;
int ret;
VisualPtr visual;
int width, height, displayWidth;
unsigned char *FBStart;
pScrn = xf86Screens[pScreen->myNum];
hwp = VGAHWPTR(pScrn);
hwp->MapSize = 0x10000;
pCyrix = CYRIXPTR(pScrn);
if (!vgaHWMapMem(pScrn))
return FALSE;
vgaHWGetIOBase(hwp);
pCyrix->FbBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
(unsigned long)pCyrix->FbAddress, pCyrix->FbMapSize);
CYRIXSave(pScrn);
CYRIXModeInit(pScrn, pScrn->currentMode);
CYRIXSaveScreen(pScreen, SCREEN_SAVER_ON);
CYRIXAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
#if 0
CYRIXSaveScreen(pScreen, SCREEN_SAVER_OFF);
#endif
if (pScrn->bitsPerPixel >= 8) miClearVisualTypes();
if (pScrn->bitsPerPixel > 8) {
if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
pScrn->defaultVisual))
return FALSE;
} else {
if (!xf86SetDefaultVisual(pScrn, -1))
return FALSE;
if (!miSetVisualTypes(pScrn->depth,
miGetDefaultVisualMask(pScrn->depth),
pScrn->rgbBits, pScrn->defaultVisual))
return FALSE;
}
miSetPixmapDepths ();
width = pScrn->virtualX;
height = pScrn->virtualY;
displayWidth = pScrn->displayWidth;
if(pCyrix->Rotate) {
height = pScrn->virtualX;
width = pScrn->virtualY;
}
if(pCyrix->ShadowFB) {
pCyrix->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
pCyrix->ShadowPtr = xalloc(pCyrix->ShadowPitch * height);
displayWidth = pCyrix->ShadowPitch / (pScrn->bitsPerPixel >> 3);
FBStart = pCyrix->ShadowPtr;
} else {
pCyrix->ShadowPtr = NULL;
FBStart = pCyrix->FbBase;
}
switch (pScrn->bitsPerPixel) {
case 1:
case 4:
case 8:
case 16:
ret = fbScreenInit(pScreen, FBStart, width,
height, pScrn->xDpi, pScrn->yDpi,
displayWidth, pScrn->bitsPerPixel);
break;
default:
xf86DrvMsg(scrnIndex, X_ERROR,
"Internal error: invalid bpp (%d) in CYRIXScreenInit\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;
}
}
} else if (pScrn->depth == 1) {
Cyrix1bppColorMap(pScrn);
}
fbPictureInit (pScreen, 0, 0);
if (pScrn->depth < 8) {
miBankInfoPtr pBankInfo;
pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1);
if (pBankInfo == NULL)
return FALSE;
pBankInfo->pBankA = hwp->Base;
pBankInfo->pBankB = hwp->Base;
pBankInfo->BankSize = 0x10000;
pBankInfo->nBankDepth = pScrn->depth;
xf86EnableAccess(pScrn);
pBankInfo->SetSourceBank =
(miBankProcPtr)CYRIXSetRead;
pBankInfo->SetDestinationBank =
(miBankProcPtr)CYRIXSetWrite;
pBankInfo->SetSourceAndDestinationBanks =
(miBankProcPtr)CYRIXSetReadWrite;
if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
pScrn->displayWidth, pBankInfo)) {
xfree(pBankInfo);
pBankInfo = NULL;
return FALSE;
}
}
if (!pCyrix->NoAccel)
CYRIXAccelInit(pScreen);
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
xf86SetSilkenMouse(pScreen);
miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
if (!miCreateDefColormap(pScreen))
return FALSE;
if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
CYRIXLoadPalette, NULL,
CMAP_RELOAD_ON_MODE_SWITCH))
return FALSE;
xf86DPMSInit(pScreen, (DPMSSetProcPtr)CYRIXDisplayPowerManagementSet, 0);
pScrn->memPhysBase = pCyrix->FbAddress;
pScrn->fbOffset = 0;
if(pCyrix->ShadowFB) {
RefreshAreaFuncPtr refreshArea = CYRIXRefreshArea;
if(pCyrix->Rotate) {
if (!pCyrix->PointerMoved) {
pCyrix->PointerMoved = pScrn->PointerMoved;
pScrn->PointerMoved = CYRIXPointerMoved;
}
switch(pScrn->bitsPerPixel) {
case 8: refreshArea = CYRIXRefreshArea8; break;
case 16: refreshArea = CYRIXRefreshArea16; break;
}
}
ShadowFBInit(pScreen, refreshArea);
}
pCyrix->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = CYRIXCloseScreen;
pScreen->SaveScreen = CYRIXSaveScreen;
if (serverGeneration == 1) {
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
}
return TRUE;
}
static Bool
CYRIXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
return CYRIXModeInit(xf86Screens[scrnIndex], mode);
}
static void
CYRIXAdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
vgaHWPtr hwp;
CYRIXPrvPtr pCyrix;
int base = y * pScrn->displayWidth + x;
unsigned char temp;
int vgaIOBase;
hwp = VGAHWPTR(pScrn);
vgaIOBase = hwp->IOBase;
pCyrix = CYRIXPTR(pScrn);
switch (pScrn->bitsPerPixel) {
case 4:
base = base >> 4;
break;
case 8:
base = (base & 0xFFFFFFF8) >> 2;
break;
case 16:
base /= 2;
break;
}
GX_REG(DC_UNLOCK) = DC_UNLOCK_VALUE;
outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
outb(vgaIOBase + 4, 0x1E); temp = inb(vgaIOBase + 5) & 0xDF;
outb(vgaIOBase + 5, temp | (base & 0x10000) >> 11);
GX_REG(DC_UNLOCK) = 0;
}
static Bool
CYRIXEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
if (!CYRIXModeInit(pScrn, pScrn->currentMode))
return FALSE;
return TRUE;
}
static void
CYRIXLeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
vgaHWPtr hwp = VGAHWPTR(pScrn);
CYRIXRestore(pScrn);
vgaHWLock(hwp);
}
static Bool
CYRIXCloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
vgaHWPtr hwp = VGAHWPTR(pScrn);
CYRIXPrvPtr pCyrix;
if (pScrn->vtSema) {
CYRIXRestore(pScrn);
vgaHWLock(hwp);
}
pCyrix = CYRIXPTR(pScrn);
if(pCyrix->AccelInfoRec)
XAADestroyInfoRec(pCyrix->AccelInfoRec);
if (pCyrix->ShadowPtr)
xfree(pCyrix->ShadowPtr);
pScrn->vtSema = FALSE;
pScreen->CloseScreen = pCyrix->CloseScreen;
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
static void
CYRIXFreeScreen(int scrnIndex, int flags)
{
vgaHWFreeHWRec(xf86Screens[scrnIndex]);
CYRIXFreeRec(xf86Screens[scrnIndex]);
}
static ModeStatus
CYRIXValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
return(MODE_OK);
}
static Bool
CYRIXSaveScreen(ScreenPtr pScreen, int mode)
{
return vgaHWSaveScreen(pScreen, mode);
}