summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c835
1 files changed, 748 insertions, 87 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
index ea5d061e1..845e3f85a 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
@@ -43,7 +43,7 @@
* Fixed 32bpp hires 8MB horizontal line glitch at middle right
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.167 2000/09/20 00:09:22 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.165 2000/07/11 01:46:36 tsi Exp $ */
/*
* This is a first cut at a non-accelerated version to work with the
@@ -79,11 +79,10 @@
#include "xf86RAC.h"
#include "vbe.h"
-#include "cfb8_32.h"
#include "fb.h"
+#include "cfb8_32.h"
#include "dixstruct.h"
-#include "mga_bios.h"
#include "mga_reg.h"
#include "mga.h"
#include "mga_macros.h"
@@ -118,6 +117,7 @@ static Bool MGAEnterVTFBDev(int scrnIndex, int flags);
static void MGALeaveVT(int scrnIndex, int flags);
static Bool MGACloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool MGASaveScreen(ScreenPtr pScreen, int mode);
+static Bool MGASaveScreenCrtc2(ScreenPtr pScreen, int mode);
/* This shouldn't be needed since RAC will disable all I/O for MGA cards. */
#ifdef DISABLE_VGA_IO
@@ -141,8 +141,10 @@ static Bool MGAUnmapMem(ScrnInfoPtr pScrn);
static void MGASave(ScrnInfoPtr pScrn);
static void MGARestore(ScrnInfoPtr pScrn);
static Bool MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags);
static void MGABlockHandler(int, pointer, pointer, pointer);
+static int MGAEntityIndex = -1;
/*
* This contains the functions needed by the server after loading the
@@ -152,7 +154,7 @@ static void MGABlockHandler(int, pointer, pointer, pointer);
* this DriverRec be an upper-case version of the driver name.
*/
-DriverRec MGA = {
+DriverRec MGA_C_NAME = {
MGA_VERSION,
MGA_DRIVER_NAME,
#if 0
@@ -207,7 +209,10 @@ typedef enum {
OPTION_VIDEO_KEY,
OPTION_ROTATE,
OPTION_TEXTURED_VIDEO,
- OPTION_XAALINES
+ OPTION_XAALINES,
+ OPTION_CRTC2HALF,
+ OPTION_AGP_MODE_2X,
+ OPTION_AGP_MODE_4X
} MGAOpts;
static OptionInfoRec MGAOptions[] = {
@@ -228,6 +233,9 @@ static OptionInfoRec MGAOptions[] = {
{ OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_TEXTURED_VIDEO, "TexturedVideo",OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_XAALINES, "XAALines", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_CRTC2HALF, "Crtc2Half", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_AGP_MODE_2X, "AGPMode2x", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_AGP_MODE_4X, "AGPMode4x", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -395,7 +403,7 @@ static MODULESETUPPROTO(mgaSetup);
static XF86ModuleVersionInfo mgaVersRec =
{
- "mga",
+ MGA_DRIVER_NAME,
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
@@ -407,7 +415,7 @@ static XF86ModuleVersionInfo mgaVersRec =
{0,0,0,0}
};
-XF86ModuleData mgaModuleData = { &mgaVersRec, mgaSetup, NULL };
+XF86ModuleData MGA_MODULE_DATA = { &mgaVersRec, mgaSetup, NULL };
static pointer
mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
@@ -418,7 +426,7 @@ mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
if (!setupDone) {
setupDone = TRUE;
- xf86AddDriver(&MGA, module, 0);
+ xf86AddDriver(&MGA_C_NAME, module, 0);
/*
* Modules that this driver always requires may be loaded here
@@ -429,10 +437,11 @@ mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
* Tell the loader about symbols from other modules that this module
* might refer to.
*/
- LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
xf8_32bppSymbols, ramdacSymbols,
ddcSymbols, i2cSymbols, shadowSymbols,
- fbdevHWSymbols, vbeSymbols, fbSymbols,
+ fbdevHWSymbols, vbeSymbols,
+ fbSymbols,
#ifdef XF86DRI
drmSymbols, driSymbols,
#endif
@@ -575,6 +584,7 @@ MGAProbe(DriverPtr drv, int flags)
foundScreen = TRUE;
else for (i = 0; i < numUsed; i++) {
ScrnInfoPtr pScrn;
+ EntityInfoPtr pEnt;
#ifdef DISABLE_VGA_IO
MgaSavePtr smga;
#endif
@@ -610,6 +620,37 @@ MGAProbe(DriverPtr drv, int flags)
pScrn->ValidMode = MGAValidMode;
foundScreen = TRUE;
}
+
+ /*
+ * For cards that can do dual head per entity, mark the entity
+ * as sharable.
+ */
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+ if (pEnt->chipset == PCI_CHIP_MGAG400) {
+ MGAEntPtr pMgaEnt = NULL;
+ DevUnion *pPriv;
+
+ xf86SetEntitySharable(usedChips[i]);
+ /* Allocate an entity private if necessary */
+ if (MGAEntityIndex < 0)
+ MGAEntityIndex = xf86AllocateEntityPrivateIndex();
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
+ if (!pPriv->ptr) {
+ pPriv->ptr = xnfcalloc(sizeof(MGAEntRec), 1);
+ pMgaEnt = pPriv->ptr;
+ pMgaEnt->lastInstance = -1;
+ } else {
+ pMgaEnt = pPriv->ptr;
+ }
+ /*
+ * Set the entity instance for this instance of the driver. For
+ * dual head per card, instance 0 is the "master" instance, driving
+ * the primary head, and instance 1 is the "slave".
+ */
+ pMgaEnt->lastInstance++;
+ xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0],
+ pMgaEnt->lastInstance);
+ }
}
if (usedChips)
xfree(usedChips);
@@ -783,6 +824,7 @@ MGASoftReset(ScrnInfoPtr pScrn)
{
MGAPtr pMga = MGAPTR(pScrn);
+ ErrorF("SoftReset called!!!\n");
pMga->FbMapSize = 8192 * 1024;
MGAMapMem(pScrn);
@@ -1071,8 +1113,16 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
double real;
int bytesPerPixel;
ClockRangePtr clockRanges;
+ const char *reqSym = NULL;
const char *s;
int flags24;
+ MGAEntPtr pMgaEnt = NULL;
+#ifdef USEMGAHAL
+ MGAMODEINFO mgaModeInfo = {0};
+ ULONG ulBOARDHANDLESize;
+ UCHAR ucMgaBase2;
+ ULONG ulOrgFBuffer;
+#endif
/*
* Note: This function is only called once at server startup, and
@@ -1097,12 +1147,26 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
}
pMga = MGAPTR(pScrn);
-
+ /* Set here until dri is enabled */
+#ifdef XF86DRI
+ pMga->have_quiescense = 1;
+#endif
/* Get the entity, and make sure it is PCI. */
pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (pMga->pEnt->location.type != BUS_PCI)
return FALSE;
+ /* Allocate an entity private if necessary */
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ pMgaEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ MGAEntityIndex)->ptr;
+ pMga->entityPrivate = pMgaEnt;
+ }
+
+ /* Set pMga->device to the relevant Device section */
+ pMga->device = xf86GetDevFromEntity(pScrn->entityList[0],
+ pScrn->entityInstanceList[0]);
+
if (flags & PROBE_DETECT) {
MGAProbeDDC(pScrn, pMga->pEnt->index);
return TRUE;
@@ -1173,6 +1237,55 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
/* Set pScrn->monitor */
pScrn->monitor = pScrn->confScreen->monitor;
+#if 1
+ /*
+ * XXX This assumes that the lower number screen is always the "master"
+ * head, and that the "master" is the first CRTC. This can result in
+ * unexpected behaviour when the config file marks the primary CRTC
+ * as the second screen.
+ */
+ if(xf86IsEntityShared(pScrn->entityList[0]) &&
+ xf86IsPrimInitDone(pScrn->entityList[0])) {
+ /* This is the second crtc */
+ pMga->SecondCrtc = TRUE;
+ pMga->HWCursor = FALSE;
+ pScrn->AdjustFrame = MGAAdjustFrameCrtc2;
+ pMgaEnt->pScrn_2 = pScrn;
+#ifdef XF86DRI
+ pMga->GetQuiescence = mgaGetQuiescence_shared;
+#endif
+ } else {
+ pMga->SecondCrtc = FALSE;
+ pMga->HWCursor = TRUE;
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ pMgaEnt->pScrn_1 = pScrn;
+#ifdef XF86DRI
+ pMga->GetQuiescence = mgaGetQuiescence_shared;
+#endif
+ } else {
+#ifdef XF86DRI
+ pMga->GetQuiescence = mgaGetQuiescence;
+#endif
+ }
+ }
+#else
+ /*
+ * This is an alternative version that determines which is the secondary
+ * CRTC from the screen field in pMga->device. It doesn't currently
+ * work becasue there are things that assume the primary CRTC is
+ * initialised first.
+ */
+ if (pMga->device->screen == 1) {
+ /* This is the second CRTC */
+ pMga->SecondCrtc = TRUE;
+ pMga->HWCursor = FALSE;
+ pScrn->AdjustFrame = MGAAdjustFrameCrtc2;
+ } else {
+ pMga->SecondCrtc = FALSE;
+ pMga->HWCursor = TRUE;
+ }
+#endif
+
/*
* The first thing we should figure out is the depth, bpp, etc.
* Our default depth is 8, so pass it to the helper function.
@@ -1183,10 +1296,13 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
flags24 = Support24bppFb | Support32bppFb | SupportConvert32to24;
s = xf86TokenToOptName(MGAOptions, OPTION_OVERLAY);
if (!(xf86FindOption(pScrn->confScreen->options, s) ||
- xf86FindOption(pMga->pEnt->device->options, s))) {
+ xf86FindOption(pMga->device->options, s))) {
flags24 |= PreferConvert32to24;
}
+ if (pMga->SecondCrtc)
+ flags24 = Support32bppFb;
+
if (!xf86SetDepthBpp(pScrn, 8, 8, 8, flags24)) {
return FALSE;
} else {
@@ -1243,12 +1359,12 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
* Set the Chipset and ChipRev, allowing config file entries to
* override.
*/
- if (pMga->pEnt->device->chipset && *pMga->pEnt->device->chipset) {
- pScrn->chipset = pMga->pEnt->device->chipset;
+ if (pMga->device->chipset && *pMga->device->chipset) {
+ pScrn->chipset = pMga->device->chipset;
pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset);
from = X_CONFIG;
- } else if (pMga->pEnt->device->chipID >= 0) {
- pMga->Chipset = pMga->pEnt->device->chipID;
+ } else if (pMga->device->chipID >= 0) {
+ pMga->Chipset = pMga->device->chipID;
pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
from = X_CONFIG;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
@@ -1258,8 +1374,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pMga->Chipset = pMga->PciInfo->chipType;
pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
}
- if (pMga->pEnt->device->chipRev >= 0) {
- pMga->ChipRev = pMga->pEnt->device->chipRev;
+ if (pMga->device->chipRev >= 0) {
+ pMga->ChipRev = pMga->device->chipRev;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
pMga->ChipRev);
} else {
@@ -1305,8 +1421,31 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pMga->numXAALines);
}
+#ifdef XF86DRI
+ {
+ Bool temp;
+
+ from = X_DEFAULT;
+
+ pMga->agp_mode = 1;
+ if (xf86GetOptValBool(MGAOptions, OPTION_AGP_MODE_2X,
+ &temp)) {
+ pMga->agp_mode = 2;
+ from = X_CONFIG;
+ }
+
+ if (xf86GetOptValBool(MGAOptions, OPTION_AGP_MODE_4X,
+ &temp)) {
+ pMga->agp_mode = 4;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP Mode %dx\n",
+ pMga->agp_mode);
+ }
+#endif
+
from = X_DEFAULT;
- pMga->HWCursor = TRUE;
+
/*
* The preferred method is to use the "hw cursor" option as a tri-state
* option, with the default set above.
@@ -1346,7 +1485,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
}
if ((s = xf86GetOptValString(MGAOptions, OPTION_OVERLAY))) {
if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) {
- if(pScrn->bitsPerPixel == 32) {
+ if(pScrn->bitsPerPixel == 32 && pMga->SecondCrtc == FALSE) {
pMga->Overlay8Plus24 = TRUE;
if(!xf86GetOptValInteger(
MGAOptions, OPTION_COLOR_KEY,&(pMga->colorKey)))
@@ -1357,13 +1496,15 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
"PseudoColor overlay enabled\n");
} else {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Option \"Overlay\" is only supported in 32 bits per pixel\n");
+ "Option \"Overlay\" is only supported in 32 bits per pixel on"
+ "the first CRTC\n");
}
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
"\"%s\" is not a valid value for Option \"Overlay\"\n", s);
}
}
+
if(xf86GetOptValInteger(MGAOptions, OPTION_VIDEO_KEY, &(pMga->videoKey))) {
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",
pMga->videoKey);
@@ -1467,16 +1608,16 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
* For the 2064 and older rev 1064, base0 is the MMIO and base0 is
* the framebuffer is base1. Let the config file override these.
*/
- if (pMga->pEnt->device->MemBase != 0) {
+ if (pMga->device->MemBase != 0) {
/* Require that the config file value matches one of the PCI values. */
- if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->pEnt->device->MemBase)) {
+ if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->device->MemBase)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"MemBase 0x%08lX doesn't match any PCI base register.\n",
- pMga->pEnt->device->MemBase);
+ pMga->device->MemBase);
MGAFreeRec(pScrn);
return FALSE;
}
- pMga->FbAddress = pMga->pEnt->device->MemBase;
+ pMga->FbAddress = pMga->device->MemBase;
from = X_CONFIG;
} else {
/* details: mgabase2 sdk pp 4-12 */
@@ -1493,19 +1634,20 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
}
+
xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
(unsigned long)pMga->FbAddress);
- if (pMga->pEnt->device->IOBase != 0) {
+ if (pMga->device->IOBase != 0) {
/* Require that the config file value matches one of the PCI values. */
- if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->pEnt->device->IOBase)) {
+ if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->device->IOBase)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"IOBase 0x%08lX doesn't match any PCI base register.\n",
- pMga->pEnt->device->IOBase);
+ pMga->device->IOBase);
MGAFreeRec(pScrn);
return FALSE;
}
- pMga->IOAddress = pMga->pEnt->device->IOBase;
+ pMga->IOAddress = pMga->device->IOBase;
from = X_CONFIG;
} else {
/* details: mgabase1 sdk pp 4-11 */
@@ -1542,9 +1684,9 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
*/
pMga->BiosFrom = X_NONE;
- if (pMga->pEnt->device->BiosBase != 0) {
+ if (pMga->device->BiosBase != 0) {
/* XXX This isn't used */
- pMga->BiosAddress = pMga->pEnt->device->BiosBase;
+ pMga->BiosAddress = pMga->device->BiosBase;
pMga->BiosFrom = X_CONFIG;
} else {
/* details: rombase sdk pp 4-15 */
@@ -1591,20 +1733,73 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
* file, we respect that setting.
*/
from = X_PROBED;
- if (pMga->pEnt->device->videoRam != 0) {
- pScrn->videoRam = pMga->pEnt->device->videoRam;
+ if (pMga->device->videoRam != 0) {
+ pScrn->videoRam = pMga->device->videoRam;
from = X_CONFIG;
} else if (pMga->FBDev) {
pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
} else {
pScrn->videoRam = MGACountRam(pScrn);
}
+
+ if(xf86IsEntityShared(pScrn->entityList[0])) {
+ /* This takes gives either half or 8 meg to the second head
+ * whichever is less. */
+ if(pMga->SecondCrtc == FALSE) {
+ Bool UseHalf = FALSE;
+ int adjust;
+
+ xf86GetOptValBool(MGAOptions, OPTION_CRTC2HALF, &UseHalf);
+ adjust = pScrn->videoRam / 2;
+
+ if (UseHalf == TRUE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Crtc2 will use %dK of VideoRam\n",
+ adjust);
+ } else {
+ adjust = min(adjust, 8192);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Crtc2 will use %dK of VideoRam\n",
+ adjust);
+ }
+ pMgaEnt->mastervideoRam = pScrn->videoRam - adjust;
+ pScrn->videoRam = pMgaEnt->mastervideoRam;
+ pMgaEnt->slavevideoRam = adjust;
+ pMgaEnt->masterFbAddress = pMga->FbAddress;
+ pMga->FbMapSize =
+ pMgaEnt->masterFbMapSize = pScrn->videoRam * 1024;
+ pMgaEnt->slaveFbAddress = pMga->FbAddress +
+ pMgaEnt->masterFbMapSize;
+ pMgaEnt->slaveFbMapSize = pMgaEnt->slavevideoRam * 1024;
+ pMga->realSrcOrg = pMga->SrcOrg = 0;
+ pMga->DstOrg = 0;
+ } else {
+ pMga->FbAddress = pMgaEnt->slaveFbAddress;
+ pMga->FbMapSize = pMgaEnt->slaveFbMapSize;
+ pScrn->videoRam = pMgaEnt->slavevideoRam;
+ pMga->DstOrg = pMga->realSrcOrg =
+ pMgaEnt->slaveFbAddress - pMgaEnt->masterFbAddress;
+ pMga->SrcOrg = 0; /* This is not stored in hw format!! */
+ }
+ pMgaEnt->refCount++;
+ } else {
+ /* Normal Handling of video ram etc */
+ pMga->FbMapSize = pScrn->videoRam * 1024;
+ switch(pMga->Chipset) {
+ case PCI_CHIP_MGAG400:
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ pMga->SrcOrg = 0;
+ pMga->DstOrg = 0;
+ break;
+ default:
+ break;
+ }
+ }
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
pScrn->videoRam);
-
- pMga->FbMapSize = pScrn->videoRam * 1024;
-
- /* Set the bpp shift value */
+
+ /* Set the bpp shift value */
pMga->BppShifts[0] = 0;
pMga->BppShifts[1] = 1;
pMga->BppShifts[2] = 0;
@@ -1670,25 +1865,25 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
* If the user has specified ramdac speed in the XF86Config
* file, we respect that setting.
*/
- if (pMga->pEnt->device->dacSpeeds[0]) {
+ if (pMga->device->dacSpeeds[0]) {
int speed = 0;
switch (pScrn->bitsPerPixel) {
case 8:
- speed = pMga->pEnt->device->dacSpeeds[DAC_BPP8];
+ speed = pMga->device->dacSpeeds[DAC_BPP8];
break;
case 16:
- speed = pMga->pEnt->device->dacSpeeds[DAC_BPP16];
+ speed = pMga->device->dacSpeeds[DAC_BPP16];
break;
case 24:
- speed = pMga->pEnt->device->dacSpeeds[DAC_BPP24];
+ speed = pMga->device->dacSpeeds[DAC_BPP24];
break;
case 32:
- speed = pMga->pEnt->device->dacSpeeds[DAC_BPP32];
+ speed = pMga->device->dacSpeeds[DAC_BPP32];
break;
}
if (speed == 0)
- pMga->MaxClock = pMga->pEnt->device->dacSpeeds[0];
+ pMga->MaxClock = pMga->device->dacSpeeds[0];
else
pMga->MaxClock = speed;
from = X_CONFIG;
@@ -1696,10 +1891,13 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pMga->MaxClock = pMga->Dac.maxPixelClock;
from = pMga->Dac.ClockFrom;
}
+ if(pMga->SecondCrtc == TRUE) {
+ /* Override on 2nd crtc */
+ pMga->MaxClock = 112000;
+ }
xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
pMga->MaxClock / 1000);
-
- /*
+ /*
* Setup the ClockRanges, which describe what clock ranges are available,
* and what sort of modes they can be used for.
*/
@@ -1708,8 +1906,16 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
clockRanges->minClock = pMga->MinClock;
clockRanges->maxClock = pMga->MaxClock;
clockRanges->clockIndex = -1; /* programmable */
- clockRanges->interlaceAllowed = TRUE;
+#ifdef USEMGAHAL
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+#else
+ if (pMga->SecondCrtc == TRUE)
+ clockRanges->interlaceAllowed = FALSE;
+ else
+ clockRanges->interlaceAllowed = TRUE;
clockRanges->doubleScanAllowed = TRUE;
+#endif
clockRanges->ClockMulFactor = 1;
clockRanges->ClockDivFactor = 1;
@@ -1788,6 +1994,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
i = 1;
}
if (i == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Validate Modes Failed\n");
MGAFreeRec(pScrn);
return FALSE;
}
@@ -1800,6 +2007,86 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
MGAFreeRec(pScrn);
return FALSE;
}
+ /*******************/
+ /* ADDED BY MATROX */
+ /*******************/
+#ifdef USEMGAHAL
+ if(pMga->SecondCrtc == FALSE) {
+ ulBOARDHANDLESize = MGAGetBOARDHANDLESize();
+ pMga->pBoard = (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) + ulBOARDHANDLESize);
+ pMga->pClientStruct = (LPCLIENTDATA) xalloc (sizeof(CLIENTDATA));
+ /* Fill the client part */
+ pMga->pClientStruct->pMga = (MGAPtr) pMga;
+
+ /* Determine the Frame buffer limit size */
+ if((pMga->Chipset == PCI_CHIP_MGA1064 && pMga->ChipRev < 3) ||
+ (pMga->Chipset == PCI_CHIP_MGA2064)) {
+ ucMgaBase2 = 0x14;
+ } else {
+ ucMgaBase2 = 0x10;
+ }
+#if 0
+ /*
+ * This is bad for cards where there is less physical memory than
+ * the PCI map size.
+ */
+ ulOrgFBuffer = pciReadLong(pMga->PciTag,ucMgaBase2);
+ pciWriteLong(pMga->PciTag,ucMgaBase2,0xffffffff);
+ pMga->FbMapSize = pciReadLong(pMga->PciTag,ucMgaBase2);
+ pciWriteLong(pMga->PciTag,ucMgaBase2,ulOrgFBuffer);
+ pMga->FbMapSize = ~(pMga->FbMapSize & 0xfffffff0) + 1;
+#endif
+ /* Open the matrox low level library */
+ MGAMapMem(pScrn);
+ MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
+ MGAUnmapMem(pScrn);
+ pMga->pMgaHwInfo = (LPMGAHWINFO) xalloc (sizeof(MGAHWINFO));
+ MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
+ /* copy the board handles */
+ if(xf86IsEntityShared(pScrn->entityList[0])) {
+ pMgaEnt->pClientStruct = pMga->pClientStruct;
+ pMgaEnt->pBoard = pMga->pBoard;
+ pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo;
+ }
+ mgaModeInfo.flOutput = MGAMODEINFO_ANALOG1;
+#if 1
+ mgaModeInfo.ulDispWidth = pScrn->virtualX;
+ mgaModeInfo.ulDispHeight = pScrn->virtualY;
+#else
+ mgaModeInfo.ulDispWidth = pScrn->modes->HDisplay;
+ mgaModeInfo.ulDispHeight = pScrn->modes->VDisplay;
+#endif
+ mgaModeInfo.ulDeskWidth = pScrn->virtualX;
+ mgaModeInfo.ulDeskHeight = pScrn->virtualY;
+ mgaModeInfo.ulBpp = pScrn->bitsPerPixel;
+ mgaModeInfo.ulZoom = 1;
+ } else { /* Second CRTC && entity is shared */
+ mgaModeInfo.flOutput = MGAMODEINFO_ANALOG2 |
+ MGAMODEINFO_SECOND_CRTC;
+#if 1
+ mgaModeInfo.ulDispWidth = pScrn->virtualX;
+ mgaModeInfo.ulDispHeight = pScrn->virtualY;
+#else
+ mgaModeInfo.ulDispWidth = pScrn->modes->HDisplay;
+ mgaModeInfo.ulDispHeight = pScrn->modes->VDisplay;
+#endif
+ mgaModeInfo.ulDeskWidth = pScrn->virtualX;
+ mgaModeInfo.ulDeskHeight = pScrn->virtualY;
+ mgaModeInfo.ulBpp = pScrn->bitsPerPixel;
+ mgaModeInfo.ulZoom = 1;
+ pMga->pBoard = pMgaEnt->pBoard;
+ pMga->pClientStruct = pMgaEnt->pClientStruct;
+ pMga->pMgaHwInfo = pMga->pMgaHwInfo;
+ }
+ if(MGAValidateMode(pMga->pBoard,&mgaModeInfo) != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "MGAValidateMode found the mode to be invalid\n");
+ return FALSE;
+ }
+
+ pScrn->displayWidth = mgaModeInfo.ulFBPitch;
+
+#endif /* USEMGAHAL */
/*
* Set the CRTC parameters for all of the modes based on the type
@@ -1809,8 +2096,11 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
* driver and if the driver doesn't provide code to set them. They
* are not pre-initialised at all.
*/
- xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
-
+#ifdef USEMGAHAL
+ xf86SetCrtcForModes(pScrn, 0);
+#else
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+#endif
/* Set the current mode to the first in the list */
pScrn->currentMode = pScrn->modes;
@@ -1869,43 +2159,73 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n",
pMga->YDstOrg);
- pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel;
+ if(xf86IsEntityShared(pScrn->entityList[0])) {
+ if(pMga->SecondCrtc == FALSE) {
+ pMga->FbUsableSize = pMgaEnt->masterFbMapSize;
+ /* Allocate HW cursor buffer at the end of video ram */
+ if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
+ if( pScrn->virtualY * pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8 <=
+ pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
+ pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
+ pMga->FbCursorOffset =
+ pMgaEnt->masterFbMapSize -
+ pMga->Dac.CursorOffscreenMemSize;
+ } else {
+ pMga->HWCursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Too little offscreen memory for HW cursor; "
+ "using SW cursor\n");
+ }
+ }
+ } else { /* Second CRTC */
+ pMga->FbUsableSize = pMgaEnt->slaveFbMapSize;
+ pMga->HWCursor = FALSE;
+ }
+ } else {
+ pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel;
+ /* Allocate HW cursor buffer at the end of video ram */
+ if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
+ if( pScrn->virtualY * pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8 <=
+ pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
+ pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
+ pMga->FbCursorOffset =
+ pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize;
+ } else {
+ pMga->HWCursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Too little offscreen memory for HW cursor; "
+ "using SW cursor\n");
+ }
+ }
+ }
/*
* XXX This should be taken into account in some way in the mode valdation
* section.
*/
- /* Allocate HW cursor buffer at the end of video ram */
- if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
- if( pScrn->virtualY * pScrn->displayWidth * pScrn->bitsPerPixel / 8 <=
- pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
- pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
- pMga->FbCursorOffset =
- pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize;
- } else {
- pMga->HWCursor = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Too little offscreen memory for HW cursor; using SW cursor\n");
- }
- }
/* Load the required framebuffer */
- if(pMga->Overlay8Plus24) {
+ if (pMga->Overlay8Plus24) {
if (!xf86LoadSubModule(pScrn, "xf8_32bpp")) {
MGAFreeRec(pScrn);
return FALSE;
}
- xf86LoaderReqSymbols("cfb8_32ScreenInit", NULL);
+ reqSym = "cfb8_32ScreenInit";
} else {
if (!xf86LoadSubModule(pScrn, "fb")) {
MGAFreeRec(pScrn);
return FALSE;
}
+ reqSym = "fbScreenInit";
xf86LoaderReqSymbols("fbScreenInit", NULL);
#ifdef RENDER
xf86LoaderReqSymbols("fbPictureInit", NULL);
#endif
}
+ xf86LoaderReqSymbols(reqSym, NULL);
+
/* Load XAA if needed */
if (!pMga->NoAccel) {
@@ -1942,7 +2262,43 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pMga->CurrentLayout.weight.blue = pScrn->weight.blue;
pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24;
pMga->CurrentLayout.mode = pScrn->currentMode;
+#ifdef USEMGAHAL
+ /* Close the library after preinit */
+ /* This needs to only happen after this board has completed preinit
+ * both times
+ */
+ if(xf86IsEntityShared(pScrn->entityList[0])) {
+ /* Entity is shared make sure refcount == 2 */
+ /* If ref count is 2 then reset it to 0 */
+ if(pMgaEnt->refCount == 2) {
+ /* Both boards have done there initialization */
+ MGACloseLibrary(pMga->pBoard);
+
+ if (pMga->pBoard)
+ xfree(pMga->pBoard);
+ if (pMga->pClientStruct)
+ xfree(pMga->pClientStruct);
+ if (pMga->pMgaModeInfo)
+ xfree(pMga->pMgaModeInfo);
+ if (pMga->pMgaHwInfo)
+ xfree(pMga->pMgaHwInfo);
+ pMgaEnt->refCount = 0;
+ }
+ } else {
+ MGACloseLibrary(pMga->pBoard);
+
+ if (pMga->pBoard)
+ xfree(pMga->pBoard);
+ if (pMga->pClientStruct)
+ xfree(pMga->pClientStruct);
+ if (pMga->pMgaModeInfo)
+ xfree(pMga->pMgaModeInfo);
+ if (pMga->pMgaHwInfo)
+ xfree(pMga->pMgaHwInfo);
+ }
+#endif
+ xf86SetPrimInitDone(pScrn->entityList[0]);
return TRUE;
}
@@ -2089,10 +2445,51 @@ MGASave(ScrnInfoPtr pScrn)
MGAPtr pMga = MGAPTR(pScrn);
MGARegPtr mgaReg = &pMga->SavedReg;
+#ifdef USEMGAHAL
+ if(pMga->SecondCrtc == TRUE) return;
+
+ if(pMga->pBoard != NULL) {
+ MGASaveVgaState(pMga->pBoard);
+ }
+#endif
+
/* Only save text mode fonts/text for the primary card */
(*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary);
}
+#ifdef USEMGAHAL
+/* Convert DisplayModeRec parameters in MGAMODEINFO parameters. */
+static void FillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ pMga->pMgaModeInfo = (LPMGAMODEINFO) xalloc (sizeof(MGAMODEINFO));
+
+ pMga->pMgaModeInfo->flOutput = 0;
+ pMga->pMgaModeInfo->ulDispWidth = mode->HDisplay;
+ pMga->pMgaModeInfo->ulDispHeight = mode->VDisplay;
+ pMga->pMgaModeInfo->ulDeskWidth = pScrn->virtualX;
+ pMga->pMgaModeInfo->ulDeskHeight = pScrn->virtualY;
+ pMga->pMgaModeInfo->ulFBPitch = 0;
+ pMga->pMgaModeInfo->ulBpp = pScrn->bitsPerPixel;
+ pMga->pMgaModeInfo->ulZoom = 1;
+ pMga->pMgaModeInfo->flSignalMode = 0;
+ pMga->pMgaModeInfo->ulRefreshRate = 0;
+ pMga->pMgaModeInfo->ulHorizRate = 0;
+ pMga->pMgaModeInfo->ulPixClock = mode->Clock;
+ pMga->pMgaModeInfo->ulHFPorch = mode->HSyncStart - mode->HDisplay;
+ pMga->pMgaModeInfo->ulHSync = mode->HSyncEnd - mode->HSyncStart;
+ pMga->pMgaModeInfo->ulHBPorch = mode->HTotal - mode->HSyncEnd;
+ pMga->pMgaModeInfo->ulVFPorch = mode->VSyncStart - mode->VDisplay;
+ pMga->pMgaModeInfo->ulVSync = mode->VSyncEnd - mode->VSyncStart;
+ pMga->pMgaModeInfo->ulVBPorch = mode->VTotal - mode->VSyncEnd;
+ /* Use DstOrg directly */
+ /* This is an offset in pixels not memory */
+ pMga->pMgaModeInfo->ulDstOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8);
+ pMga->pMgaModeInfo->ulDisplayOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8);
+ pMga->pMgaModeInfo->ulPanXGran = 0;
+ pMga->pMgaModeInfo->ulPanYGran = 0;
+}
+#endif /* USEMGAHAL */
/*
* Initialise a new mode. This is currently still using the old
@@ -2123,13 +2520,57 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
vgaReg = &hwp->ModeReg;
mgaReg = &pMga->ModeReg;
+#ifdef USEMGAHAL
+ FillModeInfoStruct(pScrn,mode);
+
+ if(pMga->SecondCrtc == TRUE) {
+ pMga->pMgaModeInfo->flOutput = MGAMODEINFO_ANALOG2 |
+ MGAMODEINFO_SECOND_CRTC |
+ MGAMODEINFO_FORCE_PITCH |
+ MGAMODEINFO_FORCE_DISPLAYORG;
+ } else {
+ pMga->pMgaModeInfo->flOutput = MGAMODEINFO_ANALOG1 |
+ MGAMODEINFO_FORCE_PITCH;
+ }
+
+ pMga->pMgaModeInfo->ulFBPitch = pScrn->displayWidth;
+ if(MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Invalid parameters\n");
+ return FALSE;
+ }
+
+ if(MGAValidateVideoParameters(pMga->pBoard,pMga->pMgaModeInfo) != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Invalid parameters\n");
+ return FALSE;
+ }
+#endif /* USEMGAHAL */
+
#ifdef XF86DRI
if (pMga->directRenderingEnabled) {
DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
}
#endif
+
+#ifdef USEMGAHAL
+ if(MGASetMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) {
+ return FALSE;
+ }
+
+#define outMGAdreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val)
+
+#define outMGAdac(reg, val) \
+ (outMGAdreg(MGA1064_INDEX, reg), outMGAdreg(MGA1064_DATA, val))
+
+ if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) {
+ outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, pMga->FbCursorOffset >> 10);
+ outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, pMga->FbCursorOffset >> 18);
+ }
+#endif /* USEMGAHAL */
+
+#ifndef USEMGAHAL
(*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE);
+#endif
MGAStormSync(pScrn);
MGAStormEngineInit(pScrn);
@@ -2163,19 +2604,50 @@ MGARestore(ScrnInfoPtr pScrn)
MGAPtr pMga = MGAPTR(pScrn);
MGARegPtr mgaReg = &pMga->SavedReg;
- if (pScrn->pScreen != NULL)
- MGAStormSync(pScrn);
+ if (pScrn->pScreen != NULL)
+ MGAStormSync(pScrn);
+
+ if(pMga->SecondCrtc == TRUE) return;
/* Only restore text mode fonts/text for the primary card */
vgaHWProtect(pScrn, TRUE);
- if (pMga->Primary)
+ if (pMga->Primary) {
+#ifdef USEMGAHAL
+ if(pMga->pBoard != NULL) {
+ MGASetVgaMode(pMga->pBoard);
+ MGARestoreVgaState(pMga->pBoard);
+ }
+#endif
(*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE);
- else
+ } else {
vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ }
vgaHWProtect(pScrn, FALSE);
}
+/* Workaround for a G400 CRTC2 display problem */
+static void
+MGACrtc2FillStrip(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if (pMga->NoAccel) {
+ /* Clears the whole screen, but ... */
+ bzero(pMga->FbStart,
+ (pScrn->bitsPerPixel >> 3) * pScrn->displayWidth * pScrn->virtualY);
+ } else {
+ xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex);
+ pMga->RestoreAccelState(pScrn);
+ pMga->SetupForSolidFill(pScrn, 0, GXcopy, 0xFFFFFFFF);
+ pMga->SubsequentSolidFillRect(pScrn, pScrn->virtualX, 0,
+ pScrn->displayWidth - pScrn->virtualX,
+ pScrn->virtualY);
+ MGAStormSync(pScrn);
+ }
+}
+
+
/* Mandatory */
/* This gets called at the start of each server generation */
@@ -2191,6 +2663,8 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
VisualPtr visual;
unsigned char *FBStart;
int width, height, displayWidth;
+ MGAEntPtr pMgaEnt = NULL;
+ int f;
/*
* First get the ScrnInfoRec
@@ -2200,6 +2674,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
hwp = VGAHWPTR(pScrn);
pMga = MGAPTR(pScrn);
MGAdac = &pMga->Dac;
+
/* Map the MGA memory and MMIO areas */
if (pMga->FBDev) {
@@ -2210,6 +2685,51 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
}
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ DevUnion *pPriv;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
+ pMgaEnt = pPriv->ptr;
+ pMgaEnt->refCount++;
+#ifdef USEMGAHAL
+ if(pMgaEnt->refCount == 1) {
+ pMga->pBoard =
+ (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) +
+ MGAGetBOARDHANDLESize());
+ pMga->pClientStruct = (LPCLIENTDATA) xalloc (sizeof(CLIENTDATA));
+ /* Fill the client part */
+ pMga->pClientStruct->pMga = (MGAPtr) pMga;
+
+ MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
+
+ pMga->pMgaHwInfo = (LPMGAHWINFO) xalloc (sizeof(MGAHWINFO));
+ MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
+ /* Now copy these to the entitystructure */
+ pMgaEnt->pClientStruct = pMga->pClientStruct;
+ pMgaEnt->pBoard = pMga->pBoard;
+ pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo;
+ } else { /* Ref count is 2 */
+ pMga->pClientStruct = pMgaEnt->pClientStruct;
+ pMga->pBoard = pMgaEnt->pBoard;
+ pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo;
+ }
+#endif /* USEMGAHAL */
+ } else {
+#ifdef USEMGAHAL
+ pMga->pBoard =
+ (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) +
+ MGAGetBOARDHANDLESize());
+ pMga->pClientStruct = (LPCLIENTDATA) xalloc (sizeof(CLIENTDATA));
+ /* Fill the client part */
+ pMga->pClientStruct->pMga = (MGAPtr) pMga;
+
+ MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));
+
+ pMga->pMgaHwInfo = (LPMGAHWINFO) xalloc (sizeof(MGAHWINFO));
+ MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);
+#endif /* USEMGAHAL */
+ }
+
+
/* Initialise the MMIO vgahw functions */
vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET);
vgaHWGetIOBase(hwp);
@@ -2238,7 +2758,11 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* Darken the screen for aesthetic reasons and set the viewport */
- MGASaveScreen(pScreen, SCREEN_SAVER_ON);
+ if (pMga->SecondCrtc == TRUE) {
+ MGASaveScreenCrtc2(pScreen, SCREEN_SAVER_ON);
+ } else {
+ MGASaveScreen(pScreen, SCREEN_SAVER_ON);
+ }
pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
/*
@@ -2267,6 +2791,11 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
if (!miSetVisualTypes(24, TrueColorMask, pScrn->rgbBits, TrueColor))
return FALSE;
+ } else if (pMga->SecondCrtc) {
+ /* No DirectColor on the second head */
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ TrueColor))
+ return FALSE;
} else {
if (!xf86SetDefaultVisual(pScrn, -1))
return FALSE;
@@ -2313,27 +2842,29 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* The DRI does not work when textured video is enabled at this time.
*/
- if (!pMga->NoAccel && pMga->TexturedVideo != TRUE)
+ if (!pMga->NoAccel && pMga->TexturedVideo != TRUE &&
+ pMga->SecondCrtc == FALSE)
pMga->directRenderingEnabled = MGADRIScreenInit(pScreen);
else
pMga->directRenderingEnabled = FALSE;
#endif
-
- if(pMga->Overlay8Plus24) {
+
+ if (pMga->Overlay8Plus24) {
ret = cfb8_32ScreenInit(pScreen, FBStart,
width, height,
pScrn->xDpi, pScrn->yDpi,
displayWidth);
} else {
ret = fbScreenInit(pScreen, FBStart, width, height,
- pScrn->xDpi, pScrn->yDpi,
- displayWidth, pScrn->bitsPerPixel);
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth, pScrn->bitsPerPixel);
#ifdef RENDER
if (ret)
fbPictureInit (pScreen, 0, 0);
#endif
}
+
if (!ret)
return FALSE;
@@ -2386,9 +2917,12 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* Initialize colormap layer.
Must follow initialization of the default colormap */
+ if (!pMga->SecondCrtc)
+ f = CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH;
+ else
+ f = CMAP_RELOAD_ON_MODE_SWITCH;
if(!xf86HandleColormaps(pScreen, 256, 8,
- (pMga->FBDev ? fbdevHWLoadPalette : MGAdac->LoadPalette), NULL,
- CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH))
+ (pMga->FBDev ? fbdevHWLoadPalette : MGAdac->LoadPalette), NULL, f))
return FALSE;
if(pMga->Overlay8Plus24) { /* Must come after colormap initialization */
@@ -2436,14 +2970,20 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n");
}
+ if (xf86IsEntityShared(pScrn->entityList[0]) && pMga->SecondCrtc == FALSE)
+ pMgaEnt->directRenderingEnabled = pMga->directRenderingEnabled;
+ pMga->have_quiescense = 1;
#endif
pScrn->memPhysBase = pMga->FbAddress;
pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
- MGAInitVideo(pScreen);
-
- pScreen->SaveScreen = MGASaveScreen;
+ if(pMga->SecondCrtc == TRUE) {
+ pScreen->SaveScreen = MGASaveScreenCrtc2;
+ } else {
+ pScreen->SaveScreen = MGASaveScreen;
+ MGAInitVideo(pScreen);
+ }
/* Wrap the current CloseScreen function */
pMga->CloseScreen = pScreen->CloseScreen;
@@ -2454,6 +2994,11 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
}
+ /* For the second head, work around display problem. */
+ if (pMga->SecondCrtc) {
+ MGACrtc2FillStrip(pScrn);
+ }
+
/* Done */
return TRUE;
}
@@ -2512,6 +3057,33 @@ MGAAdjustFrame(int scrnIndex, int x, int y, int flags)
}
+#define C2STARTADD0 0x3C28
+
+void
+MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn;
+ int Base;
+ MGAFBLayout *pLayout;
+ MGAPtr pMga;
+
+ pScrn = xf86Screens[scrnIndex];
+ pMga = MGAPTR(pScrn);
+ pLayout = &pMga->CurrentLayout;
+
+ if(pMga->ShowCache && y && pScrn->vtSema)
+ y += pScrn->virtualY - 1;
+
+ /* 3-85 c2offset
+ * 3-93 c2startadd0
+ * 3-96 c2vcount
+ */
+
+ Base = (y * pLayout->displayWidth + x) * pLayout->bitsPerPixel >> 3;
+ Base += pMga->DstOrg;
+ Base &= 0x01ffffc0;
+ OUTREG(C2STARTADD0, Base);
+}
/*
* This is called when VT switching back to the X server. Its job is
@@ -2525,12 +3097,15 @@ static Bool
MGAEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ MGAPtr pMga;
#ifdef XF86DRI
ScreenPtr pScreen;
- MGAPtr pMGA;
+#endif
- pMGA = MGAPTR(pScrn);
- if (pMGA->directRenderingEnabled) {
+ pMga = MGAPTR(pScrn);
+
+#ifdef XF86DRI
+ if (pMga->directRenderingEnabled) {
pScreen = screenInfo.screens[scrnIndex];
DRIUnlock(pScreen);
}
@@ -2539,6 +3114,12 @@ MGAEnterVT(int scrnIndex, int flags)
if (!MGAModeInit(pScrn, pScrn->currentMode))
return FALSE;
MGAAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /* For the second head, work around display problem. */
+ if (pMga->SecondCrtc) {
+ MGACrtc2FillStrip(pScrn);
+ }
+
return TRUE;
}
@@ -2610,7 +3191,8 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
vgaHWPtr hwp = VGAHWPTR(pScrn);
MGAPtr pMga = MGAPTR(pScrn);
-
+ MGAEntPtr pMgaEnt = NULL;
+
if (pScrn->vtSema) {
if (pMga->FBDev) {
fbdevHWRestore(pScrn);
@@ -2628,7 +3210,43 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
pMga->directRenderingEnabled=FALSE;
}
#endif
-
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ DevUnion *pPriv;
+ pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex);
+ pMgaEnt = pPriv->ptr;
+ pMgaEnt->refCount--;
+ }
+
+#ifdef USEMGAHAL
+ if(xf86IsEntityShared(pScrn->entityList[0])) {
+ if(pMgaEnt->refCount == 0) {
+ /* Both boards have closed there screen */
+ MGACloseLibrary(pMga->pBoard);
+
+ if (pMga->pBoard)
+ xfree(pMga->pBoard);
+ if (pMga->pClientStruct)
+ xfree(pMga->pClientStruct);
+ if (pMga->pMgaModeInfo)
+ xfree(pMga->pMgaModeInfo);
+ if (pMga->pMgaHwInfo)
+ xfree(pMga->pMgaHwInfo);
+ }
+ } else {
+ MGACloseLibrary(pMga->pBoard);
+
+ if (pMga->pBoard)
+ xfree(pMga->pBoard);
+ if (pMga->pClientStruct)
+ xfree(pMga->pClientStruct);
+ if (pMga->pMgaModeInfo)
+ xfree(pMga->pMgaModeInfo);
+ if (pMga->pMgaHwInfo)
+ xfree(pMga->pMgaHwInfo);
+ }
+#endif /* USEMGAHAL */
+
if (pMga->AccelInfoRec)
XAADestroyInfoRec(pMga->AccelInfoRec);
if (pMga->CursorInfoRec)
@@ -2649,6 +3267,8 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
if (xf86IsPc98())
outb(0xfac, 0x00);
+ xf86ClearPrimInitDone(pScrn->entityList[0]);
+
if(pMga->BlockHandler)
pScreen->BlockHandler = pMga->BlockHandler;
@@ -2680,6 +3300,8 @@ static int
MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
int lace;
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ MGAPtr pMga = MGAPTR(pScrn);
lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
@@ -2691,6 +3313,17 @@ MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
(mode->CrtcVSyncStart <= 4096 * lace) &&
(mode->CrtcVSyncEnd <= 4096 * lace) &&
(mode->CrtcVTotal <= 4096 * lace)) {
+
+ /* Can't have horizontal panning for second head of G400 */
+ if (pMga->SecondCrtc) {
+ if (flags == MODECHECK_FINAL) {
+ if (pMga->allowedWidth == 0)
+ pMga->allowedWidth = pScrn->virtualX;
+ if (mode->HDisplay != pMga->allowedWidth)
+ return(MODE_ONE_WIDTH);
+ }
+ }
+
return(MODE_OK);
} else {
return(MODE_BAD);
@@ -2701,6 +3334,36 @@ MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
/* Do screen blanking */
/* Mandatory */
+#define MGAREG_C2CTL 0x3c10
+
+static Bool
+MGASaveScreenCrtc2(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = NULL;
+ MGAPtr pMga = NULL;
+ Bool on;
+ CARD32 tmp;
+
+ on = xf86IsUnblank(mode);
+
+ if (on)
+ SetTimeSinceLastInputEvent();
+ if (pScreen != NULL)
+ pScrn = xf86Screens[pScreen->myNum];
+
+ if (pScrn != NULL)
+ pMga = MGAPTR(pScrn);
+
+ if(pMga != NULL && pScrn->vtSema) {
+ tmp = INREG(MGAREG_C2CTL);
+ tmp &= ~0x00000008;
+ if (!on) tmp |= 0x0000008;
+ OUTREG(MGAREG_C2CTL, tmp);
+ }
+
+ return TRUE;
+}
+
static Bool
MGASaveScreen(ScreenPtr pScreen, int mode)
{
@@ -2721,8 +3384,6 @@ MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
MGAPtr pMga = MGAPTR(pScrn);
unsigned char seq1 = 0, crtcext1 = 0;
-ErrorF("MGADisplayPowerManagementSet: %d\n", PowerManagementMode);
-
switch (PowerManagementMode)
{
case DPMSModeOn: