#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "vgaHW.h"
#include "xf86RAC.h"
#include "xf86Resources.h"
#include "mipointer.h"
#include "mibstore.h"
#include "micmap.h"
#include "shadowfb.h"
#include "xf86fbman.h"
#include "xf4bpp.h"
#include "xf1bpp.h"
#include "fb.h"
#include "xf86DDC.h"
#include "xf86int10.h"
#include "cir.h"
#define _ALP_PRIVATE_
#include "alp.h"
#include "xf86xv.h"
#include "Xv.h"
#ifdef ALPPROBEI2C
static void AlpProbeI2C(int scrnIndex);
#endif
Bool AlpPreInit(ScrnInfoPtr pScrn, int flags);
Bool AlpScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
Bool AlpEnterVT(int scrnIndex, int flags);
void AlpLeaveVT(int scrnIndex, int flags);
static Bool AlpCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool AlpSaveScreen(ScreenPtr pScreen, int mode);
Bool AlpSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
void AlpAdjustFrame(int scrnIndex, int x, int y, int flags);
void AlpFreeScreen(int scrnIndex, int flags);
ModeStatus AlpValidMode(int scrnIndex, DisplayModePtr mode,
Bool verbose, int flags);
static void AlpSave(ScrnInfoPtr pScrn);
static void AlpRestore(ScrnInfoPtr pScrn);
static Bool AlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
static void AlpProbeLCD(ScrnInfoPtr pScrn);
static void AlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq);
static void AlpOffscreenAccelInit(ScrnInfoPtr pScrn);
static void AlpDisplayPowerManagementSet(ScrnInfoPtr pScrn,
int PowerManagementMode, int flags);
static int pix24bpp = 0;
typedef enum {
OPTION_HW_CURSOR,
OPTION_PCI_RETRY,
OPTION_NOACCEL,
OPTION_MMIO,
OPTION_ROTATE,
OPTION_SHADOW_FB,
OPTION_MEMCFG1,
OPTION_MEMCFG2
} CirOpts;
static const OptionInfoRec CirOptions[] = {
{ OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_MEMCFG1, "MemCFG1", OPTV_INTEGER, {0}, -1 },
{ OPTION_MEMCFG2, "MemCFG2", OPTV_INTEGER, {0}, -1 },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
static int gd5430_MaxClocks[] = { 85500, 85500, 50000, 28500, 0 };
static int gd5446_MaxClocks[] = { 135100, 135100, 85500, 85500, 0 };
static int gd5480_MaxClocks[] = { 135100, 200000, 200000, 135100, 135100 };
static int gd7548_MaxClocks[] = { 80100, 80100, 80100, 80100, 80100 };
static const char *vgahwSymbols[] = {
"vgaHWFreeHWRec",
"vgaHWGetHWRec",
"vgaHWGetIOBase",
"vgaHWGetIndex",
"vgaHWHandleColormaps",
"vgaHWInit",
"vgaHWLock",
"vgaHWMapMem",
"vgaHWProtect",
"vgaHWRestore",
"vgaHWSave",
"vgaHWSaveScreen",
"vgaHWSetMmioFuncs",
"vgaHWSetStdFuncs",
"vgaHWUnlock",
NULL
};
#ifdef XFree86LOADER
static const char *miscfbSymbols[] = {
"xf1bppScreenInit",
"xf4bppScreenInit",
NULL
};
#endif
static const char *fbSymbols[] = {
"fbScreenInit",
"fbPictureInit",
NULL
};
static const char *xaaSymbols[] = {
"XAACreateInfoRec",
"XAADestroyInfoRec",
"XAAInit",
NULL
};
static const char *ramdacSymbols[] = {
"xf86CreateCursorInfoRec",
"xf86DestroyCursorInfoRec",
"xf86InitCursor",
NULL
};
static const char *int10Symbols[] = {
"xf86FreeInt10",
"xf86InitInt10",
NULL
};
static const char *shadowSymbols[] = {
"ShadowFBInit",
NULL
};
static const char *ddcSymbols[] = {
"xf86PrintEDID",
"xf86DoEDID_DDC2",
"xf86SetDDCproperties",
NULL
};
static const char *i2cSymbols[] = {
"xf86CreateI2CBusRec",
"xf86I2CBusInit",
NULL
};
#ifdef XFree86LOADER
#define ALP_MAJOR_VERSION 1
#define ALP_MINOR_VERSION 0
#define ALP_PATCHLEVEL 0
static MODULESETUPPROTO(alpSetup);
static XF86ModuleVersionInfo alpVersRec =
{
"cirrus_alpine",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XF86_VERSION_CURRENT,
ALP_MAJOR_VERSION, ALP_MINOR_VERSION, ALP_PATCHLEVEL,
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_NONE,
{0,0,0,0}
};
XF86ModuleData cirrus_alpineModuleData = { &alpVersRec, alpSetup, NULL };
static pointer
alpSetup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = FALSE;
if (!setupDone) {
setupDone = TRUE;
LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
miscfbSymbols, ramdacSymbols,int10Symbols,
ddcSymbols, i2cSymbols, shadowSymbols, NULL);
}
return (pointer)1;
}
#endif
const OptionInfoRec *
AlpAvailableOptions(int chipid)
{
return CirOptions;
}
ScrnInfoPtr
AlpProbe(int entity)
{
ScrnInfoPtr pScrn = NULL;
if ((pScrn = xf86ConfigPciEntity(pScrn, 0, entity, CIRPciChipsets,
NULL,NULL, NULL, NULL, NULL))) {
pScrn->PreInit = AlpPreInit;
pScrn->ScreenInit = AlpScreenInit;
pScrn->SwitchMode = AlpSwitchMode;
pScrn->AdjustFrame = AlpAdjustFrame;
pScrn->EnterVT = AlpEnterVT;
pScrn->LeaveVT = AlpLeaveVT;
pScrn->FreeScreen = AlpFreeScreen;
pScrn->ValidMode = AlpValidMode;
}
return pScrn;
}
static Bool
AlpGetRec(ScrnInfoPtr pScrn)
{
#ifdef ALP_DEBUG
ErrorF("AlpGetRec\n");
#endif
if (pScrn->driverPrivate != NULL)
return TRUE;
pScrn->driverPrivate = xnfcalloc(sizeof(CirRec), 1);
((CirPtr)pScrn->driverPrivate)->chip.alp = xnfcalloc(sizeof(AlpRec),1);
#ifdef ALP_DEBUG
ErrorF("AlpGetRec 0x%x\n", CIRPTR(pScrn));
#endif
return TRUE;
}
static void
AlpFreeRec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate == NULL)
return;
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
}
static int
AlpCountRam(ScrnInfoPtr pScrn)
{
CirPtr pCir = CIRPTR(pScrn);
vgaHWPtr hwp = VGAHWPTR(pScrn);
MessageType from;
int videoram = 0;
pCir->FbMapSize = 1024*1024;
pCir->IoMapSize = 0x4000;
if (!CirMapMem(pCir, pScrn->scrnIndex))
return 0;
switch (pCir->Chipset)
{
case PCI_CHIP_GD7548:
break;
default:
if (pCir->UseMMIO)
vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
}
if (pCir->chip.alp->sr0f != (CARD32)-1) {
from = X_CONFIG;
hwp->writeSeq(hwp, 0x0F, pCir->chip.alp->sr0f);
} else {
from = X_PROBED;
pCir->chip.alp->sr0f = hwp->readSeq(hwp, 0x0F);
}
xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 1 is 0x%02X\n",
(unsigned int)pCir->chip.alp->sr0f);
switch (pCir->Chipset) {
case PCI_CHIP_GD5430:
switch (pCir->chip.alp->sr0f & 0x18) {
case 0x08:
videoram = 512;
break;
case 0x10:
videoram = 1024;
break;
case 0x18:
videoram = 2048;
break;
}
break;
case PCI_CHIP_GD5434_4:
case PCI_CHIP_GD5434_8:
case PCI_CHIP_GD5436:
switch (pCir->chip.alp->sr0f & 0x18) {
case 0x10:
videoram = 1024;
break;
case 0x18:
videoram = 2048;
if (pCir->chip.alp->sr0f & 0x80)
videoram = 4096;
break;
}
case PCI_CHIP_GD5446:
videoram = 1024;
if (pCir->chip.alp->sr17 != (CARD32)-1) {
from = X_CONFIG;
hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17);
} else {
from = X_PROBED;
pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17);
}
xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n",
(unsigned int)pCir->chip.alp->sr17);
if ((pCir->chip.alp->sr0f & 0x18) == 0x18) {
if (pCir->chip.alp->sr0f & 0x80) {
if (pCir->chip.alp->sr17 & 0x80)
videoram = 2048;
else if (pCir->chip.alp->sr17 & 0x02)
videoram = 3072;
else
videoram = 4096;
} else {
if ((pCir->chip.alp->sr17 & 80) == 0)
videoram = 2048;
}
}
break;
case PCI_CHIP_GD5480:
if (pCir->chip.alp->sr17 != (CARD32)-1) {
from = X_CONFIG;
hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17);
} else {
from = X_PROBED;
pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17);
}
xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n",
(unsigned int)pCir->chip.alp->sr17);
videoram = 1024;
if ((pCir->chip.alp->sr0f & 0x18) == 0x18) {
videoram = 2048;
if (pCir->chip.alp->sr0f & 0x80)
videoram = 4096;
}
if (pCir->chip.alp->sr17 & 0x80)
videoram <<= 1;
break;
case PCI_CHIP_GD7548:
videoram = 1024;
switch (pCir->chip.alp->sr0f & 0x90) {
case 0x10:
break;
case 0x90:
videoram <<= 1;
break;
}
break;
}
if (!CirUnmapMem(pCir, pScrn->scrnIndex))
return 0;
vgaHWSetStdFuncs(hwp);
return videoram;
}
static int *
GetAccelPitchValues(ScrnInfoPtr pScrn)
{
int *linePitches = NULL;
int i, n = 0;
CirPtr pCir = CIRPTR(pScrn);
#if 1
int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280,
1600, 1920, 2048, 0 };
#else
int accelWidths[] = { 512, 576, 640, 768, 800, 960, 1024, 1152,
1280, 1536, 1600, 1920, 2048, 0 };
#endif
for (i = 0; accelWidths[i] != 0; i++) {
if (accelWidths[i] % pCir->Rounding == 0) {
n++;
linePitches = xnfrealloc(linePitches, n * sizeof(int));
linePitches[n - 1] = accelWidths[i];
}
}
if (n > 0) {
linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
linePitches[n] = 0;
}
return linePitches;
}
Bool
AlpPreInit(ScrnInfoPtr pScrn, int flags)
{
CirPtr pCir;
vgaHWPtr hwp;
MessageType from, from1;
int i;
ClockRangePtr clockRanges;
char *s;
xf86Int10InfoPtr pInt = NULL;
if (flags & PROBE_DETECT) {
cirProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
return TRUE;
}
#ifdef ALP_DEBUG
ErrorF("AlpPreInit\n");
#endif
if (pScrn->numEntities != 1)
return FALSE;
if (!xf86LoadSubModule(pScrn, "vgahw"))
return FALSE;
xf86LoaderReqSymLists(vgahwSymbols, NULL);
if (!vgaHWGetHWRec(pScrn))
return FALSE;
hwp = VGAHWPTR(pScrn);
vgaHWGetIOBase(hwp);
if (!AlpGetRec(pScrn))
return FALSE;
pCir = CIRPTR(pScrn);
pCir->pScrn = pScrn;
pCir->PIOReg = hwp->PIOOffset + 0x3CE;
pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (pCir->pEnt->location.type != BUS_PCI) {
xfree(pCir->pEnt);
return FALSE;
}
pCir->Chipset = pCir->pEnt->chipset;
pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index);
pCir->PciTag = pciTag(pCir->PciInfo->bus,
pCir->PciInfo->device,
pCir->PciInfo->func);
if (xf86LoadSubModule(pScrn, "int10")) {
xf86LoaderReqSymLists(int10Symbols,NULL);
xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n");
pInt = xf86InitInt10(pCir->pEnt->index);
xf86FreeInt10(pInt);
pciWriteLong(pCir->PciTag,0x10,pCir->PciInfo->memBase[0]);
pciWriteLong(pCir->PciTag,0x14,pCir->PciInfo->memBase[1]);
}
pScrn->monitor = pScrn->confScreen->monitor;
if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
SupportConvert32to24 | PreferConvert32to24)) {
return FALSE;
} else {
switch (pScrn->depth) {
case 1:
case 4:
case 8:
case 15:
case 16:
case 24:
break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Given depth (%d) is not supported by this driver\n",
pScrn->depth);
return FALSE;
}
}
xf86PrintDepthBpp(pScrn);
if (pScrn->depth == 24 && pix24bpp == 0)
pix24bpp = xf86GetBppFromDepth(pScrn, 24);
if (pScrn->depth > 8) {
rgb zeros = {0, 0, 0};
if (!xf86SetWeight(pScrn, zeros, zeros)) {
return FALSE;
} else {
;
}
}
if (!xf86SetDefaultVisual(pScrn, -1)) {
return FALSE;
}
xf86CollectOptions(pScrn, NULL);
if (!(pCir->Options = xalloc(sizeof(CirOptions))))
return FALSE;
memcpy(pCir->Options, CirOptions, sizeof(CirOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCir->Options);
if (!xf86IsPrimaryPci(pCir->PciInfo)
&& !(pInt || (xf86IsOptionSet(pCir->Options,OPTION_MEMCFG1)
&& xf86IsOptionSet(pCir->Options,OPTION_MEMCFG2))))
return FALSE;
if (pScrn->depth == 8)
pScrn->rgbBits = 6;
from = X_DEFAULT;
pCir->HWCursor = FALSE;
if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, &pCir->HWCursor))
from = X_CONFIG;
xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
pCir->HWCursor ? "HW" : "SW");
if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) {
pCir->NoAccel = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
}
if(pScrn->bitsPerPixel < 8) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Cannot use accelerations in less than 8 bpp\n");
pCir->NoAccel = TRUE;
}
if (pCir->pEnt->device->chipRev >= 0) {
pCir->ChipRev = pCir->pEnt->device->chipRev;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
pCir->ChipRev);
} else {
pCir->ChipRev = pCir->PciInfo->chipRev;
}
if (pCir->pEnt->device->MemBase != 0) {
if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->MemBase)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"MemBase 0x%08lX doesn't match any PCI base register.\n",
pCir->pEnt->device->MemBase);
return FALSE;
}
pCir->FbAddress = pCir->pEnt->device->MemBase;
from = X_CONFIG;
} else {
if (pCir->PciInfo->memBase[0] != 0) {
pCir->FbAddress = pCir->PciInfo->memBase[0] & 0xff000000;
from = X_PROBED;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"No valid FB address in PCI config space\n");
AlpFreeRec(pScrn);
return FALSE;
}
}
xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
(unsigned long)pCir->FbAddress);
if (pCir->pEnt->device->IOBase != 0) {
if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->IOBase)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"IOBase 0x%08lX doesn't match any PCI base register.\n",
pCir->pEnt->device->IOBase);
return FALSE;
}
pCir->IOAddress = pCir->pEnt->device->IOBase;
from = X_CONFIG;
} else {
if (pCir->PciInfo->memBase[1] != 0) {
pCir->IOAddress = pCir->PciInfo->memBase[1] & 0xfffff000;
from = X_PROBED;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"No valid MMIO address in PCI config space\n");
}
}
#if 0
if (xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, FALSE)) {
pCir->UseMMIO = TRUE;
from = X_CONFIG;
}
#endif
if (!xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, TRUE)) {
pCir->UseMMIO = FALSE;
from1 = X_CONFIG;
} else if (pCir->IOAddress) {
if (pScrn->bitsPerPixel != 1) {
pCir->UseMMIO = TRUE;
from1 = X_PROBED;
} else {
pCir->UseMMIO = FALSE;
from1 = X_PROBED;
}
} else {
pCir->UseMMIO = FALSE;
from1 = X_PROBED;
}
if (pCir->UseMMIO) {
xf86DrvMsg(pScrn->scrnIndex, from1, "Using MMIO\n");
xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
(unsigned long)pCir->IOAddress);
} else
xf86DrvMsg(pScrn->scrnIndex, from1, "Not Using MMIO\n");
if (!pCir->UseMMIO) {
pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT | RAC_FB;
xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr);
} else {
xf86SetOperatingState(resVga, pCir->pEnt->index, ResUnusedOpr);
}
if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"xf86RegisterResources() found resource conflicts\n");
return FALSE;
}
if (!xf86LoadSubModule(pScrn, "i2c")) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(i2cSymbols,NULL);
if (!xf86LoadSubModule(pScrn, "ddc")) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(ddcSymbols, NULL);
if(!AlpI2CInit(pScrn)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"I2C initialization failed\n");
}
else
xf86SetDDCproperties(pScrn,xf86PrintEDID(
xf86DoEDID_DDC2(pScrn->scrnIndex,pCir->I2CPtr1)));
AlpProbeLCD(pScrn);
#ifdef CIRPROBEI2C
CirProbeI2C(pScrn->scrnIndex);
#endif
if (pScrn->depth > 1) {
Gamma zeros = {0.0, 0.0, 0.0};
if (!xf86SetGamma(pScrn, zeros))
return FALSE;
}
if (xf86GetOptValBool(pCir->Options,
OPTION_SHADOW_FB,&pCir->shadowFB))
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n",
pCir->shadowFB ? "enabled" : "disabled");
if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) {
if(!xf86NameCmp(s, "CW")) {
pCir->shadowFB = TRUE;
pCir->rotate = 1;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"Rotating screen clockwise - acceleration disabled\n");
} else if(!xf86NameCmp(s, "CCW")) {
pCir->shadowFB = TRUE;
pCir->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");
}
}
if (pCir->shadowFB && (pScrn->depth < 8)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"shadowFB not supported at this depth.\n");
pCir->shadowFB = FALSE;
pCir->rotate = 0;
}
if (pCir->shadowFB && !pCir->NoAccel) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"HW acceleration not supported with \"shadowFB\".\n");
pCir->NoAccel = TRUE;
}
if (pCir->rotate && pCir->HWCursor) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"HW cursor not supported with \"rotate\".\n");
pCir->HWCursor = FALSE;
}
pCir->chip.alp->sr0f = (CARD32)-1;
pCir->chip.alp->sr17 = (CARD32)-1;
(void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG1, (unsigned long *)&pCir->chip.alp->sr0f);
(void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG2, (unsigned long *)&pCir->chip.alp->sr17);
if (pCir->pEnt->device->videoRam != 0) {
pScrn->videoRam = pCir->pEnt->device->videoRam;
pCir->IoMapSize = 0x4000;
from = X_CONFIG;
} else {
pScrn->videoRam = AlpCountRam(pScrn);
from = X_PROBED;
}
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam);
pCir->FbMapSize = pScrn->videoRam * 1024;
pCir->properties = 0;
if ((pCir->chip.alp->sr0f & 0x18) > 0x8)
pCir->properties |= HWCUR64;
switch (pCir->Chipset) {
case PCI_CHIP_GD7548:
pCir->properties |= HWCUR64;
pCir->properties |= ACCEL_AUTOSTART;
break;
case PCI_CHIP_GD5436:
case PCI_CHIP_GD5480:
pCir->properties |= ACCEL_AUTOSTART;
break;
default:
break;
}
pScrn->progClock = TRUE;
pCir->MinClock = 12000;
xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
pCir->MinClock / 1000);
if (pCir->pEnt->device->dacSpeeds[0]) {
ErrorF("Do not specily a Clocks line for Cirrus chips\n");
return FALSE;
} else {
int speed;
int *p = NULL;
switch (pCir->Chipset) {
case PCI_CHIP_GD5430:
case PCI_CHIP_GD5434_4:
case PCI_CHIP_GD5434_8:
case PCI_CHIP_GD5436:
p = gd5430_MaxClocks;
break;
case PCI_CHIP_GD5446:
p = gd5446_MaxClocks;
break;
case PCI_CHIP_GD5480:
p = gd5480_MaxClocks;
break;
case PCI_CHIP_GD7548:
p = gd7548_MaxClocks;
break;
}
if (!p)
return FALSE;
switch(pScrn->bitsPerPixel) {
case 1:
case 4:
speed = p[0];
break;
case 8:
speed = p[1];
break;
case 15:
case 16:
speed = p[2];
break;
case 24:
speed = p[3];
break;
case 32:
speed = p[4];
break;
default:
speed = 0;
break;
}
pCir->MaxClock = speed;
from = X_PROBED;
}
xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
pCir->MaxClock / 1000);
clockRanges = xnfcalloc(sizeof(ClockRange), 1);
clockRanges->next = NULL;
clockRanges->minClock = pCir->MinClock;
clockRanges->maxClock = pCir->MaxClock;
clockRanges->clockIndex = -1;
clockRanges->interlaceAllowed = FALSE;
clockRanges->doubleScanAllowed = FALSE;
clockRanges->doubleScanAllowed = FALSE;
clockRanges->doubleScanAllowed = FALSE;
clockRanges->ClockMulFactor = 1;
clockRanges->ClockDivFactor = 1;
clockRanges->PrivFlags = 0;
switch (pCir->Chipset)
{
case PCI_CHIP_GD7548:
pCir->Rounding = 1;
break;
default:
pCir->Rounding = 128 >> pCir->BppShift;
}
#if 0
if (pCir->Chipset != PCI_CHIP_GD5446 &&
pCir->Chipset != PCI_CHIP_GD5480) {
pCir->NoAccel = TRUE;
}
#endif
if (pCir->NoAccel) {
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
pScrn->display->modes, clockRanges,
NULL, 256, 2048,
pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
pScrn->display->virtualX,
pScrn->display->virtualY,
pCir->FbMapSize,
LOOKUP_BEST_REFRESH);
} else {
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
pScrn->display->modes, clockRanges,
GetAccelPitchValues(pScrn), 0, 0,
pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
pScrn->display->virtualX,
pScrn->display->virtualY,
pCir->FbMapSize,
LOOKUP_BEST_REFRESH);
}
if (i == -1) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86PruneDriverModes(pScrn);
if (i == 0 || pScrn->modes == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
AlpFreeRec(pScrn);
return FALSE;
}
xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
pScrn->currentMode = pScrn->modes;
xf86PrintModes(pScrn);
xf86SetDpi(pScrn, 0, 0);
switch (pScrn->bitsPerPixel) {
case 1:
if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymbols("xf1bppScreenInit",NULL);
break;
case 4:
if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymbols("xf4bppScreenInit",NULL);
break;
case 8:
case 16:
case 24:
case 32:
if (xf86LoadSubModule(pScrn, "fb") == NULL) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(fbSymbols, NULL);
break;
}
if (!pCir->NoAccel) {
if (!xf86LoadSubModule(pScrn, "xaa")) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(xaaSymbols, NULL);
}
if (pCir->HWCursor) {
if (!xf86LoadSubModule(pScrn, "ramdac")) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(ramdacSymbols, NULL);
}
if (pCir->shadowFB) {
if (!xf86LoadSubModule(pScrn, "shadowfb")) {
AlpFreeRec(pScrn);
return FALSE;
}
xf86LoaderReqSymLists(shadowSymbols, NULL);
}
return TRUE;
}
static void
AlpSave(ScrnInfoPtr pScrn)
{
CirPtr pCir = CIRPTR(pScrn);
vgaHWPtr hwp = VGAHWPTR(pScrn);
#ifdef ALP_DEBUG
ErrorF("AlpSave\n");
#endif
vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL);
pCir->chip.alp->ModeReg.ExtVga[CR1A] = pCir->chip.alp->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A);
pCir->chip.alp->ModeReg.ExtVga[CR1B] = pCir->chip.alp->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B);
pCir->chip.alp->ModeReg.ExtVga[CR1D] = pCir->chip.alp->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D);
pCir->chip.alp->ModeReg.ExtVga[SR07] = pCir->chip.alp->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07);
pCir->chip.alp->ModeReg.ExtVga[SR0E] = pCir->chip.alp->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E);
pCir->chip.alp->ModeReg.ExtVga[SR12] = pCir->chip.alp->SavedReg.ExtVga[SR12] = hwp->readSeq(hwp, 0x12);
pCir->chip.alp->ModeReg.ExtVga[SR13] = pCir->chip.alp->SavedReg.ExtVga[SR13] = hwp->readSeq(hwp, 0x13);
pCir->chip.alp->ModeReg.ExtVga[SR17] = pCir->chip.alp->SavedReg.ExtVga[SR17] = hwp->readSeq(hwp, 0x17);
pCir->chip.alp->ModeReg.ExtVga[SR1E] = pCir->chip.alp->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E);
pCir->chip.alp->ModeReg.ExtVga[SR21] = pCir->chip.alp->SavedReg.ExtVga[SR21] = hwp->readSeq(hwp, 0x21);
pCir->chip.alp->ModeReg.ExtVga[SR2D] = pCir->chip.alp->SavedReg.ExtVga[SR2D] = hwp->readSeq(hwp, 0x2D);
pCir->chip.alp->ModeReg.ExtVga[GR17] = pCir->chip.alp->SavedReg.ExtVga[GR17] = hwp->readGr(hwp, 0x17);
pCir->chip.alp->ModeReg.ExtVga[GR18] = pCir->chip.alp->SavedReg.ExtVga[GR18] = hwp->readGr(hwp, 0x18);
hwp->readDacMask(hwp);
hwp->readDacMask(hwp);
hwp->readDacMask(hwp);
hwp->readDacMask(hwp);
pCir->chip.alp->ModeReg.ExtVga[HDR] = pCir->chip.alp->SavedReg.ExtVga[HDR] = hwp->readDacMask(hwp);
}
static void
AlpFix1bppColorMap(ScrnInfoPtr pScrn)
{
vgaHWPtr hwp = VGAHWPTR(pScrn);
hwp->writeDacWriteAddr(hwp, 0x00);
hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00);
hwp->writeDacWriteAddr(hwp, 0x3F);
hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F);
}
static void
alpRestore(vgaHWPtr hwp, AlpRegPtr cirReg)
{
hwp->writeCrtc(hwp, 0x1A, cirReg->ExtVga[CR1A]);
hwp->writeCrtc(hwp, 0x1B, cirReg->ExtVga[CR1B]);
hwp->writeCrtc(hwp, 0x1D, cirReg->ExtVga[CR1D]);
hwp->writeSeq(hwp, 0x07, cirReg->ExtVga[SR07]);
hwp->writeSeq(hwp, 0x0E, cirReg->ExtVga[SR0E]);
hwp->writeSeq(hwp, 0x12, cirReg->ExtVga[SR12]);
hwp->writeSeq(hwp, 0x13, cirReg->ExtVga[SR13]);
hwp->writeSeq(hwp, 0x17, cirReg->ExtVga[SR17]);
hwp->writeSeq(hwp, 0x1E, cirReg->ExtVga[SR1E]);
hwp->writeSeq(hwp, 0x21, cirReg->ExtVga[SR21]);
hwp->writeSeq(hwp, 0x2D, cirReg->ExtVga[SR2D]);
hwp->writeGr(hwp, 0x17, cirReg->ExtVga[GR17]);
hwp->writeGr(hwp, 0x18, cirReg->ExtVga[GR18]);
hwp->readDacMask(hwp);
hwp->readDacMask(hwp);
hwp->readDacMask(hwp);
hwp->readDacMask(hwp);
hwp->writeDacMask(hwp, cirReg->ExtVga[HDR ]);
}
static Bool
AlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
vgaHWPtr hwp;
CirPtr pCir;
int depthcode;
int width;
Bool HDiv2 = FALSE, VDiv2 = FALSE;
#ifdef ALP_DEBUG
ErrorF("AlpModeInit %d bpp, %d %d %d %d %d %d %d %d %d\n",
pScrn->bitsPerPixel,
mode->Clock,
mode->HDisplay,
mode->HSyncStart,
mode->HSyncEnd,
mode->HTotal,
mode->VDisplay,
mode->VSyncStart,
mode->VSyncEnd,
mode->VTotal);
ErrorF("AlpModeInit: depth %d bits\n", pScrn->depth);
#endif
pCir = CIRPTR(pScrn);
hwp = VGAHWPTR(pScrn);
vgaHWUnlock(hwp);
pCir->pitch = pScrn->displayWidth * pScrn->bitsPerPixel >> 3;
depthcode = pScrn->depth;
if (pScrn->bitsPerPixel == 32)
depthcode = 32;
if ((pCir->Chipset == PCI_CHIP_GD5480 && mode->Clock > 135100) ||
(pCir->Chipset == PCI_CHIP_GD5446 && mode->Clock > 85500)) {
if (!mode->CrtcHAdjusted) {
mode->CrtcHDisplay >>= 1;
mode->CrtcHSyncStart >>= 1;
mode->CrtcHTotal >>= 1;
mode->CrtcHSyncEnd >>= 1;
mode->SynthClock >>= 1;
mode->CrtcHAdjusted = TRUE;
}
depthcode += 64;
HDiv2 = TRUE;
}
if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) {
if (!mode->CrtcVAdjusted) {
mode->CrtcVDisplay >>= 1;
mode->CrtcVSyncStart >>= 1;
mode->CrtcVSyncEnd >>= 1;
mode->CrtcVTotal >>= 1;
mode->CrtcVAdjusted = TRUE;
}
VDiv2 = TRUE;
}
if (!vgaHWInit(pScrn, mode))
return FALSE;
pScrn->vtSema = TRUE;
pCir->chip.alp->ModeReg.ExtVga[SR12] = 0;
if ((pCir->properties & HWCUR64) == HWCUR64)
{
pCir->chip.alp->ModeReg.ExtVga[SR12] = 0x4;
switch (pCir->Chipset)
{
case PCI_CHIP_GD7548:
pCir->chip.alp->ModeReg.ExtVga[SR21] |= 0x10;
break;
}
}
else
pCir->chip.alp->ModeReg.ExtVga[SR12] = 0;
if(VDiv2)
hwp->ModeReg.CRTC[0x17] |= 0x04;
#ifdef ALP_DEBUG
ErrorF("SynthClock = %d\n", mode->SynthClock);
#endif
pCir->chip.alp->ModeReg.ExtVga[GR17] |= 0x08;
pCir->chip.alp->ModeReg.ExtVga[GR17] &= ~0x04;
pCir->chip.alp->ModeReg.ExtVga[HDR] = 0;
pCir->chip.alp->ModeReg.ExtVga[SR07] &= 0xe0;
#ifdef ALP_DEBUG
ErrorF("depthcode = %d\n", depthcode);
#endif
if (pScrn->bitsPerPixel == 1) {
hwp->IOBase = 0x3B0;
hwp->ModeReg.MiscOutReg &= ~0x01;
} else {
hwp->IOBase = 0x3D0;
hwp->ModeReg.MiscOutReg |= 0x01;
}
switch (depthcode) {
case 1:
case 4:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x10;
break;
case 8:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x11;
break;
case 64+8:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
break;
case 15:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC0;
break;
case 64+15:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC0;
break;
case 16:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17;
pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC1;
break;
case 64+16:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC1;
break;
case 24:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x15;
pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC5;
break;
case 32:
pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19;
pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC5;
break;
default:
ErrorF("X11: Internal error: AlpModeInit: Cannot Initialize display to requested mode\n");
#ifdef ALP_DEBUG
ErrorF("AlpModeInit returning FALSE on depthcode %d\n", depthcode);
#endif
return FALSE;
}
if (HDiv2)
pCir->chip.alp->ModeReg.ExtVga[GR18] |= 0x20;
else
pCir->chip.alp->ModeReg.ExtVga[GR18] &= ~0x20;
switch (pCir->Chipset)
{
case PCI_CHIP_GD7548:
if (pCir->UseMMIO)
{
pCir->chip.alp->ModeReg.ExtVga[SR17] =
(pCir->chip.alp->ModeReg.ExtVga[SR17] & ~0x40) | 4;
ErrorF("UseMMIO: SR17=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17]));
}
#ifdef ALP_SETUP
ErrorF("SR2D=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17]));
#endif
pCir->chip.alp->ModeReg.ExtVga[SR2D] |= 0xC0;
break;
}
pCir->chip.alp->ModeReg.ExtVga[CR1A] = 0x00;
width = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
if (pScrn->bitsPerPixel == 1)
width <<= 2;
hwp->ModeReg.CRTC[0x13] = width >> 3;
pCir->chip.alp->ModeReg.ExtVga[CR1B] &= 0xAF;
pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+4)) & 0x10;
pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+3)) & 0x40;
pCir->chip.alp->ModeReg.ExtVga[CR1B] |= 0x22;
vgaHWProtect(pScrn, TRUE);
hwp->writeMiscOut(hwp, hwp->ModeReg.MiscOutReg);
alpRestore(hwp,&pCir->chip.alp->ModeReg);
AlpSetClock(pCir, hwp, mode->SynthClock);
vgaHWRestore(pScrn, &hwp->ModeReg, VGA_SR_MODE | VGA_SR_CMAP);
if (pScrn->bitsPerPixel == 1)
AlpFix1bppColorMap(pScrn);
vgaHWProtect(pScrn, FALSE);
return TRUE;
}
static void
AlpRestore(ScrnInfoPtr pScrn)
{
vgaHWPtr hwp;
vgaRegPtr vgaReg;
CirPtr pCir;
AlpRegPtr alpReg;
#ifdef ALP_DEBUG
ErrorF("AlpRestore\n");
#endif
hwp = VGAHWPTR(pScrn);
pCir = CIRPTR(pScrn);
vgaReg = &hwp->SavedReg;
alpReg = &pCir->chip.alp->SavedReg;
vgaHWProtect(pScrn, TRUE);
alpRestore(hwp,alpReg);
vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
vgaHWProtect(pScrn, FALSE);
}
Bool
AlpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn;
vgaHWPtr hwp;
CirPtr pCir;
int i, ret;
int init_picture = 0;
VisualPtr visual;
int displayWidth,width,height;
unsigned char * FbBase = NULL;
int cursor_size = 0;
#ifdef ALP_DEBUG
ErrorF("AlpScreenInit\n");
#endif
pScrn = xf86Screens[pScreen->myNum];
hwp = VGAHWPTR(pScrn);
pCir = CIRPTR(pScrn);
if (!vgaHWMapMem(pScrn))
return FALSE;
if (!CirMapMem(pCir, pScrn->scrnIndex))
return FALSE;
switch (pCir->Chipset)
{
case PCI_CHIP_GD7548:
break;
default:
if(pCir->UseMMIO)
vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
}
vgaHWGetIOBase(hwp);
AlpSave(pScrn);
if (!AlpModeInit(pScrn, pScrn->currentMode))
return FALSE;
AlpSaveScreen(pScreen, SCREEN_SAVER_ON);
AlpAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
miClearVisualTypes();
if (!miSetVisualTypes(pScrn->depth,
miGetDefaultVisualMask(pScrn->depth),
pScrn->rgbBits, pScrn->defaultVisual))
return FALSE;
miSetPixmapDepths ();
displayWidth = pScrn->displayWidth;
if (pCir->rotate) {
height = pScrn->virtualX;
width = pScrn->virtualY;
} else {
width = pScrn->virtualX;
height = pScrn->virtualY;
}
if(pCir->shadowFB) {
pCir->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
pCir->ShadowPtr = xalloc(pCir->ShadowPitch * height);
displayWidth = pCir->ShadowPitch / (pScrn->bitsPerPixel >> 3);
FbBase = pCir->ShadowPtr;
} else {
pCir->ShadowPtr = NULL;
FbBase = pCir->FbBase;
}
switch (pScrn->bitsPerPixel) {
case 1:
ret = xf1bppScreenInit(pScreen, FbBase,
width, height,
pScrn->xDpi, pScrn->yDpi,
displayWidth);
break;
case 4:
ret = xf4bppScreenInit(pScreen, FbBase,
width, height,
pScrn->xDpi, pScrn->yDpi,
displayWidth);
break;
case 8:
case 16:
case 24:
case 32:
ret = fbScreenInit(pScreen, FbBase,
width,height,
pScrn->xDpi, pScrn->yDpi,
displayWidth,pScrn->bitsPerPixel);
init_picture = 1;
break;
default:
xf86DrvMsg(scrnIndex, X_ERROR,
"X11: Internal error: invalid bpp (%d) in AlpScreenInit\n",
pScrn->bitsPerPixel);
ret = FALSE;
break;
}
if (!ret)
return FALSE;
#ifdef ALP_DEBUG
ErrorF("AlpScreenInit after depth dependent init\n");
#endif
if (pScrn->bitsPerPixel > 8) {
for (i = 0; i < pScreen->numVisuals; i++) {
visual = &pScreen->visuals[i];
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;
}
}
}
if (init_picture)
fbPictureInit (pScreen, 0, 0);
miInitializeBackingStore(pScreen);
xf86SetBlackWhitePixels(pScreen);
pCir->offscreen_offset = pScrn->videoRam*1024;
pCir->offscreen_size = pScrn->videoRam * 1024 - pScrn->virtualY *
(BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel));
#ifdef ALP_DEBUG
ErrorF("offscreen_offset=%d, offscreen_size=%d\n",
pCir->offscreen_offset, pCir->offscreen_size);
#endif
if (pCir->HWCursor) {
if ((pCir->properties & HWCUR64)
&& (pCir->offscreen_size >= 64*8*2)) {
cursor_size = 64;
pCir->offscreen_size -= 64*8*2;
pCir->offscreen_offset -= 64*8*2;
} else if (pCir->offscreen_size >= 32*4*2) {
cursor_size = 32;
pCir->offscreen_size -= 32*8*2;
pCir->offscreen_offset -= 32*8*2;
}
}
if (!pCir->NoAccel) {
AlpOffscreenAccelInit(pScrn);
if (!(pCir->UseMMIO ? AlpXAAInitMMIO(pScreen) :
AlpXAAInit(pScreen)))
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Could not initialize XAA\n");
}
#if 1
pCir->DGAModeInit = AlpModeInit;
if (!CirDGAInit(pScreen))
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"DGA initialization failed\n");
#endif
xf86SetSilkenMouse(pScreen);
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
if (pCir->HWCursor) {
if (!AlpHWCursorInit(pScreen, cursor_size))
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Hardware cursor initialization failed\n");
#ifdef ALP_DEBUG
ErrorF("AlpHWCursorInit() complete\n");
#endif
}
if (pCir->shadowFB) {
RefreshAreaFuncPtr refreshArea = cirRefreshArea;
if(pCir->rotate) {
if (!pCir->PointerMoved) {
pCir->PointerMoved = pScrn->PointerMoved;
pScrn->PointerMoved = cirPointerMoved;
}
switch(pScrn->bitsPerPixel) {
case 8: refreshArea = cirRefreshArea8; break;
case 16: refreshArea = cirRefreshArea16; break;
case 24: refreshArea = cirRefreshArea24; break;
case 32: refreshArea = cirRefreshArea32; break;
}
}
ShadowFBInit(pScreen, refreshArea);
}
if (!miCreateDefColormap(pScreen))
return FALSE;
if (pScrn->bitsPerPixel > 1 && pScrn->bitsPerPixel <= 8)
vgaHWHandleColormaps(pScreen);
xf86DPMSInit(pScreen, AlpDisplayPowerManagementSet, 0);
pScrn->memPhysBase = pCir->FbAddress;
pScrn->fbOffset = 0;
{
XF86VideoAdaptorPtr *ptr;
int n;
n = xf86XVListGenericAdaptors(pScrn,&ptr);
if (n)
xf86XVScreenInit(pScreen, ptr, n);
}
pScreen->SaveScreen = AlpSaveScreen;
pCir->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = AlpCloseScreen;
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
return TRUE;
}
Bool
AlpSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
return AlpModeInit(xf86Screens[scrnIndex], mode);
}
void
AlpAdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn;
int Base, tmp;
vgaHWPtr hwp;
pScrn = xf86Screens[scrnIndex];
hwp = VGAHWPTR(pScrn);
Base = ((y * pScrn->displayWidth + x) / 8);
if (pScrn->bitsPerPixel != 1)
Base *= (pScrn->bitsPerPixel/4);
#ifdef ALP_DEBUG
ErrorF("AlpAdjustFrame %d %d 0x%x %d %x\n", x, y, flags, Base, Base);
#endif
if ((Base & ~0x000FFFFF) != 0) {
ErrorF("X11: Internal error: AlpAdjustFrame: cannot handle overflow\n");
return;
}
hwp->writeCrtc(hwp, 0x0C, (Base >> 8) & 0xff);
hwp->writeCrtc(hwp, 0x0D, Base & 0xff);
tmp = hwp->readCrtc(hwp, 0x1B);
tmp &= 0xF2;
tmp |= (Base >> 16) & 0x01;
tmp |= (Base >> 15) & 0x0C;
hwp->writeCrtc(hwp, 0x1B, tmp);
tmp = hwp->readCrtc(hwp, 0x1D);
tmp &= 0x7F;
tmp |= (Base >> 12) & 0x80;
hwp->writeCrtc(hwp, 0x1D, tmp);
}
Bool
AlpEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
CirPtr pCir = CIRPTR(pScrn);
Bool ret;
#ifdef ALP_DEBUG
ErrorF("AlpEnterVT\n");
#endif
if (!(ret = AlpModeInit(pScrn, pScrn->currentMode)))
return FALSE;
if (!pCir->NoAccel)
pCir->InitAccel(pScrn);
return ret;
}
void
AlpLeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
vgaHWPtr hwp = VGAHWPTR(pScrn);
#ifdef ALP_DEBUG
ErrorF("AlpLeaveVT\n");
#endif
AlpRestore(pScrn);
vgaHWLock(hwp);
}
static Bool
AlpCloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
vgaHWPtr hwp = VGAHWPTR(pScrn);
CirPtr pCir = CIRPTR(pScrn);
if(pScrn->vtSema) {
AlpRestore(pScrn);
vgaHWLock(hwp);
CirUnmapMem(pCir, pScrn->scrnIndex);
}
if (pCir->AccelInfoRec)
XAADestroyInfoRec(pCir->AccelInfoRec);
pCir->AccelInfoRec = NULL;
if (pCir->CursorInfoRec)
xf86DestroyCursorInfoRec(pCir->CursorInfoRec);
pCir->CursorInfoRec = NULL;
if (pCir->DGAModes)
xfree(pCir->DGAModes);
pCir->DGAnumModes = 0;
pCir->DGAModes = NULL;
pScrn->vtSema = FALSE;
pScreen->CloseScreen = pCir->CloseScreen;
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
void
AlpFreeScreen(int scrnIndex, int flags)
{
#ifdef ALP_DEBUG
ErrorF("AlpFreeScreen\n");
#endif
if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
vgaHWFreeHWRec(xf86Screens[scrnIndex]);
AlpFreeRec(xf86Screens[scrnIndex]);
}
ModeStatus
AlpValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
int lace;
lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
if ((mode->CrtcHDisplay <= 2048) &&
(mode->CrtcHSyncStart <= 4096) &&
(mode->CrtcHSyncEnd <= 4096) &&
(mode->CrtcHTotal <= 4096) &&
(mode->CrtcVDisplay <= 2048 * lace) &&
(mode->CrtcVSyncStart <= 4096 * lace) &&
(mode->CrtcVSyncEnd <= 4096 * lace) &&
(mode->CrtcVTotal <= 4096 * lace)) {
return(MODE_OK);
} else {
return(MODE_BAD);
}
}
static Bool
AlpSaveScreen(ScreenPtr pScreen, int mode)
{
return vgaHWSaveScreen(pScreen, mode);
}
static void
AlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq)
{
int num, den, ffreq;
CARD8 tmp;
#ifdef ALP_DEBUG
ErrorF("AlpSetClock freq=%d.%03dMHz\n", freq / 1000, freq % 1000);
#endif
ffreq = freq;
if (!CirrusFindClock(&ffreq, pCir->MaxClock, &num, &den))
return;
#ifdef ALP_DEBUG
ErrorF("AlpSetClock: nom=%x den=%x ffreq=%d.%03dMHz\n",
num, den, ffreq / 1000, ffreq % 1000);
#endif
tmp = hwp->readSeq(hwp, 0x0E);
hwp->writeSeq(hwp, 0x0E, (tmp & 0x80) | num);
hwp->writeSeq(hwp, 0x1E, den);
}
static void
AlpDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
int flags)
{
unsigned char sr01, gr0e;
vgaHWPtr hwp;
#ifdef ALP_DEBUG
ErrorF("AlpDisplayPowerManagementSet\n");
#endif
hwp = VGAHWPTR(pScrn);
#ifdef ALP_DEBUG
ErrorF("AlpDisplayPowerManagementSet: %d\n", PowerManagementMode);
#endif
switch (PowerManagementMode) {
case DPMSModeOn:
sr01 = 0x00;
gr0e = 0x00;
break;
case DPMSModeStandby:
sr01 = 0x20;
gr0e = 0x02;
break;
case DPMSModeSuspend:
sr01 = 0x20;
gr0e = 0x04;
break;
case DPMSModeOff:
sr01 = 0x20;
gr0e = 0x06;
break;
default:
return;
}
sr01 |= hwp->readSeq(hwp, 0x01) & ~0x20;
hwp->writeSeq(hwp, 0x01, sr01);
gr0e |= hwp->readGr(hwp, 0x0E) & ~0x06;
hwp->writeGr(hwp, 0x0E, gr0e);
}
#ifdef ALPPROBEI2C
static void AlpProbeI2C(int scrnIndex)
{
int i;
I2CBusPtr b;
b = xf86I2CFindBus(scrnIndex, "I2C bus 1");
if (b == NULL)
ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 1");
else {
for (i = 2; i < 256; i += 2)
if (xf86I2CProbeAddress(b, i))
ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName);
}
b = xf86I2CFindBus(scrnIndex, "I2C bus 2");
if (b == NULL)
ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 2");
else {
for (i = 2; i < 256; i += 2)
if (xf86I2CProbeAddress(b, i))
ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName);
}
}
#endif
static void
AlpProbeLCD(ScrnInfoPtr pScrn)
{
CirPtr pCir = CIRPTR(pScrn);
AlpPtr pAlp = ALPPTR(pCir);
vgaHWPtr hwp = VGAHWPTR(pScrn);
CARD8 lcdCrtl;
static const char* lcd_type_names[] =
{
"none",
"dual-scan monochrome",
"unknown",
"DSTN (dual scan color)",
"TFT (active matrix)"
};
pAlp->lcdType = LCD_NONE;
switch (pCir->Chipset) {
case PCI_CHIP_GD7548:
switch (hwp->readCrtc(hwp, 0x2C) >> 6) {
case 0: pAlp->lcdType = LCD_DUAL_MONO; break;
case 1: pAlp->lcdType = LCD_UNKNOWN; break;
case 2: pAlp->lcdType = LCD_DSTN; break;
case 3: pAlp->lcdType = LCD_TFT; break;
}
lcdCrtl = hwp->readCrtc(hwp, 0x2D);
hwp->writeCrtc(hwp, 0x2D, lcdCrtl | 0x80);
switch ((hwp->readCrtc(hwp, 0x9) >> 2) & 3) {
case 0:
pAlp->lcdWidth = 640;
pAlp->lcdHeight = 480;
break;
case 1:
pAlp->lcdWidth = 800;
pAlp->lcdHeight = 600;
break;
case 2:
pAlp->lcdWidth = 1024;
pAlp->lcdHeight = 768;
break;
case 3:
pAlp->lcdWidth = 0;
pAlp->lcdHeight = 0;
break;
}
hwp->writeCrtc(hwp, 0x2D, lcdCrtl);
break;
}
if (pAlp->lcdType != LCD_NONE) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"LCD display: %dx%d %s\n",
pAlp->lcdWidth, pAlp->lcdHeight,
lcd_type_names[pAlp->lcdType]);
}
}
static void
AlpOffscreenAccelInit(ScrnInfoPtr pScrn)
{
CirPtr pCir = CIRPTR(pScrn);
AlpPtr pAlp = ALPPTR(pCir);
if (pCir->offscreen_size >= 8 && pCir->Chipset == PCI_CHIP_GD7548) {
pCir->offscreen_offset -= 8;
pCir->offscreen_size -= 8;
pAlp->monoPattern8x8 = pCir->offscreen_offset;
#ifdef ALP_DEBUG
ErrorF("monoPattern8x8=%d\n", pAlp->monoPattern8x8);
#endif
} else pAlp->monoPattern8x8 = 0;
{
BoxRec box;
box.x1=0;
box.y1=0;
box.x2=pScrn->virtualX;
box.y2= pCir->offscreen_offset / pCir->pitch;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Using %d lines for offscreen memory\n",
box.y2 - pScrn->virtualY);
}
}