summaryrefslogtreecommitdiff
path: root/src/sis_driver.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:49:00 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:49:00 +0000
commit358bf68d49977ee48bdbc0aabec6a2f827dfbf4c (patch)
tree59172aa954c76690ee07eeee29652033029e9064 /src/sis_driver.c
parent49e117b6598ba3b812a705297b4679eb95137d5c (diff)
merge latest (4.3.99.16) from XFree86 (vendor) branch
Diffstat (limited to 'src/sis_driver.c')
-rw-r--r--src/sis_driver.c9724
1 files changed, 6744 insertions, 2980 deletions
diff --git a/src/sis_driver.c b/src/sis_driver.c
index eb89fe2..833e3c3 100644
--- a/src/sis_driver.c
+++ b/src/sis_driver.c
@@ -1,7 +1,9 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.86 2003/02/04 02:44:29 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.156 2003/11/20 19:53:23 twini Exp $ */
/*
+ * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Formerly based on old code which is
* Copyright 1998,1999 by Alan Hourihane, Wigan, England.
- * Parts Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -21,36 +23,45 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
- * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ * - driver entirely rewritten, only basic structure taken from old code
+ * (except sis_dri.c, sis_shadow.c and parts of sis_dga.c;
+ * these were taken over; sis_dri.c was slightly adapted):
+ * - rewritten for 5597/5598, 6326 and 530/620 chipsets,
+ * - rewritten for 300 series (300/540/630/730),
+ * - 315 series (315/550/650/651/M650/661FX/M661FX/M661MX/740/741) support
+ * - 330 series (330/760) support
+ * - dual head support for 300, 315 and 330 series
+ * - merged-framebuffer support for 300, 315 and 330 series
+ * - pseudo-xinerama extension for MergedFB mode
+ * - SiS video bridge support for 300, 315 and 330 series (LCD, TV, VGA2),
+ * - LVDS support for 300 and 315 series,
+ * - Chrontel 7019/LVDS support (650, 740; up to 1600x1200)
+ * - Chrontel 700x, 701x support for TV output
+ * - VESA mode switching (deprecated),
+ * - plasma panel support,
+ * - entirely rewritten Xv support for 300 series
+ * - Xv support for 5597/5598, 6326, 530/620, 315 and 330 series
+ * - TV and hi-res support for the 6326
+ * - color HW cursor support for 300(emulated), 315 and 330 series
+ * - SiSCtrl interface for 300, 315 and 330 series
+ * - etc. etc. etc.
+ *
+ * This notice covers the entire driver code
+ *
+ * Authors of old code:
+ * Alan Hourihane, alanh@fairlite.demon.co.uk
* Mike Chapman <mike@paranoia.com>,
* Juanjo Santamarta <santamarta@ctv.es>,
* Mitani Hiroshi <hmitani@drl.mei.co.jp>
* David Thomas <davtom@dream.org.uk>.
- *
- * Thomas Winischhofer <thomas@winischhofer.net>:
- * - 310/325 series (315/550/650/651/740/M650) support
- * - (possibly incomplete) Xabre (SiS330) support
- * - new mode switching code for 300, 310/325 and 330 series
- * - many fixes for 300/540/630/730 chipsets,
- * - many fixes for 5597/5598, 6326 and 530/620 chipsets,
- * - VESA mode switching (deprecated),
- * - extended CRT2/video bridge handling support,
- * - dual head support on 300, 310/325 and 330 series
- * - 650/LVDS (up to 1400x1050), 650/Chrontel 701x support
- * - 30xB/30xLV/30xLVX video bridge support (300, 310/325, 330 series)
- * - Xv support for 5597/5598, 6326, 530/620 and 310/325 series
- * - video overlay enhancements for 300 series
- * - TV and hi-res support for the 6326
- * - Color HW cursor support for 300(emulated), 310/325 and 330 series
- * - etc.
*/
#include "fb.h"
-#include "xf1bpp.h"
-#include "xf4bpp.h"
#include "mibank.h"
#include "micmap.h"
#include "xf86.h"
+#include "xf86Priv.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "xf86_ansic.h"
@@ -68,7 +79,7 @@
#include "mipointer.h"
#include "mibstore.h"
-
+
#include "sis.h"
#include "sis_regs.h"
#include "sis_vb.h"
@@ -80,10 +91,11 @@
#include "extensions/xf86dgastr.h"
#include "globals.h"
+
#define DPMS_SERVER
#include "extensions/dpms.h"
-#ifdef XvExtension
+#if (XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,0,0)) || (defined(XvExtension))
#include "xf86xv.h"
#include "Xv.h"
#endif
@@ -92,82 +104,29 @@
#include "dri.h"
#endif
-/* Mandatory functions */
-static void SISIdentify(int flags);
-static Bool SISProbe(DriverPtr drv, int flags);
-static Bool SISPreInit(ScrnInfoPtr pScrn, int flags);
-static Bool SISScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
-static Bool SISEnterVT(int scrnIndex, int flags);
-static void SISLeaveVT(int scrnIndex, int flags);
-static Bool SISCloseScreen(int scrnIndex, ScreenPtr pScreen);
-static Bool SISSaveScreen(ScreenPtr pScreen, int mode);
-static Bool SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
-static void SISAdjustFrame(int scrnIndex, int x, int y, int flags);
-#ifdef SISDUALHEAD
-static Bool SISSaveScreenDH(ScreenPtr pScreen, int mode);
-#endif
-
-/* Optional functions */
-static void SISFreeScreen(int scrnIndex, int flags);
-static int SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
- int flags);
-
-/* Internally used functions */
-static Bool SISMapMem(ScrnInfoPtr pScrn);
-static Bool SISUnmapMem(ScrnInfoPtr pScrn);
-static void SISSave(ScrnInfoPtr pScrn);
-static void SISRestore(ScrnInfoPtr pScrn);
-static void SISVESARestore(ScrnInfoPtr pScrn);
-static Bool SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
-static void SISModifyModeInfo(DisplayModePtr mode);
-static void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
-static void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg);
-static void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg);
-static Bool SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
-static void SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe);
-static UShort SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
-static void SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function);
-static void SISBridgeRestore(ScrnInfoPtr pScrn);
-static void SiSEnableTurboQueue(ScrnInfoPtr pScrn);
-unsigned char SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode);
-static void SISWaitVBRetrace(ScrnInfoPtr pScrn);
-
-void SISWaitRetraceCRT1(ScrnInfoPtr pScrn);
-void SISWaitRetraceCRT2(ScrnInfoPtr pScrn);
-
-BOOLEAN SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn);
-#ifdef CYCLECRT2
-Bool SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode);
-#endif
+/* Globals (yes, these ARE really required to be global) */
-#ifdef DEBUG
-static void SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode);
-#endif
-
-/* TW: New mode switching functions */
-extern BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
- ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
-extern BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
- ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
-extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
-extern USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
-extern void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
-extern DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
#ifdef SISDUALHEAD
-extern BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
- ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
-extern BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
- ScrnInfoPtr pScrn, DisplayModePtr mode);
+static int SISEntityIndex = -1;
#endif
-/* TW: For power management for 310/325 series */
-extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
-extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
-extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
+#ifdef SISMERGED
+#ifdef SISXINERAMA
+static Bool SiSnoPanoramiXExtension = TRUE;
+int SiSXineramaPixWidth = 0;
+int SiSXineramaPixHeight = 0;
+int SiSXineramaNumScreens = 0;
+SiSXineramaData *SiSXineramadataPtr = NULL;
+static int SiSXineramaGeneration;
-#ifdef SISDUALHEAD
-static int SISEntityIndex = -1;
+int SiSProcXineramaQueryVersion(ClientPtr client);
+int SiSProcXineramaGetState(ClientPtr client);
+int SiSProcXineramaGetScreenCount(ClientPtr client);
+int SiSProcXineramaGetScreenSize(ClientPtr client);
+int SiSProcXineramaIsActive(ClientPtr client);
+int SiSProcXineramaQueryScreens(ClientPtr client);
+int SiSSProcXineramaDispatch(ClientPtr client);
+#endif
#endif
/*
@@ -206,9 +165,8 @@ static SymTabRec SISChipsets[] = {
{ PCI_CHIP_SIS315PRO, "SIS315PRO" },
{ PCI_CHIP_SIS550, "SIS550" },
{ PCI_CHIP_SIS650, "SIS650/M650/651/740" },
-#ifdef INCL_SIS330 /* TW: New for SiS330 (untested) */
{ PCI_CHIP_SIS330, "SIS330(Xabre)" },
-#endif
+ { PCI_CHIP_SIS660, "SIS660/661FX/M661FX/M661MX/741/760" },
{ -1, NULL }
};
@@ -224,9 +182,8 @@ static PciChipsets SISPciChipsets[] = {
{ PCI_CHIP_SIS315H, PCI_CHIP_SIS315H, RES_SHARED_VGA },
{ PCI_CHIP_SIS315PRO, PCI_CHIP_SIS315PRO, RES_SHARED_VGA },
{ PCI_CHIP_SIS650, PCI_CHIP_SIS650, RES_SHARED_VGA },
-#ifdef INCL_SIS330 /* TW: New for SiS330 */
{ PCI_CHIP_SIS330, PCI_CHIP_SIS330, RES_SHARED_VGA },
-#endif
+ { PCI_CHIP_SIS660, PCI_CHIP_SIS660, RES_SHARED_VGA },
{ -1, -1, RES_UNDEFINED }
};
@@ -234,7 +191,10 @@ static const char *xaaSymbols[] = {
"XAACopyROP",
"XAACreateInfoRec",
"XAADestroyInfoRec",
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0)
"XAAFillSolidRects",
+#endif
+ "XAAFillMono8x8PatternRects",
"XAAHelpPatternROP",
"XAAInit",
NULL
@@ -248,6 +208,7 @@ static const char *vgahwSymbols[] = {
"vgaHWInit",
"vgaHWLock",
"vgaHWMapMem",
+ "vgaHWUnmapMem",
"vgaHWProtect",
"vgaHWRestore",
"vgaHWSave",
@@ -256,12 +217,6 @@ static const char *vgahwSymbols[] = {
NULL
};
-static const char *miscfbSymbols[] = {
- "xf1bppScreenInit",
- "xf4bppScreenInit",
- NULL
-};
-
static const char *fbSymbols[] = {
"fbPictureInit",
"fbScreenInit",
@@ -284,16 +239,6 @@ static const char *ddcSymbols[] = {
"xf86PrintEDID",
"xf86SetDDCproperties",
"xf86InterpretEDID",
- "xf86DoEDID_DDC1",
-#ifdef SISI2C
- "xf86DoEDID_DDC2",
-#endif
- NULL
-};
-
-static const char *i2cSymbols[] = {
- "xf86I2CBusInit",
- "xf86CreateI2CBusRec",
NULL
};
@@ -351,6 +296,9 @@ static const char *driSymbols[] = {
"DRIScreenInit",
"DRIUnlock",
"GlxSetVisualConfigs",
+#ifdef SISNEWDRI2
+ "DRICreatePCIBusID"
+#endif
NULL
};
#endif
@@ -380,20 +328,20 @@ sisSetup(pointer module, pointer opts, int *errmaj, int *errmin)
{
static Bool setupDone = FALSE;
- if (!setupDone) {
- setupDone = TRUE;
- xf86AddDriver(&SIS, module, 0);
- LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols, xaaSymbols,
- miscfbSymbols, shadowSymbols, ramdacSymbols,
- vbeSymbols, int10Symbols,
+ if(!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&SIS, module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
+ shadowSymbols, ramdacSymbols,
+ vbeSymbols, int10Symbols,
#ifdef XF86DRI
- drmSymbols, driSymbols,
+ drmSymbols, driSymbols,
#endif
- NULL);
- return (pointer)TRUE;
- }
+ NULL);
+ return (pointer)TRUE;
+ }
- if (errmaj) *errmaj = LDR_ONCEONLY;
+ if(errmaj) *errmaj = LDR_ONCEONLY;
return NULL;
}
@@ -407,8 +355,7 @@ SISGetRec(ScrnInfoPtr pScrn)
* pScrn->driverPrivate is initialised to NULL, so we can check if
* the allocation has already been done.
*/
- if (pScrn->driverPrivate != NULL)
- return TRUE;
+ if(pScrn->driverPrivate != NULL) return TRUE;
pScrn->driverPrivate = xnfcalloc(sizeof(SISRec), 1);
@@ -426,43 +373,93 @@ SISFreeRec(ScrnInfoPtr pScrn)
SISEntPtr pSiSEnt = NULL;
#endif
- /* TW: Just to make sure... */
+ /* Just to make sure... */
if(!pSiS) return;
+#ifdef SISDUALHEAD
pSiSEnt = pSiS->entityPrivate;
+#endif
if(pSiS->pstate) xfree(pSiS->pstate);
pSiS->pstate = NULL;
if(pSiS->fonts) xfree(pSiS->fonts);
pSiS->fonts = NULL;
+
#ifdef SISDUALHEAD
if(pSiSEnt) {
- if(!pSiS->SecondHead) {
- /* TW: Free memory only if we are first head; in case of an error
- * during init of the second head, the server will continue -
- * and we need the BIOS image and SiS_Private for the first
- * head.
+ if(!pSiS->SecondHead) {
+ /* Free memory only if we are first head; in case of an error
+ * during init of the second head, the server will continue -
+ * and we need the BIOS image and SiS_Private for the first
+ * head.
*/
if(pSiSEnt->BIOS) xfree(pSiSEnt->BIOS);
pSiSEnt->BIOS = pSiS->BIOS = NULL;
if(pSiSEnt->SiS_Pr) xfree(pSiSEnt->SiS_Pr);
pSiSEnt->SiS_Pr = pSiS->SiS_Pr = NULL;
- } else {
+ if(pSiSEnt->RenderAccelArray) xfree(pSiSEnt->RenderAccelArray);
+ pSiSEnt->RenderAccelArray = pSiS->RenderAccelArray = NULL;
+ } else {
pSiS->BIOS = NULL;
pSiS->SiS_Pr = NULL;
- }
+ pSiS->RenderAccelArray = NULL;
+ }
} else {
#endif
- if(pSiS->BIOS) xfree(pSiS->BIOS);
- pSiS->BIOS = NULL;
- if(pSiS->SiS_Pr) xfree(pSiS->SiS_Pr);
- pSiS->SiS_Pr = NULL;
-#ifdef SISDUALHEAD
+ if(pSiS->BIOS) xfree(pSiS->BIOS);
+ pSiS->BIOS = NULL;
+ if(pSiS->SiS_Pr) xfree(pSiS->SiS_Pr);
+ pSiS->SiS_Pr = NULL;
+ if(pSiS->RenderAccelArray) xfree(pSiS->RenderAccelArray);
+ pSiS->RenderAccelArray = NULL;
+#ifdef SISDUALHEAD
+ }
+#endif
+#ifdef SISMERGED
+ if(pSiS->CRT2HSync) xfree(pSiS->CRT2HSync);
+ pSiS->CRT2HSync = NULL;
+ if(pSiS->CRT2VRefresh) xfree(pSiS->CRT2VRefresh);
+ pSiS->CRT2VRefresh = NULL;
+ if(pSiS->MetaModes) xfree(pSiS->MetaModes);
+ pSiS->MetaModes = NULL;
+ if(pSiS->CRT2pScrn) {
+ if(pSiS->CRT2pScrn->modes) {
+ while(pSiS->CRT2pScrn->modes)
+ xf86DeleteMode(&pSiS->CRT2pScrn->modes, pSiS->CRT2pScrn->modes);
+ }
+ if(pSiS->CRT2pScrn->monitor) {
+ if(pSiS->CRT2pScrn->monitor->Modes) {
+ while(pSiS->CRT2pScrn->monitor->Modes)
+ xf86DeleteMode(&pSiS->CRT2pScrn->monitor->Modes, pSiS->CRT2pScrn->monitor->Modes);
+ }
+ if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC);
+ xfree(pSiS->CRT2pScrn->monitor);
+ }
+ xfree(pSiS->CRT2pScrn);
+ pSiS->CRT2pScrn = NULL;
+ }
+ if(pSiS->CRT1Modes) {
+ if(pSiS->CRT1Modes != pScrn->modes) {
+ if(pScrn->modes) {
+ pScrn->currentMode = pScrn->modes;
+ do {
+ DisplayModePtr p = pScrn->currentMode->next;
+ if(pScrn->currentMode->Private)
+ xfree(pScrn->currentMode->Private);
+ xfree(pScrn->currentMode);
+ pScrn->currentMode = p;
+ } while(pScrn->currentMode != pScrn->modes);
+ }
+ pScrn->currentMode = pSiS->CRT1CurrentMode;
+ pScrn->modes = pSiS->CRT1Modes;
+ pSiS->CRT1CurrentMode = NULL;
+ pSiS->CRT1Modes = NULL;
+ }
}
#endif
- if (pSiS->pVbe) vbeFree(pSiS->pVbe);
+ if(pSiS->pVbe) vbeFree(pSiS->pVbe);
pSiS->pVbe = NULL;
- if (pScrn->driverPrivate == NULL)
+ if(pScrn->driverPrivate == NULL)
return;
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
@@ -472,290 +469,197 @@ static void
SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
{
SISPtr pSiS = SISPTR(pScrn);
- unsigned char extDDC_PCR=0;
- unsigned char crtc17, seq1;
+ BOOLEAN docrt1 = TRUE, docrt2 = TRUE;
+ unsigned char sr1=0, cr17=0, cr63=0, sr11=0, pmreg=0, sr7=0;
+ unsigned char p1_13=0, p2_0=0, oldpmreg=0;
+ BOOLEAN backlight = TRUE;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"SISDisplayPowerManagementSet(%d)\n",PowerManagementMode);
- /* unlock registers */
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) docrt2 = FALSE;
+ else docrt1 = FALSE;
+ }
+#endif
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
- /* Read CR17 */
- inSISIDXREG(SISCR, 0x17, crtc17);
-
- /* Read SR1 */
- inSISIDXREG(SISSR, 0x01, seq1);
-
- if(pSiS->VBFlags & CRT2_LCD) {
- if(((pSiS->VGAEngine == SIS_300_VGA) &&
- (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
- ((pSiS->VGAEngine == SIS_315_VGA) &&
- ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
- /* Read Power Control Register (SR11) */
- inSISIDXREG(SISSR, 0x11, extDDC_PCR);
- /* if not blanked, obtain state of LCD blank flags set by BIOS */
- if(!pSiS->Blank) {
- pSiS->LCDon = extDDC_PCR;
- }
- /* erase LCD blank flags */
- extDDC_PCR &= ~0x0C;
- }
+ if(docrt2) {
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(((pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->VBFlags & (VB_301|VB_30xBDH|VB_LVDS))) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) &&
+ ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->BlankCRT2) inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ } else
+#endif
+ if(!pSiS->Blank) inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ }
}
switch (PowerManagementMode) {
case DPMSModeOn: /* HSync: On, VSync: On */
-
- pSiS->Blank = FALSE;
- seq1 &= ~0x20;
- crtc17 |= 0x80;
- if(pSiS->VBFlags & CRT2_LCD) {
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_CHRONTEL) {
- SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
- } else if(pSiS->VBFlags & VB_LVDS) {
- extDDC_PCR |= (pSiS->LCDon & 0x0C);
- } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
- }
- } else if(pSiS->VGAEngine == SIS_300_VGA) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
- } else {
- extDDC_PCR |= (pSiS->LCDon & 0x0C);
- }
- }
- }
+ if(docrt1) pSiS->Blank = FALSE;
+#ifdef SISDUALHEAD
+ else pSiS->BlankCRT2 = FALSE;
+#endif
+ sr1 = 0x00;
+ cr17 = 0x80;
+ pmreg = 0x00;
+ cr63 = 0x00;
+ sr7 = 0x10;
+ sr11 = (pSiS->LCDon & 0x0C);
+ p2_0 = 0x20;
+ p1_13 = 0x00;
+ backlight = TRUE;
break;
- case DPMSModeStandby: /* HSync: Off, VSync: On */
case DPMSModeSuspend: /* HSync: On, VSync: Off */
+ if(docrt1) pSiS->Blank = TRUE;
+#ifdef SISDUALHEAD
+ else pSiS->BlankCRT2 = TRUE;
+#endif
+ sr1 = 0x20;
+ cr17 = 0x80;
+ pmreg = 0x80;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ sr11 = 0x08;
+ p2_0 = 0x40;
+ p1_13 = 0x80;
+ backlight = FALSE;
+ break;
- pSiS->Blank = TRUE;
- seq1 |= 0x20 ;
- if(pSiS->VBFlags & CRT2_LCD) {
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_CHRONTEL) {
- SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
- } else if(pSiS->VBFlags & VB_LVDS) {
- extDDC_PCR |= 0x08;
- } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- }
- } else if(pSiS->VGAEngine == SIS_300_VGA) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- } else {
- extDDC_PCR |= 0x08;
- }
- }
- }
+ case DPMSModeStandby: /* HSync: Off, VSync: On */
+ if(docrt1) pSiS->Blank = TRUE;
+#ifdef SISDUALHEAD
+ else pSiS->BlankCRT2 = TRUE;
+#endif
+ sr1 = 0x20;
+ cr17 = 0x80;
+ pmreg = 0x40;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ sr11 = 0x08;
+ p2_0 = 0x80;
+ p1_13 = 0x40;
+ backlight = FALSE;
break;
case DPMSModeOff: /* HSync: Off, VSync: Off */
-
- pSiS->Blank = TRUE;
- seq1 |= 0x20;
- if(pSiS->VGAEngine == SIS_300_VGA ||
- pSiS->VGAEngine == SIS_315_VGA) {
- /* TW: We can't switch off CRT1 if bridge is in slavemode */
- if(pSiS->VBFlags & CRT2_ENABLE) {
- if(!(SiSBridgeIsInSlaveMode(pScrn))) crtc17 &= ~0x80;
- } else crtc17 &= ~0x80;
- } else {
- crtc17 &= ~0x80;
- }
- if(pSiS->VBFlags & CRT2_LCD) {
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_CHRONTEL) {
- SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
- } else if(pSiS->VBFlags & VB_LVDS) {
- extDDC_PCR |= 0x0C;
- } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- }
- } else if(pSiS->VGAEngine == SIS_300_VGA) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- } else {
- extDDC_PCR |= 0x0C;
- }
- }
- }
+ if(docrt1) pSiS->Blank = TRUE;
+#ifdef SISDUALHEAD
+ else pSiS->BlankCRT2 = TRUE;
+#endif
+ sr1 = 0x20;
+ cr17 = 0x00;
+ pmreg = 0xc0;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ sr11 = 0x08;
+ p2_0 = 0xc0;
+ p1_13 = 0xc0;
+ backlight = FALSE;
break;
+ default:
+ return;
}
- outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */
-
- outSISIDXREG(SISCR, 0x17, crtc17);
-
- if(pSiS->VBFlags & CRT2_LCD) {
- if(((pSiS->VGAEngine == SIS_300_VGA) &&
- (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
- ((pSiS->VGAEngine == SIS_315_VGA) &&
- ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
- outSISIDXREG(SISSR, 0x11, extDDC_PCR);
- }
+ if(docrt2) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ if(backlight) {
+ SiS_Chrontel701xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ }
+ }
+ }
+ }
}
- outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
- usleep(10000);
- outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
-
-}
-
-#ifdef SISDUALHEAD
-/* TW: DPMS for dual head mode */
-static void
-SISDisplayPowerManagementSetDH(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
-{
- SISPtr pSiS = SISPTR(pScrn);
- unsigned char crtc17 = 0;
- unsigned char extDDC_PCR=0;
- unsigned char seq1 = 0;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "SISDisplayPowerManagementSetDH(%d)\n",PowerManagementMode);
-
- /* unlock registers */
-#ifdef UNLOCK_ALWAYS
- sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
-#endif
-
- if (pSiS->SecondHead) {
-
- /* TW: Second (slave) head is always CRT1 */
-
- /* Read CR17 and SR01 */
- inSISIDXREG(SISCR, 0x17, crtc17);
- inSISIDXREG(SISSR, 0x01, seq1);
-
- switch (PowerManagementMode)
- {
- case DPMSModeOn: /* HSync: On, VSync: On */
- seq1 &= ~0x20 ;
- crtc17 |= 0x80;
- pSiS->BlankCRT1 = FALSE;
- break;
-
- case DPMSModeStandby: /* HSync: Off, VSync: On */
- case DPMSModeSuspend: /* HSync: On, VSync: Off */
- seq1 |= 0x20;
- pSiS->BlankCRT1 = TRUE;
- break;
-
- case DPMSModeOff: /* HSync: Off, VSync: Off */
- seq1 |= 0x20 ;
- pSiS->BlankCRT1 = TRUE;
- crtc17 &= ~0x80;
- break;
- }
- outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
-
- outSISIDXREG(SISSR, 0x01, seq1); /* Set/Clear "Display On" bit */
-
- usleep(10000);
-
- outSISIDXREG(SISCR, 0x17, crtc17);
-
- outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
-
- } else {
-
- /* TW: Master head is always CRT2 */
-
- /* TV can not be managed */
- if(!(pSiS->VBFlags & CRT2_LCD)) return;
-
- if(((pSiS->VGAEngine == SIS_300_VGA) &&
- (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
- ((pSiS->VGAEngine == SIS_315_VGA) &&
- ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
- /* Read Power Control Register (SR11) */
- inSISIDXREG(SISSR, 0x11, extDDC_PCR);
- /* if not blanked obtain state of LCD blank flags set by BIOS */
- if(!pSiS->BlankCRT2) {
- pSiS->LCDon = extDDC_PCR;
- }
- /* erase LCD blank flags */
- extDDC_PCR &= ~0xC;
- }
-
- switch (PowerManagementMode) {
-
- case DPMSModeOn:
- pSiS->BlankCRT2 = FALSE;
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_CHRONTEL) {
- SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
- } else if(pSiS->VBFlags & VB_LVDS) {
- extDDC_PCR |= (pSiS->LCDon & 0x0C);
- } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext);
- }
- } else if(pSiS->VGAEngine == SIS_300_VGA) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOn(pSiS->SiS_Pr, &pSiS->sishw_ext);
- } else {
- extDDC_PCR |= (pSiS->LCDon & 0x0C);
- }
- }
- break;
+ if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ if((docrt2 && (pSiS->VBFlags & CRT2_LCD)) || (docrt1 && (pSiS->VBFlags & CRT1_LCDA))) {
+ if(backlight) {
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ }
+ }
- case DPMSModeStandby:
- case DPMSModeSuspend:
- pSiS->BlankCRT2 = TRUE;
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_CHRONTEL) {
- SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
- } else if(pSiS->VBFlags & VB_LVDS) {
- extDDC_PCR |= 0x08;
- } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
- }
- } else if(pSiS->VGAEngine == SIS_300_VGA) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
- } else {
- extDDC_PCR |= 0x08;
- }
+ if(docrt1) {
+ setSISIDXREG(SISSR, 0x01, ~0x20, sr1); /* Set/Clear "Display On" bit */
+ switch(pSiS->VGAEngine) {
+ case SIS_OLD_VGA:
+ case SIS_530_VGA:
+ inSISIDXREG(SISSR, 0x11, oldpmreg);
+ setSISIDXREG(SISCR, 0x17, 0x7f, cr17);
+ setSISIDXREG(SISSR, 0x11, 0x3f, pmreg);
+ break;
+ case SIS_315_VGA:
+ if((!pSiS->CRT1off) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C))) {
+ setSISIDXREG(SISCR, 0x63, 0xbf, cr63);
+ setSISIDXREG(SISSR, 0x07, 0xef, sr7);
}
- break;
-
- case DPMSModeOff:
- pSiS->BlankCRT2 = TRUE;
- if(pSiS->VGAEngine == SIS_315_VGA) {
- if(pSiS->VBFlags & VB_CHRONTEL) {
- SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
- } else if(pSiS->VBFlags & VB_LVDS) {
- extDDC_PCR |= 0x0C;
- } else if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
- }
- } else if(pSiS->VGAEngine == SIS_300_VGA) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- SiS_SiS30xBLOff(pSiS->SiS_Pr, &pSiS->sishw_ext);
- } else {
- extDDC_PCR |= 0x0C;
- }
- }
- break;
- }
+ /* fall through */
+ default:
+ if((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C)) {
+ inSISIDXREG(SISSR, 0x1f, oldpmreg);
+ if(!pSiS->CRT1off) {
+ setSISIDXREG(SISSR, 0x1f, 0x3f, pmreg);
+ }
+ }
+ /* TODO: Check if Chrontel TV is active and in slave mode,
+ * don't go into power-saving mode this in this case!
+ */
+ }
+ oldpmreg &= 0xc0;
+ }
- if(((pSiS->VGAEngine == SIS_300_VGA) &&
- (!(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)))) ||
- ((pSiS->VGAEngine == SIS_315_VGA) &&
- ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
- outSISIDXREG(SISSR, 0x11, extDDC_PCR);
- }
+ if(docrt2) {
+ if(pSiS->VBFlags & CRT2_LCD) {
+ if(((pSiS->VGAEngine == SIS_300_VGA) &&
+ (pSiS->VBFlags & (VB_301|VB_30xBDH|VB_LVDS))) ||
+ ((pSiS->VGAEngine == SIS_315_VGA) &&
+ ((pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+ setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
+ }
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ if((pSiS->VBFlags & (VB_301B|VB_301C|VB_302B)) &&
+ (!(pSiS->VBFlags & VB_30xBDH))) {
+ setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
+ }
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ if((pSiS->VBFlags & (VB_301B|VB_301C|VB_302B)) &&
+ (!(pSiS->VBFlags & VB_30xBDH))) {
+ setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+ }
+ }
+ } else if(pSiS->VBFlags & CRT2_VGA) {
+ if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B)) {
+ setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+ }
+ }
+ }
+ if((docrt1) && (pmreg != oldpmreg) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C))) {
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
}
+
}
-#endif
/* Mandatory */
static void
@@ -764,20 +668,80 @@ SISIdentify(int flags)
xf86PrintChipsets(SIS_NAME, "driver for SiS chipsets", SISChipsets);
}
+#if 0
+/* This won't work as long as noone added the symbols to the symlist */
static void
-SIS1bppColorMap(ScrnInfoPtr pScrn)
+SISCalculateGammaRamp(ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
+ int i, j, nramp;
+ unsigned short *ramp[3];
+ float gamma_max[3], gamma_prescale[3], framp;
+
+ gamma_max[0] = (float)pSiS->GammaBriR / 1000;
+ gamma_max[1] = (float)pSiS->GammaBriG / 1000;
+ gamma_max[2] = (float)pSiS->GammaBriB / 1000;
+ gamma_prescale[0] = (float)pSiS->GammaPBriR / 1000;
+ gamma_prescale[1] = (float)pSiS->GammaPBriG / 1000;
+ gamma_prescale[2] = (float)pSiS->GammaPBriB / 1000;
+
+ if(!(nramp = xf86GetGammaRampSize(pScrn->pScreen))) return;
+
+ for(i=0; i<3; i++) {
+ ramp[i] = (unsigned short *)xalloc(nramp * sizeof(unsigned short));
+ if(!ramp[i]) {
+ if(ramp[0]) { xfree(ramp[0]); ramp[0] = NULL; }
+ if(ramp[1]) { xfree(ramp[1]); ramp[1] = NULL; }
+ return;
+ }
+ }
- outSISREG(SISCOLIDX, 0x00);
- outSISREG(SISCOLDATA, 0x00);
- outSISREG(SISCOLDATA, 0x00);
- outSISREG(SISCOLDATA, 0x00);
+ for(i = 0; i < 3; i++) {
+ int fullscale = 65535 * gamma_max[i];
+ float dramp = 1. / (nramp - 1);
+ float invgamma=0.0, v;
- outSISREG(SISCOLIDX, 0x3f);
- outSISREG(SISCOLDATA, 0x3f);
- outSISREG(SISCOLDATA, 0x3f);
- outSISREG(SISCOLDATA, 0x3f);
+ switch(i) {
+ case 0: invgamma = 1. / pScrn->gamma.red; break;
+ case 1: invgamma = 1. / pScrn->gamma.green; break;
+ case 2: invgamma = 1. / pScrn->gamma.blue; break;
+ }
+
+ for(j = 0; j < nramp; j++) {
+ framp = pow(gamma_prescale[i] * j * dramp, invgamma);
+
+ v = (fullscale < 0) ? (65535 + fullscale * framp) :
+ fullscale * framp;
+ if(v < 0) v = 0;
+ else if(v > 65535) v = 65535;
+ ramp[i][j] = (unsigned short)v;
+ }
+ }
+
+ xf86ChangeGammaRamp(pScrn->pScreen, nramp, ramp[0], ramp[1], ramp[2]);
+
+ xfree(ramp[0]);
+ xfree(ramp[1]);
+ xfree(ramp[2]);
+ ramp[0] = ramp[1] = ramp[2] = NULL;
+}
+#endif
+
+static void
+SISErrorLog(ScrnInfoPtr pScrn, const char *format, ...)
+{
+ va_list ap;
+ static const char *str = "**************************************************\n";
+
+ va_start(ap, format);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " ERROR:\n");
+ xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap);
+ va_end(ap);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " END OF MESSAGE\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
}
/* Mandatory */
@@ -811,13 +775,12 @@ SISProbe(DriverPtr drv, int flags)
* specified.
*/
- if ((numDevSections = xf86MatchDevice(SIS_DRIVER_NAME,
- &devSections)) <= 0) {
- /*
- * There's no matching device section in the config file, so quit
- * now.
- */
- return FALSE;
+ if((numDevSections = xf86MatchDevice(SIS_DRIVER_NAME, &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
}
/*
@@ -830,26 +793,25 @@ SISProbe(DriverPtr drv, int flags)
* All of the cards this driver supports are PCI, so the "probing" just
* amounts to checking the PCI data that the server has already collected.
*/
- if (xf86GetPciVideoInfo() == NULL) {
- /*
- * We won't let anything in the config file override finding no
- * PCI video cards at all. This seems reasonable now, but we'll see.
- */
- return FALSE;
+ if(xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
}
numUsed = xf86MatchPciInstances(SIS_NAME, PCI_VENDOR_SIS,
- SISChipsets, SISPciChipsets, devSections,
- numDevSections, drv, &usedChips);
+ SISChipsets, SISPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
/* Free it since we don't need that list after this */
xfree(devSections);
- if (numUsed <= 0)
- return FALSE;
+ if(numUsed <= 0) return FALSE;
- if (flags & PROBE_DETECT)
+ if(flags & PROBE_DETECT) {
foundScreen = TRUE;
- else for (i = 0; i < numUsed; i++) {
+ } else for(i = 0; i < numUsed; i++) {
ScrnInfoPtr pScrn;
#ifdef SISDUALHEAD
EntityInfoPtr pEnt;
@@ -858,7 +820,7 @@ SISProbe(DriverPtr drv, int flags)
/* Allocate a ScrnInfoRec and claim the slot */
pScrn = NULL;
- if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ if((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
SISPciChipsets, NULL, NULL,
NULL, NULL, NULL))) {
/* Fill in what we can of the ScrnInfoRec */
@@ -879,37 +841,37 @@ SISProbe(DriverPtr drv, int flags)
#ifdef SISDUALHEAD
pEnt = xf86GetEntityInfo(usedChips[i]);
- /* TW: I assume these chipsets as - basically - dual head capable. */
- if (pEnt->chipset == PCI_CHIP_SIS630 || pEnt->chipset == PCI_CHIP_SIS540 ||
- pEnt->chipset == PCI_CHIP_SIS650 || pEnt->chipset == PCI_CHIP_SIS550 ||
- pEnt->chipset == PCI_CHIP_SIS315 || pEnt->chipset == PCI_CHIP_SIS315H ||
- pEnt->chipset == PCI_CHIP_SIS315PRO || pEnt->chipset == PCI_CHIP_SIS330 ||
- pEnt->chipset == PCI_CHIP_SIS300) {
+ if(pEnt->chipset == PCI_CHIP_SIS630 || pEnt->chipset == PCI_CHIP_SIS540 ||
+ pEnt->chipset == PCI_CHIP_SIS650 || pEnt->chipset == PCI_CHIP_SIS550 ||
+ pEnt->chipset == PCI_CHIP_SIS315 || pEnt->chipset == PCI_CHIP_SIS315H ||
+ pEnt->chipset == PCI_CHIP_SIS315PRO || pEnt->chipset == PCI_CHIP_SIS330 ||
+ pEnt->chipset == PCI_CHIP_SIS300 || pEnt->chipset == PCI_CHIP_SIS660) {
SISEntPtr pSiSEnt = NULL;
DevUnion *pPriv;
xf86SetEntitySharable(usedChips[i]);
- if (SISEntityIndex < 0)
- SISEntityIndex = xf86AllocateEntityPrivateIndex();
+ if(SISEntityIndex < 0) {
+ SISEntityIndex = xf86AllocateEntityPrivateIndex();
+ }
pPriv = xf86GetEntityPrivate(pScrn->entityList[0], SISEntityIndex);
- if (!pPriv->ptr) {
- pPriv->ptr = xnfcalloc(sizeof(SISEntRec), 1);
- pSiSEnt = pPriv->ptr;
- pSiSEnt->lastInstance = -1;
- pSiSEnt->DisableDual = FALSE;
- pSiSEnt->ErrorAfterFirst = FALSE;
- pSiSEnt->MapCountIOBase = pSiSEnt->MapCountFbBase = 0;
- pSiSEnt->FbBase = pSiSEnt->IOBase = NULL;
- pSiSEnt->forceUnmapIOBase = FALSE;
- pSiSEnt->forceUnmapFbBase = FALSE;
+ if(!pPriv->ptr) {
+ pPriv->ptr = xnfcalloc(sizeof(SISEntRec), 1);
+ pSiSEnt = pPriv->ptr;
+ pSiSEnt->lastInstance = -1;
+ pSiSEnt->DisableDual = FALSE;
+ pSiSEnt->ErrorAfterFirst = FALSE;
+ pSiSEnt->MapCountIOBase = pSiSEnt->MapCountFbBase = 0;
+ pSiSEnt->FbBase = pSiSEnt->IOBase = NULL;
+ pSiSEnt->forceUnmapIOBase = FALSE;
+ pSiSEnt->forceUnmapFbBase = FALSE;
#ifdef __alpha__
- pSiSEnt->MapCountIOBaseDense = 0;
- pSiSEnt->IOBaseDense = NULL;
- pSiSEnt->forceUnmapIOBaseDense = FALSE;
+ pSiSEnt->MapCountIOBaseDense = 0;
+ pSiSEnt->IOBaseDense = NULL;
+ pSiSEnt->forceUnmapIOBaseDense = FALSE;
#endif
} else {
- pSiSEnt = pPriv->ptr;
+ pSiSEnt = pPriv->ptr;
}
pSiSEnt->lastInstance++;
xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0],
@@ -922,9 +884,11 @@ SISProbe(DriverPtr drv, int flags)
}
-/* TW: If monitor section has no HSync/VRefresh data,
- * derive it from DDC data.
+/* If monitor section has no HSync/VRefresh data,
+ * derive it from DDC data. Done by common layer
+ * since 4.3.99.14.
*/
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0)
static void
SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
{
@@ -961,19 +925,19 @@ SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
};
/* "Future modes"; we only check the really high ones */
const myddcstdmodes mystdmodes[8] = {
- { 1280, 1024, 85, 91.1 },
- { 1600, 1200, 60, 75.0 },
- { 1600, 1200, 65, 81.3 },
- { 1600, 1200, 70, 87.5 },
- { 1600, 1200, 75, 93.8 },
+ { 1280, 1024, 85, 91.1 },
+ { 1600, 1200, 60, 75.0 },
+ { 1600, 1200, 65, 81.3 },
+ { 1600, 1200, 70, 87.5 },
+ { 1600, 1200, 75, 93.8 },
{ 1600, 1200, 85, 106.3 },
- { 1920, 1440, 60, 90.0 },
+ { 1920, 1440, 60, 90.0 },
{ 1920, 1440, 75, 112.5 }
};
if(flag) { /* HSync */
- for (i = 0; i < 4; i++) {
- if (ddc->det_mon[i].type == DS_RANGES) {
+ for(i = 0; i < 4; i++) {
+ if(ddc->det_mon[i].type == DS_RANGES) {
mon->nHsync = 1;
mon->hsync[0].lo = ddc->det_mon[i].section.ranges.min_h;
mon->hsync[0].hi = ddc->det_mon[i].section.ranges.max_h;
@@ -987,13 +951,13 @@ SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
if(myhtiming[i].whichone == 1) temp = ddc->timings1.t1;
else temp = ddc->timings1.t2;
if(temp & myhtiming[i].mask) {
- if((i==0) || (myhlow > myhtiming[i].rate))
+ if((i==0) || (myhlow > myhtiming[i].rate))
myhlow = myhtiming[i].rate;
}
if(myhtiming[10-i].whichone == 1) temp = ddc->timings1.t1;
else temp = ddc->timings1.t2;
if(temp & myhtiming[10-i].mask) {
- if((i==0) || (myhhigh < myhtiming[10-i].rate))
+ if((i==0) || (myhhigh < myhtiming[10-i].rate))
myhhigh = myhtiming[10-i].rate;
}
}
@@ -1018,8 +982,8 @@ SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
} else { /* Vrefresh */
- for (i = 0; i < 4; i++) {
- if (ddc->det_mon[i].type == DS_RANGES) {
+ for(i = 0; i < 4; i++) {
+ if(ddc->det_mon[i].type == DS_RANGES) {
mon->nVrefresh = 1;
mon->vrefresh[0].lo = ddc->det_mon[i].section.ranges.min_v;
mon->vrefresh[0].hi = ddc->det_mon[i].section.ranges.max_v;
@@ -1032,13 +996,13 @@ SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
if(myvtiming[i].whichone == 1) temp = ddc->timings1.t1;
else temp = ddc->timings1.t2;
if(temp & myvtiming[i].mask) {
- if((i==0) || (myvlow > myvtiming[i].rate))
+ if((i==0) || (myvlow > myvtiming[i].rate))
myvlow = myvtiming[i].rate;
}
if(myvtiming[9-i].whichone == 1) temp = ddc->timings1.t1;
else temp = ddc->timings1.t2;
if(temp & myvtiming[9-i].mask) {
- if((i==0) || (myvhigh < myvtiming[9-i].rate))
+ if((i==0) || (myvhigh < myvtiming[9-i].rate))
myvhigh = myvtiming[9-i].rate;
}
}
@@ -1062,68 +1026,1225 @@ SiSSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
}
}
+#endif
+
+/* Some helper functions for MergedFB mode */
+
+#ifdef SISMERGED
+
+/* Helper function for CRT2 monitor vrefresh/hsync options
+ * (Code base from mga driver)
+ */
+static int
+SiSStrToRanges(range *r, char *s, int max)
+{
+ float num = 0.0;
+ int rangenum = 0;
+ Bool gotdash = FALSE;
+ Bool nextdash = FALSE;
+ char* strnum = NULL;
+ do {
+ switch(*s) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ if(strnum == NULL) {
+ strnum = s;
+ gotdash = nextdash;
+ nextdash = FALSE;
+ }
+ break;
+ case '-':
+ case ' ':
+ case 0:
+ if(strnum == NULL) break;
+ sscanf(strnum, "%f", &num);
+ strnum = NULL;
+ if(gotdash) {
+ r[rangenum - 1].hi = num;
+ } else {
+ r[rangenum].lo = num;
+ r[rangenum].hi = num;
+ rangenum++;
+ }
+ if(*s == '-') nextdash = (rangenum != 0);
+ else if(rangenum >= max) return rangenum;
+ break;
+ default:
+ return 0;
+ }
+
+ } while(*(s++) != 0);
+
+ return rangenum;
+}
+
+/* Copy and link two modes form mergedfb mode
+ * (Code base taken from mga driver)
+ * Copys mode i, links the result to dest, and returns it.
+ * Links i and j in Private record.
+ * If dest is NULL, return value is copy of i linked to itself.
+ * For mergedfb auto-config, we only check the dimension
+ * against virtualX/Y, if they were user-provided.
+ */
+static DisplayModePtr
+SiSCopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
+ DisplayModePtr i, DisplayModePtr j,
+ SiSScrn2Rel srel)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ DisplayModePtr mode;
+ int dx = 0,dy = 0;
+
+ if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest;
+ memcpy(mode, i, sizeof(DisplayModeRec));
+ if(!((mode->Private = xalloc(sizeof(SiSMergedDisplayModeRec))))) {
+ xfree(mode);
+ return dest;
+ }
+ ((SiSMergedDisplayModePtr)mode->Private)->CRT1 = i;
+ ((SiSMergedDisplayModePtr)mode->Private)->CRT2 = j;
+ ((SiSMergedDisplayModePtr)mode->Private)->CRT2Position = srel;
+ mode->PrivSize = 0;
+
+ switch(srel) {
+ case sisLeftOf:
+ case sisRightOf:
+ if(!(pScrn->display->virtualX)) {
+ dx = i->HDisplay + j->HDisplay;
+ } else {
+ dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
+ }
+ dx -= mode->HDisplay;
+ if(!(pScrn->display->virtualY)) {
+ dy = max(i->VDisplay, j->VDisplay);
+ } else {
+ dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+ }
+ dy -= mode->VDisplay;
+ break;
+ case sisAbove:
+ case sisBelow:
+ if(!(pScrn->display->virtualY)) {
+ dy = i->VDisplay + j->VDisplay;
+ } else {
+ dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
+ }
+ dy -= mode->VDisplay;
+ if(!(pScrn->display->virtualX)) {
+ dx = max(i->HDisplay, j->HDisplay);
+ } else {
+ dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+ }
+ dx -= mode->HDisplay;
+ break;
+ case sisClone:
+ if(!(pScrn->display->virtualX)) {
+ dx = max(i->HDisplay, j->HDisplay);
+ } else {
+ dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+ }
+ dx -= mode->HDisplay;
+ if(!(pScrn->display->virtualY)) {
+ dy = max(i->VDisplay, j->VDisplay);
+ } else {
+ dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+ }
+ dy -= mode->VDisplay;
+ break;
+ }
+ mode->HDisplay += dx;
+ mode->HSyncStart += dx;
+ mode->HSyncEnd += dx;
+ mode->HTotal += dx;
+ mode->VDisplay += dy;
+ mode->VSyncStart += dy;
+ mode->VSyncEnd += dy;
+ mode->VTotal += dy;
+ mode->Clock = 0;
+
+ if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > pSiS->maxxfbmem) ||
+ (mode->HDisplay > 4088) ||
+ (mode->VDisplay > 4096) ) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Skipped %dx%d, not enough video RAM or beyond hardware specs\n",
+ mode->HDisplay, mode->VDisplay);
+ xfree(mode->Private);
+ xfree(mode);
+
+ return dest;
+ }
+
+#ifdef SISXINERAMA
+ if(srel != sisClone) {
+ pSiS->AtLeastOneNonClone = TRUE;
+ }
+#endif
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Merged %dx%d and %dx%d to %dx%d%s\n",
+ i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay,
+ mode->HDisplay, mode->VDisplay, (srel == sisClone) ? " (Clone)" : "");
+
+ mode->next = mode;
+ mode->prev = mode;
+
+ if(dest) {
+ mode->next = dest->next; /* Insert node after "dest" */
+ dest->next->prev = mode;
+ mode->prev = dest;
+ dest->next = mode;
+ }
+
+ return mode;
+}
+
+/* Helper function to find a mode from a given name
+ * (Code base taken from mga driver)
+ */
+static DisplayModePtr
+SiSGetModeFromName(char* str, DisplayModePtr i)
+{
+ DisplayModePtr c = i;
+ if(!i) return NULL;
+ do {
+ if(strcmp(str, c->name) == 0) return c;
+ c = c->next;
+ } while(c != i);
+ return NULL;
+}
+
+static DisplayModePtr
+SiSFindWidestTallestMode(DisplayModePtr i, Bool tallest)
+{
+ DisplayModePtr c = i, d = NULL;
+ int max = 0;
+ if(!i) return NULL;
+ do {
+ if(tallest) {
+ if(c->VDisplay > max) {
+ max = c->VDisplay;
+ d = c;
+ }
+ } else {
+ if(c->HDisplay > max) {
+ max = c->HDisplay;
+ d = c;
+ }
+ }
+ c = c->next;
+ } while(c != i);
+ return d;
+}
+
+static DisplayModePtr
+SiSGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
+ DisplayModePtr i, DisplayModePtr j,
+ SiSScrn2Rel srel)
+{
+#ifdef SISXINERAMA
+ SISPtr pSiS = SISPTR(pScrn);
+#endif
+ DisplayModePtr mode1 = NULL;
+ DisplayModePtr mode2 = NULL;
+ DisplayModePtr result = NULL;
+
+#ifdef SISXINERAMA
+ pSiS->AtLeastOneNonClone = FALSE;
+#endif
+
+ switch(srel) {
+ case sisLeftOf:
+ case sisRightOf:
+ mode1 = SiSFindWidestTallestMode(i, FALSE);
+ mode2 = SiSFindWidestTallestMode(j, FALSE);
+ break;
+ case sisAbove:
+ case sisBelow:
+ mode1 = SiSFindWidestTallestMode(i, TRUE);
+ mode2 = SiSFindWidestTallestMode(j, TRUE);
+ break;
+ case sisClone:
+ mode1 = i;
+ mode2 = j;
+ }
+
+ if(mode1 && mode2) {
+ return(SiSCopyModeNLink(pScrn, result, mode1, mode2, srel));
+ } else {
+ return NULL;
+ }
+}
+
+/* Generate the merged-fb mode modelist from metamodes
+ * (Code base taken from mga driver)
+ */
+static DisplayModePtr
+SiSGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str,
+ DisplayModePtr i, DisplayModePtr j,
+ SiSScrn2Rel srel)
+{
+#ifdef SISXINERAMA
+ SISPtr pSiS = SISPTR(pScrn);
+#endif
+ char* strmode = str;
+ char modename[256];
+ Bool gotdash = FALSE;
+ SiSScrn2Rel sr;
+ DisplayModePtr mode1 = NULL;
+ DisplayModePtr mode2 = NULL;
+ DisplayModePtr result = NULL;
+
+#ifdef SISXINERAMA
+ pSiS->AtLeastOneNonClone = FALSE;
+#endif
+
+ do {
+ switch(*str) {
+ case 0:
+ case '-':
+ case ' ':
+ if((strmode != str)) {
+
+ strncpy(modename, strmode, str - strmode);
+ modename[str - strmode] = 0;
+
+ if(gotdash) {
+ if(mode1 == NULL) return NULL;
+ mode2 = SiSGetModeFromName(modename, j);
+ if(!mode2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode \"%s\" is not a supported mode for CRT2\n", modename);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Skipping metamode \"%s-%s\".\n", mode1->name, modename);
+ mode1 = NULL;
+ }
+ } else {
+ mode1 = SiSGetModeFromName(modename, i);
+ if(!mode1) {
+ char* tmps = str;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode \"%s\" is not a supported mode for CRT1\n", modename);
+ gotdash = FALSE;
+ while(*tmps == ' ') tmps++;
+ if(*tmps == '-') { /* skip the next mode */
+ tmps++;
+ while((*tmps == ' ') && (*tmps != 0)) tmps++; /* skip spaces */
+ while((*tmps != ' ') && (*tmps != '-') && (*tmps != 0)) tmps++; /* skip modename */
+ strncpy(modename,strmode,tmps - strmode);
+ modename[tmps - strmode] = 0;
+ str = tmps-1;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Skipping metamode \"%s\".\n", modename);
+ mode1 = NULL;
+ }
+ }
+ gotdash = FALSE;
+ }
+ strmode = str + 1;
+ gotdash |= (*str == '-');
+
+ if(*str != 0) break;
+ /* Fall through otherwise */
+
+ default:
+ if(!gotdash && mode1) {
+ sr = srel;
+ if(!mode2) {
+ mode2 = SiSGetModeFromName(mode1->name, j);
+ sr = sisClone;
+ }
+ if(!mode2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode: \"%s\" is not a supported mode for CRT2\n", mode1->name);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Skipping metamode \"%s\".\n", modename);
+ mode1 = NULL;
+ } else {
+ result = SiSCopyModeNLink(pScrn, result, mode1, mode2, sr);
+ mode1 = NULL;
+ mode2 = NULL;
+ }
+ }
+ break;
+
+ }
+
+ } while(*(str++) != 0);
+
+ return result;
+}
+
+static DisplayModePtr
+SiSGenerateModeList(ScrnInfoPtr pScrn, char* str,
+ DisplayModePtr i, DisplayModePtr j,
+ SiSScrn2Rel srel)
+{
+ if(str != NULL) {
+ return(SiSGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "No MetaModes given, linking %s modes by default\n",
+ (srel == sisClone) ? "first" :
+ (((srel == sisLeftOf) || (srel == sisRightOf)) ? "widest" : "tallest"));
+ return(SiSGenerateModeListFromLargestModes(pScrn, i, j, srel));
+ }
+}
+
+static void
+SiSRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
+{
+ DisplayModePtr mode, bmode;
+ int max;
+ static const char *str = "MergedFB: Virtual %s %d\n";
+
+ if(!(pScrn->display->virtualX)) {
+ mode = bmode = pScrn->modes;
+ max = 0;
+ do {
+ if(mode->HDisplay > max) max = mode->HDisplay;
+ mode = mode->next;
+ } while(mode != bmode);
+ pScrn->virtualX = max;
+ pScrn->displayWidth = max;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max);
+ }
+ if(!(pScrn->display->virtualY)) {
+ mode = bmode = pScrn->modes;
+ max = 0;
+ do {
+ if(mode->VDisplay > max) max = mode->VDisplay;
+ mode = mode->next;
+ } while(mode != bmode);
+ pScrn->virtualY = max;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max);
+ }
+}
+
+static void
+SiSMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, SiSScrn2Rel srel)
+{
+ SISPtr pSiS = SISPTR(pScrn1);
+ MessageType from = X_DEFAULT;
+ xf86MonPtr DDC1 = (xf86MonPtr)(pScrn1->monitor->DDC);
+ xf86MonPtr DDC2 = (xf86MonPtr)(pScrn2->monitor->DDC);
+ int ddcWidthmm = 0, ddcHeightmm = 0;
+ const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n";
+
+ /* This sets the DPI for MergedFB mode. The problem is that
+ * this can never be exact, because the output devices may
+ * have different dimensions. This function tries to compromise
+ * through a few assumptions, and it just calculates an average DPI
+ * value for both monitors.
+ */
+
+ /* Given DisplaySize should regard BOTH monitors */
+ pScrn1->widthmm = pScrn1->monitor->widthmm;
+ pScrn1->heightmm = pScrn1->monitor->heightmm;
+
+ /* Get DDC display size; if only either CRT1 or CRT2 provided these,
+ * assume equal dimensions for both, otherwise add dimensions
+ */
+ if( (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
+ (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) ) {
+ ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
+ ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
+ switch(srel) {
+ case sisLeftOf:
+ case sisRightOf:
+ ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
+ break;
+ case sisAbove:
+ case sisBelow:
+ ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
+ default:
+ break;
+ }
+ } else if(DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
+ ddcWidthmm = DDC1->features.hsize * 10;
+ ddcHeightmm = DDC1->features.vsize * 10;
+ switch(srel) {
+ case sisLeftOf:
+ case sisRightOf:
+ ddcWidthmm *= 2;
+ break;
+ case sisAbove:
+ case sisBelow:
+ ddcHeightmm *= 2;
+ default:
+ break;
+ }
+ } else if(DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0) ) {
+ ddcWidthmm = DDC2->features.hsize * 10;
+ ddcHeightmm = DDC2->features.vsize * 10;
+ switch(srel) {
+ case sisLeftOf:
+ case sisRightOf:
+ ddcWidthmm *= 2;
+ break;
+ case sisAbove:
+ case sisBelow:
+ ddcHeightmm *= 2;
+ default:
+ break;
+ }
+ }
+
+ if(monitorResolution > 0) {
+
+ /* Set command line given values (overrules given options) */
+ pScrn1->xDpi = monitorResolution;
+ pScrn1->yDpi = monitorResolution;
+ from = X_CMDLINE;
+
+ } else if(pSiS->MergedFBXDPI) {
+
+ /* Set option-wise given values (overrule DisplaySize) */
+ pScrn1->xDpi = pSiS->MergedFBXDPI;
+ pScrn1->yDpi = pSiS->MergedFBYDPI;
+ from = X_CONFIG;
+
+ } else if(pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
+
+ /* Set values calculated from given DisplaySize */
+ from = X_CONFIG;
+ if(pScrn1->widthmm > 0) {
+ pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+ }
+ if(pScrn1->heightmm > 0) {
+ pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+ }
+ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, pScrn1->heightmm);
+
+ } else if(ddcWidthmm && ddcHeightmm) {
+
+ /* Set values from DDC-provided display size */
+ from = X_PROBED;
+ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm );
+ pScrn1->widthmm = ddcWidthmm;
+ pScrn1->heightmm = ddcHeightmm;
+ if(pScrn1->widthmm > 0) {
+ pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+ }
+ if(pScrn1->heightmm > 0) {
+ pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+ }
+
+ } else {
+
+ pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
+
+ }
+
+ /* Sanity check */
+ if(pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
+ pScrn1->yDpi = pScrn1->xDpi;
+ if(pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
+ pScrn1->xDpi = pScrn1->yDpi;
+
+ pScrn2->xDpi = pScrn1->xDpi;
+ pScrn2->yDpi = pScrn1->yDpi;
+
+ xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
+ pScrn1->xDpi, pScrn1->yDpi);
+}
+
+/* Pseudo-Xinerama extension for MergedFB mode */
+#ifdef SISXINERAMA
+
+static void
+SiSUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
+{
+ SISPtr pSiS = SISPTR(pScrn1);
+ int crt1scrnnum = 0, crt2scrnnum = 1;
+ int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0;
+ DisplayModePtr currentMode, firstMode;
+ Bool infochanged = FALSE;
+
+ if(!pSiS->MergedFB) return;
+
+ if(SiSnoPanoramiXExtension) return;
+
+ if(!SiSXineramadataPtr) return;
+
+ if(pSiS->CRT2IsScrn0) {
+ crt1scrnnum = 1;
+ crt2scrnnum = 0;
+ }
+
+ /* Attention: Usage of RandR may lead into virtual X and Y values
+ * actually smaller than our MetaModes! To avoid this, we calculate
+ * the maxCRT fields here (and not somewhere else, like in CopyNLink)
+ */
+
+ if((pSiS->SiSXineramaVX != pScrn1->virtualX) || (pSiS->SiSXineramaVY != pScrn1->virtualY)) {
+
+ if(!(pScrn1->modes)) return;
+
+ pSiS->maxCRT1_X1 = pSiS->maxCRT1_X2 = 0;
+ pSiS->maxCRT1_Y1 = pSiS->maxCRT1_Y2 = 0;
+ pSiS->maxCRT2_X1 = pSiS->maxCRT2_X2 = 0;
+ pSiS->maxCRT2_Y1 = pSiS->maxCRT2_Y2 = 0;
+ pSiS->maxClone_X1 = pSiS->maxClone_X2 = 0;
+ pSiS->maxClone_Y1 = pSiS->maxClone_Y2 = 0;
+
+ currentMode = firstMode = pScrn1->modes;
+
+ do {
+
+ DisplayModePtr p = currentMode->next;
+ DisplayModePtr i = ((SiSMergedDisplayModePtr)currentMode->Private)->CRT1;
+ DisplayModePtr j = ((SiSMergedDisplayModePtr)currentMode->Private)->CRT2;
+ SiSScrn2Rel srel = ((SiSMergedDisplayModePtr)currentMode->Private)->CRT2Position;
+
+ if((i->HDisplay <= pScrn1->virtualX) && (j->HDisplay <= pScrn1->virtualX) &&
+ (i->VDisplay <= pScrn1->virtualY) && (j->VDisplay <= pScrn1->virtualY)) {
+
+ if(srel != sisClone) {
+ if(pSiS->maxCRT1_X1 <= i->HDisplay) {
+ pSiS->maxCRT1_X1 = i->HDisplay; /* Largest CRT1 mode */
+ if(pSiS->maxCRT1_X2 < j->HDisplay) {
+ pSiS->maxCRT1_X2 = j->HDisplay; /* Largest X of CRT2 mode displayed with largest CRT1 mode */
+ }
+ }
+ if(pSiS->maxCRT2_X2 <= j->HDisplay) {
+ pSiS->maxCRT2_X2 = j->HDisplay; /* Largest CRT2 mode */
+ if(pSiS->maxCRT2_X1 < i->HDisplay) {
+ pSiS->maxCRT2_X1 = i->HDisplay; /* Largest X of CRT1 mode displayed with largest CRT2 mode */
+ }
+ }
+ if(pSiS->maxCRT1_Y1 <= i->VDisplay) {
+ pSiS->maxCRT1_Y1 = i->VDisplay;
+ if(pSiS->maxCRT1_Y2 < j->VDisplay) {
+ pSiS->maxCRT1_Y2 = j->VDisplay;
+ }
+ }
+ if(pSiS->maxCRT2_Y2 <= j->VDisplay) {
+ pSiS->maxCRT2_Y2 = j->VDisplay;
+ if(pSiS->maxCRT2_Y1 < i->VDisplay) {
+ pSiS->maxCRT2_Y1 = i->VDisplay;
+ }
+ }
+ } else {
+ if(pSiS->maxClone_X1 < i->HDisplay) {
+ pSiS->maxClone_X1 = i->HDisplay;
+ }
+ if(pSiS->maxClone_X2 < j->HDisplay) {
+ pSiS->maxClone_X2 = j->HDisplay;
+ }
+ if(pSiS->maxClone_Y1 < i->VDisplay) {
+ pSiS->maxClone_Y1 = i->VDisplay;
+ }
+ if(pSiS->maxClone_Y2 < j->VDisplay) {
+ pSiS->maxClone_Y2 = j->VDisplay;
+ }
+ }
+ }
+ currentMode = p;
+
+ } while((currentMode) && (currentMode != firstMode));
+
+ pSiS->SiSXineramaVX = pScrn1->virtualX;
+ pSiS->SiSXineramaVY = pScrn1->virtualY;
+ infochanged = TRUE;
+
+ }
+
+ switch(pSiS->CRT2Position) {
+ case sisLeftOf:
+ x1 = min(pSiS->maxCRT1_X2, pScrn1->virtualX - pSiS->maxCRT1_X1);
+ if(x1 < 0) x1 = 0;
+ y1 = 0;
+ w1 = pScrn1->virtualX - x1;
+ h1 = pScrn1->virtualY;
+ x2 = 0;
+ y2 = 0;
+ w2 = max(pSiS->maxCRT2_X2, pScrn1->virtualX - pSiS->maxCRT2_X1);
+ if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
+ h2 = pScrn1->virtualY;
+ break;
+ case sisRightOf:
+ x1 = 0;
+ y1 = 0;
+ w1 = max(pSiS->maxCRT1_X1, pScrn1->virtualX - pSiS->maxCRT1_X2);
+ if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
+ h1 = pScrn1->virtualY;
+ x2 = min(pSiS->maxCRT2_X1, pScrn1->virtualX - pSiS->maxCRT2_X2);
+ if(x2 < 0) x2 = 0;
+ y2 = 0;
+ w2 = pScrn1->virtualX - x2;
+ h2 = pScrn1->virtualY;
+ break;
+ case sisAbove:
+ x1 = 0;
+ y1 = min(pSiS->maxCRT1_Y2, pScrn1->virtualY - pSiS->maxCRT1_Y1);
+ if(y1 < 0) y1 = 0;
+ w1 = pScrn1->virtualX;
+ h1 = pScrn1->virtualY - y1;
+ x2 = 0;
+ y2 = 0;
+ w2 = pScrn1->virtualX;
+ h2 = max(pSiS->maxCRT2_Y2, pScrn1->virtualY - pSiS->maxCRT2_Y1);
+ if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
+ break;
+ case sisBelow:
+ x1 = 0;
+ y1 = 0;
+ w1 = pScrn1->virtualX;
+ h1 = max(pSiS->maxCRT1_Y1, pScrn1->virtualY - pSiS->maxCRT1_Y2);
+ if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
+ x2 = 0;
+ y2 = min(pSiS->maxCRT2_Y1, pScrn1->virtualY - pSiS->maxCRT2_Y2);
+ if(y2 < 0) y2 = 0;
+ w2 = pScrn1->virtualX;
+ h2 = pScrn1->virtualY - y2;
+ default:
+ break;
+ }
+
+ SiSXineramadataPtr[crt1scrnnum].x = x1;
+ SiSXineramadataPtr[crt1scrnnum].y = y1;
+ SiSXineramadataPtr[crt1scrnnum].width = w1;
+ SiSXineramadataPtr[crt1scrnnum].height = h1;
+ SiSXineramadataPtr[crt2scrnnum].x = x2;
+ SiSXineramadataPtr[crt2scrnnum].y = y2;
+ SiSXineramadataPtr[crt2scrnnum].width = w2;
+ SiSXineramadataPtr[crt2scrnnum].height = h2;
+
+ if(infochanged) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: CRT1 (Screen %d) (%d,%d)-(%d,%d)\n",
+ crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1);
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: CRT2 (Screen %d) (%d,%d)-(%d,%d)\n",
+ crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1);
+ }
+}
+
+/* Proc */
+
+int
+SiSProcXineramaQueryVersion(ClientPtr client)
+{
+ xPanoramiXQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SIS_XINERAMA_MAJOR_VERSION;
+ rep.minorVersion = SIS_XINERAMA_MINOR_VERSION;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+int
+SiSProcXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ WindowPtr pWin;
+ xPanoramiXGetStateReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ pWin = LookupWindow(stuff->window, client);
+ if(!pWin) return BadWindow;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !SiSnoPanoramiXExtension;
+ if(client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (&rep.state, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+SiSProcXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenCountReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ pWin = LookupWindow(stuff->window, client);
+ if(!pWin) return BadWindow;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.ScreenCount = SiSXineramaNumScreens;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.ScreenCount, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+SiSProcXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenSizeReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ pWin = LookupWindow (stuff->window, client);
+ if(!pWin) return BadWindow;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.width = SiSXineramadataPtr[stuff->screen].width;
+ rep.height = SiSXineramadataPtr[stuff->screen].height;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.width, n);
+ swaps(&rep.height, n);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
+ return client->noClientException;
+}
+
+int
+SiSProcXineramaIsActive(ClientPtr client)
+{
+ xXineramaIsActiveReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !SiSnoPanoramiXExtension;
+ if(client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.state, n);
+ }
+ WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
+ return client->noClientException;
+}
+
+int
+SiSProcXineramaQueryScreens(ClientPtr client)
+{
+ xXineramaQueryScreensReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.number = (SiSnoPanoramiXExtension) ? 0 : SiSXineramaNumScreens;
+ rep.length = rep.number * sz_XineramaScreenInfo >> 2;
+ if(client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.number, n);
+ }
+ WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
+
+ if(!SiSnoPanoramiXExtension) {
+ xXineramaScreenInfo scratch;
+ int i;
+
+ for(i = 0; i < SiSXineramaNumScreens; i++) {
+ scratch.x_org = SiSXineramadataPtr[i].x;
+ scratch.y_org = SiSXineramadataPtr[i].y;
+ scratch.width = SiSXineramadataPtr[i].width;
+ scratch.height = SiSXineramadataPtr[i].height;
+ if(client->swapped) {
+ register int n;
+ swaps(&scratch.x_org, n);
+ swaps(&scratch.y_org, n);
+ swaps(&scratch.width, n);
+ swaps(&scratch.height, n);
+ }
+ WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
+ }
+ }
+
+ return client->noClientException;
+}
+
+static int
+SiSProcXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return SiSProcXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return SiSProcXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return SiSProcXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return SiSProcXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return SiSProcXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return SiSProcXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+/* SProc */
+
+static int
+SiSSProcXineramaQueryVersion (ClientPtr client)
+{
+ REQUEST(xPanoramiXQueryVersionReq);
+ register int n;
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ return SiSProcXineramaQueryVersion(client);
+}
+
+static int
+SiSSProcXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ return SiSProcXineramaGetState(client);
+}
+
+static int
+SiSSProcXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ return SiSProcXineramaGetScreenCount(client);
+}
+
+static int
+SiSSProcXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ return SiSProcXineramaGetScreenSize(client);
+}
+
+static int
+SiSSProcXineramaIsActive(ClientPtr client)
+{
+ REQUEST(xXineramaIsActiveReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+ return SiSProcXineramaIsActive(client);
+}
+
+static int
+SiSSProcXineramaQueryScreens(ClientPtr client)
+{
+ REQUEST(xXineramaQueryScreensReq);
+ register int n;
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+ return SiSProcXineramaQueryScreens(client);
+}
+
+int
+SiSSProcXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return SiSSProcXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return SiSSProcXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return SiSSProcXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return SiSSProcXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return SiSSProcXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return SiSSProcXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+static void
+SiSXineramaResetProc(ExtensionEntry* extEntry)
+{
+ /* Called by CloseDownExtensions() */
+ if(SiSXineramadataPtr) {
+ Xfree(SiSXineramadataPtr);
+ SiSXineramadataPtr = NULL;
+ }
+}
+
+static void
+SiSXineramaExtensionInit(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ Bool success = FALSE;
+
+ if(!(SiSXineramadataPtr)) {
+
+ if(!pSiS->MergedFB) {
+ SiSnoPanoramiXExtension = TRUE;
+ return;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Xinerama active, not initializing SiS Pseudo-Xinerama\n");
+ SiSnoPanoramiXExtension = TRUE;
+ return;
+ }
+#endif
+
+ if(SiSnoPanoramiXExtension) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SiS Pseudo-Xinerama disabled\n");
+ return;
+ }
+
+ if(pSiS->CRT2Position == sisClone) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Running MergedFB in Clone mode, SiS Pseudo-Xinerama disabled\n");
+ SiSnoPanoramiXExtension = TRUE;
+ return;
+ }
+
+ if(!(pSiS->AtLeastOneNonClone)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Only Clone modes defined, SiS Pseudo-Xinerama disabled\n");
+ SiSnoPanoramiXExtension = TRUE;
+ return;
+ }
+
+ SiSXineramaNumScreens = 2;
+
+ while(SiSXineramaGeneration != serverGeneration) {
+
+ pSiS->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
+ SiSProcXineramaDispatch,
+ SiSSProcXineramaDispatch,
+ SiSXineramaResetProc,
+ StandardMinorOpcode);
+
+ if(!pSiS->XineramaExtEntry) break;
+
+ if(!(SiSXineramadataPtr = (SiSXineramaData *)
+ xcalloc(SiSXineramaNumScreens, sizeof(SiSXineramaData)))) break;
+
+ SiSXineramaGeneration = serverGeneration;
+ success = TRUE;
+ }
+
+ if(!success) {
+ SISErrorLog(pScrn, "Failed to initialize SiS Pseudo-Xinerama extension\n");
+ SiSnoPanoramiXExtension = TRUE;
+ return;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SiS Pseudo-Xinerama extension initialized\n");
+
+ pSiS->SiSXineramaVX = 0;
+ pSiS->SiSXineramaVY = 0;
+
+ }
+
+ SiSUpdateXineramaScreenInfo(pScrn);
+
+}
+#endif /* End of PseudoXinerama */
+
+static void
+SiSFreeCRT2Structs(SISPtr pSiS)
+{
+ if(pSiS->CRT2pScrn) {
+ if(pSiS->CRT2pScrn->modes) {
+ while(pSiS->CRT2pScrn->modes)
+ xf86DeleteMode(&pSiS->CRT2pScrn->modes, pSiS->CRT2pScrn->modes);
+ }
+ if(pSiS->CRT2pScrn->monitor) {
+ if(pSiS->CRT2pScrn->monitor->Modes) {
+ while(pSiS->CRT2pScrn->monitor->Modes)
+ xf86DeleteMode(&pSiS->CRT2pScrn->monitor->Modes, pSiS->CRT2pScrn->monitor->Modes);
+ }
+ if(pSiS->CRT2pScrn->monitor->DDC) xfree(pSiS->CRT2pScrn->monitor->DDC);
+ xfree(pSiS->CRT2pScrn->monitor);
+ }
+ xfree(pSiS->CRT2pScrn);
+ pSiS->CRT2pScrn = NULL;
+ }
+}
+
+#endif /* End of MergedFB helpers */
static xf86MonPtr
SiSInternalDDC(ScrnInfoPtr pScrn, int crtno)
{
SISPtr pSiS = SISPTR(pScrn);
- USHORT temp, i;
+ USHORT temp = 0xffff, temp1, i, realcrtno = crtno;
unsigned char buffer[256];
xf86MonPtr pMonitor = NULL;
- /* TW: If CRT1 is off, skip DDC */
+ /* If CRT1 is off, skip DDC */
if((pSiS->CRT1off) && (!crtno)) return NULL;
- temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 0, &buffer[0]);
- if((!temp) || (temp == 0xffff)) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "CRT%d DDC probing failed, now trying via VBE\n", crtno + 1);
- return(NULL);
+ if(crtno) {
+ if(pSiS->VBFlags & CRT2_LCD) realcrtno = 1;
+ else if(pSiS->VBFlags & CRT2_VGA) realcrtno = 2;
+ else return NULL;
} else {
+ /* If CRT1 is LCDA, skip DDC (except 301C: DDC allowed, but uses CRT2 port!) */
+ if(pSiS->VBFlags & CRT1_LCDA) {
+ if(pSiS->VBFlags & VB_301C) realcrtno = 1;
+ else return NULL;
+ }
+ }
+
+ i = 3; /* Number of retrys */
+ do {
+ temp1 = SiS_HandleDDC(pSiS->SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, realcrtno, 0, &buffer[0]);
+ if((temp1) && (temp1 != 0xffff)) temp = temp1;
+ } while((temp == 0xffff) && i--);
+ if(temp != 0xffff) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT%d DDC supported\n", crtno + 1);
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT%d DDC level: %s%s%s%s\n",
crtno + 1,
(temp & 0x1a) ? "" : "[none of the supported]",
(temp & 0x02) ? "2 " : "",
- (temp & 0x08) ? "3 " : "",
- (temp & 0x10) ? "4" : "");
+ (temp & 0x08) ? "D&P" : "",
+ (temp & 0x10) ? "FPDI-2" : "");
if(temp & 0x02) {
- i = 3; /* Number of retrys */
+ i = 5; /* Number of retrys */
do {
- temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS, crtno, 1, &buffer[0]);
+ temp = SiS_HandleDDC(pSiS->SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, realcrtno, 1, &buffer[0]);
} while((temp) && i--);
if(!temp) {
if((pMonitor = xf86InterpretEDID(pScrn->scrnIndex, &buffer[0]))) {
return(pMonitor);
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"CRT%d DDC EDID corrupt\n", crtno + 1);
return(NULL);
}
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"CRT%d DDC reading failed\n", crtno + 1);
return(NULL);
}
- } else {
+ } else if(!crtno) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "DDC levels 3 and 4 not supported by this driver yet.\n");
+ "DDC for VESA D&P and FPDI-2 not supported for CRT1.\n");
return(NULL);
- }
+ } else if(temp & 0x18) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DDC for VESA D&P and FPDI-2 not supported for CRT2 yet.\n");
+ return(NULL);
+ }
+ return(NULL);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "CRT%d DDC probing failed\n", crtno + 1);
+ return(NULL);
}
}
static xf86MonPtr
-SiSDoPrivateDDC(ScrnInfoPtr pScrn)
+SiSDoPrivateDDC(ScrnInfoPtr pScrn, int *crtnum)
{
SISPtr pSiS = SISPTR(pScrn);
#ifdef SISDUALHEAD
- if((pSiS->DualHeadMode) && (!pSiS->SecondHead))
- return(SiSInternalDDC(pScrn, 1));
- else
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ *crtnum = 1;
+ return(SiSInternalDDC(pScrn, 0));
+ } else {
+ *crtnum = 2;
+ return(SiSInternalDDC(pScrn, 1));
+ }
+ } else
#endif
- return(SiSInternalDDC(pScrn, 0));
+ if(pSiS->CRT1off) {
+ *crtnum = 2;
+ return(SiSInternalDDC(pScrn, 1));
+ } else {
+ *crtnum = 1;
+ return(SiSInternalDDC(pScrn, 0));
+ }
+}
+
+static BOOLEAN
+SiSMakeOwnModeList(ScrnInfoPtr pScrn, BOOLEAN acceptcustommodes, BOOLEAN includelcdmodes,
+ BOOLEAN isfordvi, BOOLEAN *havecustommodes)
+{
+ DisplayModePtr tempmode, delmode, mymodes;
+
+ if((mymodes = SiSBuildBuiltInModeList(pScrn, includelcdmodes, isfordvi))) {
+ if(!acceptcustommodes) {
+ while(pScrn->monitor->Modes)
+ xf86DeleteMode(&pScrn->monitor->Modes, pScrn->monitor->Modes);
+ pScrn->monitor->Modes = mymodes;
+ } else {
+ delmode = pScrn->monitor->Modes;
+ while(delmode) {
+ if(delmode->type & M_T_DEFAULT) {
+ tempmode = delmode->next;
+ xf86DeleteMode(&pScrn->monitor->Modes, delmode);
+ delmode = tempmode;
+ } else {
+ delmode = delmode->next;
+ }
+ }
+ tempmode = pScrn->monitor->Modes;
+ if(tempmode) *havecustommodes = TRUE;
+ pScrn->monitor->Modes = mymodes;
+ while(mymodes) {
+ if(!mymodes->next) break;
+ else mymodes = mymodes->next;
+ }
+ mymodes->next = tempmode;
+ if(tempmode) {
+ tempmode->prev = mymodes;
+ }
+ }
+ return TRUE;
+ } else
+ return FALSE;
}
/* Mandatory */
@@ -1133,18 +2254,18 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
SISPtr pSiS;
MessageType from;
unsigned char usScratchCR17, CR5F;
- unsigned char usScratchCR32;
+ unsigned char usScratchCR32, usScratchCR63;
+ unsigned char usScratchSR1F;
unsigned long int i;
int temp;
ClockRangePtr clockRanges;
- char *mod = NULL;
- const char *Sym = NULL;
int pix24flags;
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = NULL;
#endif
+#if defined(SISMERGED) || defined(SISDUALHEAD)
DisplayModePtr first, p, n;
- DisplayModePtr tempmode, delmode, mymodes;
+#endif
unsigned char srlockReg,crlockReg;
unsigned char tempreg;
xf86MonPtr pMonitor = NULL;
@@ -1153,20 +2274,37 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
vbeInfoPtr pVbe;
VbeInfoBlock *vbe;
- if (flags & PROBE_DETECT) {
- if (xf86LoadSubModule(pScrn, "vbe")) {
- int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
-
+ static const char *ddcsstr = "CRT%d DDC monitor info: ************************************\n";
+ static const char *ddcestr = "End of CRT%d DDC monitor info ******************************\n";
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0)
+ static const char *subshstr = "Substituting missing CRT%d monitor HSync data by DDC data\n";
+ static const char *subsvstr = "Substituting missing CRT%d monitor VRefresh data by DDC data\n";
+#endif
+#ifdef SISMERGED
+ static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n";
+ static const char *mergednocrt2 = "No CRT2 output selected or no bridge detected. %s.\n";
+ static const char *mergeddisstr = "MergedFB mode disabled";
+ static const char *modesforstr = "Modes for CRT%d: *********************************************\n";
+ static const char *crtsetupstr = "------------------------ CRT%d setup -------------------------\n";
+#endif
+#if defined(SISDUALHEAD) || defined(SISMERGED)
+ static const char *notsuitablestr = "Not using mode \"%s\" (not suitable for %s mode)\n";
+#endif
+
+ if(flags & PROBE_DETECT) {
+ if(xf86LoadSubModule(pScrn, "vbe")) {
+ int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
+
#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
- if((pVbe = VBEInit(NULL,index))) {
+ if((pVbe = VBEInit(NULL,index))) {
#else
- if((pVbe = VBEExtendedInit(NULL,index,0))) {
+ if((pVbe = VBEExtendedInit(NULL,index,0))) {
#endif
- ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
- vbeFree(pVbe);
- }
- }
- return TRUE;
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+ }
+ return TRUE;
}
/*
@@ -1184,39 +2322,47 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Check the number of entities, and fail if it isn't one. */
if(pScrn->numEntities != 1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Number of entities is not 1\n");
- return FALSE;
+ SISErrorLog(pScrn, "Number of entities is not 1\n");
+ return FALSE;
}
/* The vgahw module should be loaded here when needed */
if(!xf86LoadSubModule(pScrn, "vgahw")) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not load vgahw module\n");
- return FALSE;
+ SISErrorLog(pScrn, "Could not load vgahw module\n");
+ return FALSE;
}
xf86LoaderReqSymLists(vgahwSymbols, NULL);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "SiS driver (31/01/03-1) by "
- "Thomas Winischhofer <thomas@winischhofer.net>\n");
+ "SiS driver (%d/%02d/%02d-%d) by "
+ "Thomas Winischhofer <thomas@winischhofer.net>\n",
+ SISDRIVERVERSIONYEAR + 2000, SISDRIVERVERSIONMONTH,
+ SISDRIVERVERSIONDAY, SISDRIVERREVISION);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "See http://www.winischhofer.net/linuxsisvga.shtml "
- "for documentation and updates\n");
+ "Compiled for XFree86 %d.%d.%d.%d\n",
+ XF86_VERSION_MAJOR, XF86_VERSION_MINOR,
+ XF86_VERSION_PATCH, XF86_VERSION_SNAP);
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
+ if(xf86GetVersion() != XF86_VERSION_CURRENT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "This version of the driver is not compiled for this version of XFree86!\n");
+ }
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "See http://www.winischhofer.net/linuxsisvga.shtml "
+ "for documentation and updates\n");
/* Allocate a vgaHWRec */
if(!vgaHWGetHWRec(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not allocate VGA private\n");
- return FALSE;
+ SISErrorLog(pScrn, "Could not allocate VGA private\n");
+ return FALSE;
}
/* Allocate the SISRec driverPrivate */
if(!SISGetRec(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not allocate memory for pSiS private\n");
- return FALSE;
+ SISErrorLog(pScrn, "Could not allocate memory for pSiS private\n");
+ return FALSE;
}
pSiS = SISPTR(pScrn);
pSiS->pScrn = pScrn;
@@ -1230,26 +2376,24 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Get the entity, and make sure it is PCI. */
pSiS->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if(pSiS->pEnt->location.type != BUS_PCI) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Entity's bus type is not PCI\n");
- SISFreeRec(pScrn);
- return FALSE;
+ SISErrorLog(pScrn, "Entity's bus type is not PCI\n");
+ SISFreeRec(pScrn);
+ return FALSE;
}
#ifdef SISDUALHEAD
- /* TW: Allocate an entity private if necessary */
+ /* Allocate an entity private if necessary */
if(xf86IsEntityShared(pScrn->entityList[0])) {
- pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0],
SISEntityIndex)->ptr;
- pSiS->entityPrivate = pSiSEnt;
+ pSiS->entityPrivate = pSiSEnt;
- /* TW: If something went wrong, quit here */
- if ((pSiSEnt->DisableDual) || (pSiSEnt->ErrorAfterFirst)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "First head encountered fatal error, can't continue\n");
- SISFreeRec(pScrn);
- return FALSE;
- }
+ /* If something went wrong, quit here */
+ if((pSiSEnt->DisableDual) || (pSiSEnt->ErrorAfterFirst)) {
+ SISErrorLog(pScrn, "First head encountered fatal error, can't continue\n");
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
}
#endif
@@ -1266,16 +2410,15 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(pSiS->Primary) {
VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
if(!vgaHWMapMem(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not map VGA memory\n");
+ SISErrorLog(pScrn, "Could not map VGA memory\n");
SISFreeRec(pScrn);
return FALSE;
}
}
vgaHWGetIOBase(VGAHWPTR(pScrn));
- /* TW: We "patch" the PIOOffset inside vgaHW in order to force
- * the vgaHW module to use our relocated i/o ports.
+ /* We "patch" the PIOOffset inside vgaHW in order to force
+ * the vgaHW module to use our relocated i/o ports.
*/
VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380;
@@ -1291,8 +2434,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->pInt = xf86InitInt10(pSiS->pEnt->index);
#endif
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not load int10 module\n");
+ SISErrorLog(pScrn, "Could not load int10 module\n");
}
}
@@ -1315,14 +2457,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* The ramdac module should be loaded here when needed */
if(!xf86LoadSubModule(pScrn, "ramdac")) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not load ramdac module\n");
+ SISErrorLog(pScrn, "Could not load ramdac module\n");
#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
}
xf86LoaderReqSymLists(ramdacSymbols, NULL);
@@ -1334,32 +2475,32 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
* Set the Chipset and ChipRev, allowing config file entries to
* override. DANGEROUS!
*/
- if (pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) {
- pScrn->chipset = pSiS->pEnt->device->chipset;
- pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset);
- from = X_CONFIG;
- } else if (pSiS->pEnt->device->chipID >= 0) {
- pSiS->Chipset = pSiS->pEnt->device->chipID;
- pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
-
- from = X_CONFIG;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ if(pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) {
+ pScrn->chipset = pSiS->pEnt->device->chipset;
+ pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if(pSiS->pEnt->device->chipID >= 0) {
+ pSiS->Chipset = pSiS->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
+
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
pSiS->Chipset);
} else {
- from = X_PROBED;
- pSiS->Chipset = pSiS->PciInfo->chipType;
- pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
+ from = X_PROBED;
+ pSiS->Chipset = pSiS->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
}
- if (pSiS->pEnt->device->chipRev >= 0) {
- pSiS->ChipRev = pSiS->pEnt->device->chipRev;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ if(pSiS->pEnt->device->chipRev >= 0) {
+ pSiS->ChipRev = pSiS->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
pSiS->ChipRev);
} else {
- pSiS->ChipRev = pSiS->PciInfo->chipRev;
+ pSiS->ChipRev = pSiS->PciInfo->chipRev;
}
pSiS->sishw_ext.jChipRevision = pSiS->ChipRev;
- /* TW: Determine SiS6326 chiprevision. This is not yet used for
+ /* Determine SiS6326 chiprevision. This is not yet used for
* anything, but it will as soon as I found out on which revisions
* the hardware video overlay really works.
* According to SiS the only differences are:
@@ -1370,19 +2511,19 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
*/
pSiS->SiS6326Flags = 0;
if(pSiS->Chipset == PCI_CHIP_SIS6326) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Chipset is SiS6326 %s (revision 0x%02x)\n",
(pSiS->ChipRev == 0xaf) ? "(Ax)" :
((pSiS->ChipRev == 0x0a) ? "AGP (G0)" :
((pSiS->ChipRev == 0x0b) ? "AGP (H0)" :
- (((pSiS->ChipRev & 0xf0) == 0xd0) ? "DVD (Dx)" :
+ (((pSiS->ChipRev & 0xf0) == 0xd0) ? "DVD (Dx/H0)" :
(((pSiS->ChipRev & 0xf0) == 0x90) ? "(9x)" :
(((pSiS->ChipRev & 0xf0) == 0xc0) ? "(Cx)" :
"(unknown)"))))),
pSiS->ChipRev);
- if((pSiS->ChipRev != 0x0a) && (pSiS->ChipRev != 0x0b)) {
+ if((pSiS->ChipRev != 0x0a) && (pSiS->ChipRev != 0x0b)) {
pSiS->SiS6326Flags |= SIS6326_HASTV;
- }
+ }
}
@@ -1390,71 +2531,122 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
* This shouldn't happen because such problems should be caught in
* SISProbe(), but check it just in case.
*/
- if (pScrn->chipset == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ChipID 0x%04X is not recognised\n", pSiS->Chipset);
+ if(pScrn->chipset == NULL) {
+ SISErrorLog(pScrn, "ChipID 0x%04X is not recognised\n", pSiS->Chipset);
#ifdef SISDUALHEAD
- if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
}
- if (pSiS->Chipset < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ if(pSiS->Chipset < 0) {
+ SISErrorLog(pScrn, "Chipset \"%s\" is not recognised\n", pScrn->chipset);
#ifdef SISDUALHEAD
- if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
}
- /* TW: Determine chipset and VGA engine type for new mode switching code */
+ /* Determine chipset and VGA engine type */
+ pSiS->ChipFlags = 0;
+ pSiS->SiS_SD_Flags = 0;
+
switch(pSiS->Chipset) {
case PCI_CHIP_SIS300:
pSiS->sishw_ext.jChipType = SIS_300;
pSiS->VGAEngine = SIS_300_VGA;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES;
break;
case PCI_CHIP_SIS630: /* 630 + 730 */
pSiS->sishw_ext.jChipType = SIS_630;
if(pciReadLong(0x00000000, 0x00) == 0x07301039) {
- pSiS->sishw_ext.jChipType = SIS_730;
+ pSiS->sishw_ext.jChipType = SIS_730;
}
pSiS->VGAEngine = SIS_300_VGA;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES;
break;
case PCI_CHIP_SIS540:
pSiS->sishw_ext.jChipType = SIS_540;
pSiS->VGAEngine = SIS_300_VGA;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES;
break;
case PCI_CHIP_SIS315H:
pSiS->sishw_ext.jChipType = SIS_315H;
pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->ChipFlags |= SiSCF_315Core;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
break;
case PCI_CHIP_SIS315:
- /* TW: Override for simplicity */
+ /* Override for simplicity */
pSiS->Chipset = PCI_CHIP_SIS315H;
pSiS->sishw_ext.jChipType = SIS_315;
+ pSiS->ChipFlags |= SiSCF_315Core;
pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
break;
case PCI_CHIP_SIS315PRO:
- /* TW: Override for simplicity */
+ /* Override for simplicity */
pSiS->Chipset = PCI_CHIP_SIS315H;
pSiS->sishw_ext.jChipType = SIS_315PRO;
+ pSiS->ChipFlags |= SiSCF_315Core;
pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
break;
case PCI_CHIP_SIS550:
pSiS->sishw_ext.jChipType = SIS_550;
pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->ChipFlags |= SiSCF_Integrated;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
break;
case PCI_CHIP_SIS650: /* 650 + 740 */
pSiS->sishw_ext.jChipType = SIS_650;
+ if(pciReadLong(0x00000000, 0x00) == 0x07401039) {
+ pSiS->sishw_ext.jChipType = SIS_740;
+ }
pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->ChipFlags |= (SiSCF_Integrated | SiSCF_Real256ECore);
+ pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
break;
case PCI_CHIP_SIS330:
pSiS->sishw_ext.jChipType = SIS_330;
- pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->ChipFlags |= SiSCF_XabreCore;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES;
+ break;
+ case PCI_CHIP_SIS660: /* 660, 661, 741, 760 */
+ {
+ unsigned long hpciid = pciReadLong(0x00000000, 0x00);
+ switch(hpciid) {
+ case 0x06601039:
+ pSiS->sishw_ext.jChipType = SIS_660;
+ pSiS->ChipFlags |= SiSCF_Ultra256Core;
+ break;
+ case 0x07601039:
+ pSiS->sishw_ext.jChipType = SIS_760;
+ pSiS->ChipFlags |= SiSCF_Ultra256Core;
+ break;
+ case 0x07411039:
+ pSiS->sishw_ext.jChipType = SIS_741;
+ pSiS->ChipFlags |= SiSCF_Real256ECore;
+ break;
+ case 0x06611039:
+ default:
+ pSiS->sishw_ext.jChipType = SIS_661;
+ pSiS->ChipFlags |= SiSCF_Real256ECore;
+ }
+ /* Detection could also be done by CR5C & 0xf8:
+ 0x10 = 661 (CR5F & 0xc0: 0x00 both A0 and A1)
+ 0x80 = 760 (CR5F & 0xc0: 0x00 A0, 0x40 A1)
+ 0x90 = 741 (CR5F & 0xc0: 0x00 A0,A1 0x40 A2)
+ other: 660 (CR5F & 0xc0: 0x00 A0 0x40 A1) (DOA?)
+ */
+ pSiS->VGAEngine = SIS_315_VGA;
+ pSiS->ChipFlags |= SiSCF_Integrated;
+ pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES;
+ }
break;
case PCI_CHIP_SIS530:
pSiS->sishw_ext.jChipType = SIS_530;
@@ -1466,172 +2658,194 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
break;
}
- /* TW: Now check if sisfb is loaded. Since sisfb only supports
- * the 300 and 310/325 series, we only do this for these chips.
+ /* Now check if sisfb is loaded. Since sisfb only supports
+ * the 300 and 315 series, we only do this for these chips.
* We use this for checking where sisfb starts its memory
* heap in order to automatically detect the correct MaxXFBMem
* setting (which normally is given by the option of the same name).
- * That only works if sisfb is completely running, ie with
- * a video mode (because the fbdev will not be installed otherwise.)
+ * Under kernel 2.4.y, that only works if sisfb is completely
+ * running, ie with a video mode because the fbdev will not be
+ * installed otherwise. Under 2.5 and later, sisfb will install
+ * the framebuffer device in any way and running it with mode=none
+ * is no longer supported (or necessary).
*/
pSiS->donttrustpdc = FALSE;
pSiS->sisfbpdc = 0;
+ pSiS->sisfblcda = 0xff;
+ pSiS->sisfbscalelcd = -1;
+ pSiS->sisfbspecialtiming = CUT_NONE;
+ pSiS->OldMode = 0;
+ pSiS->sisfbfound = FALSE;
if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
int fd, i;
sisfb_info mysisfbinfo;
- BOOL found = FALSE;
char name[10];
+ CARD32 sisfbversion;
- i=0;
- do {
- sprintf(name, "/dev/fb%1d", i);
- if((fd = open(name, 'r'))) {
+ {
+ i=0;
+ do {
+ sprintf(name, "/dev/fb%1d", i);
+ if((fd = open(name, 'r')) != -1) {
- if(!ioctl(fd, SISFB_GET_INFO, &mysisfbinfo)) {
+ if(!ioctl(fd, SISFB_GET_INFO, &mysisfbinfo)) {
- if(mysisfbinfo.sisfb_id == SISFB_ID) {
+ if(mysisfbinfo.sisfb_id == SISFB_ID) {
- if((mysisfbinfo.sisfb_version >= 1) &&
- (mysisfbinfo.sisfb_revision >=5) &&
- (mysisfbinfo.sisfb_patchlevel >= 8)) {
- /* TW: Added PCI bus/slot/func into in sisfb Version 1.5.08.
+ sisfbversion = (mysisfbinfo.sisfb_version << 16) |
+ (mysisfbinfo.sisfb_revision << 8) |
+ (mysisfbinfo.sisfb_patchlevel);
+
+ if(sisfbversion >= 0x010508) {
+ /* Added PCI bus/slot/func into in sisfb Version 1.5.08.
Check this to make sure we run on the same card as sisfb
- */
- if((mysisfbinfo.sisfb_pcibus == pSiS->PciInfo->bus) &&
- (mysisfbinfo.sisfb_pcislot == pSiS->PciInfo->device) &&
- (mysisfbinfo.sisfb_pcifunc == pSiS->PciInfo->func) ) {
- found = TRUE;
- }
- } else found = TRUE;
-
- if(found) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "%s: SiS kernel fb driver (sisfb) %d.%d.%d detected (PCI: %02d:%02d.%d)\n",
- &name[5],
- mysisfbinfo.sisfb_version,
- mysisfbinfo.sisfb_revision,
- mysisfbinfo.sisfb_patchlevel,
- pSiS->PciInfo->bus,
- pSiS->PciInfo->device,
- pSiS->PciInfo->func);
- /* TW: Added version/rev/pl in sisfb 1.4.0 */
- if(mysisfbinfo.sisfb_version == 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Old version of sisfb found. Please update\n");
- }
- pSiS->sisfbMem = mysisfbinfo.heapstart;
- /* TW: Basically, we can't trust the pdc register if sisfb is loaded */
- pSiS->donttrustpdc = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "sisfb: memory heap starts at %dKB\n", pSiS->sisfbMem);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "sisfb: using video mode 0x%02x\n", mysisfbinfo.fbvidmode);
- if((mysisfbinfo.sisfb_version >= 1) &&
- (mysisfbinfo.sisfb_revision >=5) &&
- (mysisfbinfo.sisfb_patchlevel >= 6)) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "sisfb: %sreserved hardware cursor, using %s command queue\n",
- (mysisfbinfo.sisfb_caps & 0x80) ? "" : "not ",
- (mysisfbinfo.sisfb_caps & 0x40) ? "SiS300 series Turbo" :
- (mysisfbinfo.sisfb_caps & 0x20) ? "SiS310/325 series AGP" :
- (mysisfbinfo.sisfb_caps & 0x10) ? "SiS310/325 series VRAM" :
- (mysisfbinfo.sisfb_caps & 0x08) ? "SiS310/325 series MMIO" :
- "no");
- }
- if((mysisfbinfo.sisfb_version >= 1) &&
- (mysisfbinfo.sisfb_revision >=5) &&
- (mysisfbinfo.sisfb_patchlevel >= 10)) {
- /* TW: We can trust the pdc value if sisfb is of recent version */
- pSiS->donttrustpdc = FALSE;
- if(mysisfbinfo.sisfb_patchlevel >= 11) {
- pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc;
+ */
+ if((mysisfbinfo.sisfb_pcibus == pSiS->PciInfo->bus) &&
+ (mysisfbinfo.sisfb_pcislot == pSiS->PciInfo->device) &&
+ (mysisfbinfo.sisfb_pcifunc == pSiS->PciInfo->func) ) {
+ pSiS->sisfbfound = TRUE;
+ }
+ } else pSiS->sisfbfound = TRUE;
+
+ if(pSiS->sisfbfound) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%s: SiS kernel fb driver (sisfb) %d.%d.%d detected (PCI: %02d:%02d.%d)\n",
+ &name[5],
+ mysisfbinfo.sisfb_version,
+ mysisfbinfo.sisfb_revision,
+ mysisfbinfo.sisfb_patchlevel,
+ pSiS->PciInfo->bus,
+ pSiS->PciInfo->device,
+ pSiS->PciInfo->func);
+ /* Added version/rev/pl in sisfb 1.4.0 */
+ if(mysisfbinfo.sisfb_version == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Old version of sisfb found. Please update\n");
+ }
+ pSiS->sisfbMem = mysisfbinfo.heapstart;
+ /* Basically, we can't trust the pdc register if sisfb is loaded */
+ pSiS->donttrustpdc = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: memory heap starts at %dKB\n", (int)pSiS->sisfbMem);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: using video mode 0x%02x\n", mysisfbinfo.fbvidmode);
+ pSiS->OldMode = mysisfbinfo.fbvidmode;
+ if(sisfbversion >= 0x010506) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: %sreserved hardware cursor, using %s command queue\n",
+ (mysisfbinfo.sisfb_caps & 0x80) ? "" : "not ",
+ (mysisfbinfo.sisfb_caps & 0x40) ? "SiS300 Turbo" :
+ (mysisfbinfo.sisfb_caps & 0x20) ? "SiS315/330 AGP" :
+ (mysisfbinfo.sisfb_caps & 0x10) ? "SiS315/330 VRAM" :
+ (mysisfbinfo.sisfb_caps & 0x08) ? "SiS315/330 MMIO" :
+ "no");
+ }
+ if(sisfbversion >= 0x01050A) {
+ /* We can trust the pdc value if sisfb is of recent version */
+ if(pSiS->VGAEngine == SIS_300_VGA) pSiS->donttrustpdc = FALSE;
+ if(sisfbversion >= 0x01050B) {
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ /* As of 1.5.11, sisfb saved the register for us (300 series) */
+ pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc;
+ }
+ }
+ if(sisfbversion >= 0x01050E) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ pSiS->sisfblcda = mysisfbinfo.sisfb_lcda;
+ }
+ if(sisfbversion >= 0x01060D) {
+ pSiS->sisfbscalelcd = mysisfbinfo.sisfb_scalelcd;
+ pSiS->sisfbspecialtiming = mysisfbinfo.sisfb_specialtiming;
+ }
+ if(sisfbversion >= 0x010610) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ pSiS->donttrustpdc = FALSE;
+ pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc;
+ }
+ }
+ }
+ }
}
- }
- }
- }
- }
- close (fd);
- }
- i++;
-
- } while((i <= 7) && (!found));
+ }
+ }
+ close (fd);
+ }
+ i++;
+ } while((i <= 7) && (!pSiS->sisfbfound));
+ if(!pSiS->sisfbfound) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "sisfb not found\n");
+ }
}
/*
* The first thing we should figure out is the depth, bpp, etc.
- * TW: Additionally, determine the size of the HWCursor memory
- * area.
+ * Additionally, determine the size of the HWCursor memory area.
*/
- switch (pSiS->VGAEngine) {
+ switch(pSiS->VGAEngine) {
case SIS_300_VGA:
pSiS->CursorSize = 4096;
- pix24flags = Support32bppFb |
- SupportConvert24to32;
+ pix24flags = Support32bppFb;
break;
case SIS_315_VGA:
pSiS->CursorSize = 16384;
- pix24flags = Support32bppFb |
- SupportConvert24to32;
+ pix24flags = Support32bppFb;
break;
case SIS_530_VGA:
pSiS->CursorSize = 2048;
pix24flags = Support32bppFb |
- Support24bppFb |
- SupportConvert24to32 |
- SupportConvert32to24;
+ Support24bppFb;
break;
default:
pSiS->CursorSize = 2048;
- pix24flags = Support24bppFb |
- SupportConvert32to24 |
- PreferConvert32to24;
+ pix24flags = Support24bppFb;
break;
}
#ifdef SISDUALHEAD
- /* TW: In case of Dual Head, we need to determine if we are the "master" head or
- * the "slave" head. In order to do that, we set PrimInit to DONE in the
- * shared entity at the end of the first initialization. The second
- * initialization then knows that some things have already been done. THIS
- * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
+ /* In case of Dual Head, we need to determine if we are the "master" head or
+ * the "slave" head. In order to do that, we set PrimInit to DONE in the
+ * shared entity at the end of the first initialization. The second
+ * initialization then knows that some things have already been done. THIS
+ * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
*/
if(xf86IsEntityShared(pScrn->entityList[0])) {
- if(pSiSEnt->lastInstance > 0) {
- if(!xf86IsPrimInitDone(pScrn->entityList[0])) {
- /* First Head (always CRT2) */
- pSiS->SecondHead = FALSE;
- pSiSEnt->pScrn_1 = pScrn;
- pSiSEnt->CRT1ModeNo = pSiSEnt->CRT2ModeNo = -1;
- pSiS->DualHeadMode = TRUE;
- pSiSEnt->DisableDual = FALSE;
- pSiSEnt->BIOS = NULL;
- pSiSEnt->SiS_Pr = NULL;
- } else {
- /* Second Head (always CRT1) */
- pSiS->SecondHead = TRUE;
- pSiSEnt->pScrn_2 = pScrn;
- pSiS->DualHeadMode = TRUE;
- }
- } else {
- /* TW: Only one screen in config file - disable dual head mode */
- pSiS->SecondHead = FALSE;
- pSiS->DualHeadMode = FALSE;
- pSiSEnt->DisableDual = TRUE;
- }
+ if(pSiSEnt->lastInstance > 0) {
+ if(!xf86IsPrimInitDone(pScrn->entityList[0])) {
+ /* First Head (always CRT2) */
+ pSiS->SecondHead = FALSE;
+ pSiSEnt->pScrn_1 = pScrn;
+ pSiSEnt->CRT1ModeNo = pSiSEnt->CRT2ModeNo = -1;
+ pSiSEnt->CRT2ModeSet = FALSE;
+ pSiS->DualHeadMode = TRUE;
+ pSiSEnt->DisableDual = FALSE;
+ pSiSEnt->BIOS = NULL;
+ pSiSEnt->SiS_Pr = NULL;
+ pSiSEnt->RenderAccelArray = NULL;
+ } else {
+ /* Second Head (always CRT1) */
+ pSiS->SecondHead = TRUE;
+ pSiSEnt->pScrn_2 = pScrn;
+ pSiS->DualHeadMode = TRUE;
+ }
+ } else {
+ /* Only one screen in config file - disable dual head mode */
+ pSiS->SecondHead = FALSE;
+ pSiS->DualHeadMode = FALSE;
+ pSiSEnt->DisableDual = TRUE;
+ }
} else {
- /* TW: Entity is not shared - disable dual head mode */
- pSiS->SecondHead = FALSE;
- pSiS->DualHeadMode = FALSE;
+ /* Entity is not shared - disable dual head mode */
+ pSiS->SecondHead = FALSE;
+ pSiS->DualHeadMode = FALSE;
}
#endif
pSiS->ForceCursorOff = FALSE;
- /* TW: Allocate SiS_Private (for mode switching code) and initialize it */
+ /* Allocate SiS_Private (for mode switching code) and initialize it */
pSiS->SiS_Pr = NULL;
#ifdef SISDUALHEAD
if(pSiSEnt) {
@@ -1640,43 +2854,50 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
#endif
if(!pSiS->SiS_Pr) {
if(!(pSiS->SiS_Pr = xnfcalloc(sizeof(SiS_Private), 1))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not allocate memory for SiS_Pr private\n");
+ SISErrorLog(pScrn, "Could not allocate memory for SiS_Pr private\n");
#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
}
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->SiS_Pr = pSiS->SiS_Pr;
#endif
memset(pSiS->SiS_Pr, 0, sizeof(SiS_Private));
+ pSiS->SiS_Pr->SiS_Backup70xx = 0xff;
+ pSiS->SiS_Pr->SiS_CHOverScan = -1;
+ pSiS->SiS_Pr->SiS_ChSW = FALSE;
+ pSiS->SiS_Pr->SiS_CustomT = CUT_NONE;
+ pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE;
+ pSiS->SiS_Pr->LVDSHL = -1;
}
- pSiS->SiS_Pr->SiS_Backup70xx = 0xff;
- pSiS->SiS_Pr->SiS_CHOverScan = -1;
- pSiS->SiS_Pr->SiS_ChSW = FALSE;
- pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE;
- /* TW: Get our relocated IO registers */
- pSiS->RelIO = (pSiS->PciInfo->ioBase[2] & 0xFFFC) + pSiS->IODBase;
- pSiS->sishw_ext.ulIOAddress = pSiS->RelIO + 0x30;
+ /* Get our relocated IO registers */
+ pSiS->RelIO = (SISIOADDRESS)((pSiS->PciInfo->ioBase[2] & 0xFFFC) + pSiS->IODBase);
+ pSiS->sishw_ext.ulIOAddress = (SISIOADDRESS)(pSiS->RelIO + 0x30);
xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n",
(unsigned long)pSiS->RelIO);
- /* TW: Initialize SiS Port Reg definitions for externally used
- * BIOS emulation (init.c/init301.c) functions.
+ /* Initialize SiS Port Reg definitions for externally used
+ * init.c/init301.c functions.
*/
SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO + 0x30);
- /* TW: The following identifies the old chipsets. This is only
- * partly used since the really old chips are not supported,
- * but I keep it here for future use.
+ /* The following identifies the old chipsets. This is only
+ * partly used since the really old chips are not supported,
+ * but I keep it here for future use.
+ * 205, 215 and 225 are to be treated the same way, 201 and 202
+ * are different.
*/
if(pSiS->VGAEngine == SIS_OLD_VGA || pSiS->VGAEngine == SIS_530_VGA) {
switch(pSiS->Chipset) {
- case PCI_CHIP_SG86C205: /* Just for making it complete */
+ case PCI_CHIP_SG86C201:
+ pSiS->oldChipset = OC_SIS86201; break;
+ case PCI_CHIP_SG86C202:
+ pSiS->oldChipset = OC_SIS86202; break;
+ case PCI_CHIP_SG86C205:
{
unsigned char temp;
sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg);
@@ -1686,65 +2907,80 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
OC_SIS6205C : OC_SIS6205A;
break;
}
- case PCI_CHIP_SIS82C204: /* Just for making it complete */
+ case PCI_CHIP_SIS82C204:
pSiS->oldChipset = OC_SIS82204; break;
- case 0x6225: /* Just for making it complete */
+ case 0x6225:
pSiS->oldChipset = OC_SIS6225; break;
case PCI_CHIP_SIS5597:
pSiS->oldChipset = OC_SIS5597; break;
case PCI_CHIP_SIS6326:
pSiS->oldChipset = OC_SIS6326; break;
case PCI_CHIP_SIS530:
- if((pSiS->ChipRev & 0x0f) < 0x0a)
- pSiS->oldChipset = OC_SIS530A;
- else pSiS->oldChipset = OC_SIS530B;
+ if(pciReadLong(0x00000000, 0x00) == 0x06201039) {
+ pSiS->oldChipset = OC_SIS620;
+ } else {
+ if((pSiS->ChipRev & 0x0f) < 0x0a)
+ pSiS->oldChipset = OC_SIS530A;
+ else pSiS->oldChipset = OC_SIS530B;
+ }
break;
default:
pSiS->oldChipset = OC_UNKNOWN;
}
}
- if(!xf86SetDepthBpp(pScrn, 8, 8, 8, pix24flags)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf86SetDepthBpp() error\n");
+ if(!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
+ SISErrorLog(pScrn, "xf86SetDepthBpp() error\n");
#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
}
/* Check that the returned depth is one we support */
temp = 0;
switch(pScrn->depth) {
- case 8:
- case 16:
- case 24:
- break;
- case 15:
- if((pSiS->VGAEngine == SIS_300_VGA) ||
- (pSiS->VGAEngine == SIS_315_VGA))
- temp = 1;
- break;
- default:
- temp = 1;
+ case 8:
+ case 16:
+ case 24:
+ break;
+ case 15:
+ if((pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA)) {
+ temp = 1;
+ }
+ break;
+ default:
+ temp = 1;
}
if(temp) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Given depth (%d) is not supported by this driver/chipset\n",
+ SISErrorLog(pScrn,
+ "Given color depth (%d) is not supported by this driver/chipset\n",
pScrn->depth);
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
}
xf86PrintDepthBpp(pScrn);
+ if( (((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) &&
+ (pScrn->bitsPerPixel == 24)) ||
+ ((pSiS->VGAEngine == SIS_OLD_VGA) && (pScrn->bitsPerPixel == 32)) ) {
+ SISErrorLog(pScrn,
+ "Framebuffer bpp %d not supported for this chipset\n", pScrn->bitsPerPixel);
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
/* Get the depth24 pixmap format */
- if(pScrn->depth == 24 && pix24bpp == 0)
- pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+ if(pScrn->depth == 24 && pix24bpp == 0) {
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+ }
/*
* This must happen after pScrn->display has been set because
@@ -1755,8 +2991,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
rgb zeros = {0, 0, 0};
if(!xf86SetWeight(pScrn, zeros, zeros)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf86SetWeight() error\n");
+ SISErrorLog(pScrn, "xf86SetWeight() error\n");
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -1783,10 +3018,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
break;
}
if(ret) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "RGB Weight %d%d%d at depth %d not supported by hardware\n",
- pScrn->weight.red, pScrn->weight.green,
- pScrn->weight.blue, pScrn->depth);
+ SISErrorLog(pScrn,
+ "RGB weight %d%d%d at depth %d not supported by hardware\n",
+ (int)pScrn->weight.red, (int)pScrn->weight.green,
+ (int)pScrn->weight.blue, pScrn->depth);
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -1797,28 +3032,27 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
}
}
- /* TW: Set the current layout parameters */
+ /* Set the current layout parameters */
pSiS->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
pSiS->CurrentLayout.depth = pScrn->depth;
/* (Inside this function, we can use pScrn's contents anyway) */
if(!xf86SetDefaultVisual(pScrn, -1)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf86SetDefaultVisual() error\n");
+ SISErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
#ifdef SISDUALHEAD
- if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
SISFreeRec(pScrn);
return FALSE;
} else {
/* We don't support DirectColor at > 8bpp */
- if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual "
- "(%s) is not supported at depth %d\n",
- xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ if(pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ SISErrorLog(pScrn,
+ "Given default visual (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
#ifdef SISDUALHEAD
- if (pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
SISFreeRec(pScrn);
@@ -1826,6 +3060,17 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
}
}
+#ifdef SISDUALHEAD
+ /* Due to palette & timing problems we don't support 8bpp in DHM */
+ if((pSiS->DualHeadMode) && (pScrn->bitsPerPixel == 8)) {
+ SISErrorLog(pScrn, "Color depth 8 not supported in Dual Head mode.\n");
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+#endif
+
/*
* The cmap layer needs this to be initialised.
*/
@@ -1833,8 +3078,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
Gamma zeros = {0.0, 0.0, 0.0};
if(!xf86SetGamma(pScrn, zeros)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf86SetGamma() error\n");
+ SISErrorLog(pScrn, "xf86SetGamma() error\n");
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -1849,35 +3093,29 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Set the bits per RGB for 8bpp mode */
if(pScrn->depth == 8) {
- pScrn->rgbBits = 6;
+ pScrn->rgbBits = 6;
}
- pSiS->ddc1Read = SiSddc1Read;
-
from = X_DEFAULT;
/* Unlock registers */
sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg);
- /* TW: We need no backup area (300/310/325 new mode switching code) */
- pSiS->sishw_ext.pSR = NULL;
- pSiS->sishw_ext.pCR = NULL;
-
- /* TW: Read BIOS for 300 and 310/325 series customization */
+ /* Read BIOS for 300 and 315/330 series customization */
pSiS->sishw_ext.pjVirtualRomBase = NULL;
pSiS->BIOS = NULL;
pSiS->sishw_ext.UseROM = FALSE;
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
#ifdef SISDUALHEAD
- if(pSiSEnt) {
+ if(pSiSEnt) {
if(pSiSEnt->BIOS) {
- pSiS->BIOS = pSiSEnt->BIOS;
- pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS;
+ pSiS->BIOS = pSiSEnt->BIOS;
+ pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS;
}
- }
+ }
#endif
- if(!pSiS->BIOS) {
+ if(!pSiS->BIOS) {
if(!(pSiS->BIOS = xcalloc(1, BIOS_SIZE))) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Could not allocate memory for video BIOS image\n");
@@ -1887,15 +3125,15 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
BOOLEAN found;
int i;
static const char sis_rom_sig[] = "Silicon Integrated Systems";
- static const char *sis_sig[10] = {
+ static const char *sis_sig[15] = {
"300", "540", "630", "730",
- "315", "315", "315", "5315", "6325",
- "Xabre"
+ "315", "315", "315", "5315", "6325", "6325",
+ "Xabre", "6330", "6330", "6330", "6330"
};
- static const unsigned short sis_nums[10] = {
+ static const unsigned short sis_nums[15] = {
SIS_300, SIS_540, SIS_630, SIS_730,
- SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650,
- SIS_330
+ SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740,
+ SIS_330, SIS_661, SIS_741, SIS_660, SIS_760
};
found = FALSE;
@@ -1915,16 +3153,21 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
romptr = pSiS->BIOS[0x14] | (pSiS->BIOS[0x15] << 8);
if(romptr > (BIOS_SIZE - 5)) continue;
- for(i = 0; (i < 10) && (!found); i++) {
- if(strncmp(sis_sig[i], (char *)&pSiS->BIOS[romptr], strlen(sis_sig[i])) == 0) {
- if(sis_nums[i] == pSiS->sishw_ext.jChipType) {
- found = TRUE;
- break;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Ignoring BIOS for SiS %s at %p\n", sis_sig[i], segstart);
- }
- }
+ for(i = 0; (i < 15) && (!found); i++) {
+ if(strncmp(sis_sig[i], (char *)&pSiS->BIOS[romptr], strlen(sis_sig[i])) == 0) {
+ if(sis_nums[i] == pSiS->sishw_ext.jChipType) {
+ found = TRUE;
+ break;
+ } else {
+ if((pSiS->sishw_ext.jChipType != SIS_740) &&
+ (pSiS->sishw_ext.jChipType != SIS_661) &&
+ (pSiS->sishw_ext.jChipType != SIS_741) &&
+ (pSiS->sishw_ext.jChipType != SIS_660)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Ignoring BIOS for SiS %s at 0x%lx\n", sis_sig[i], segstart);
+ }
+ }
+ }
}
if(found) break;
}
@@ -1941,38 +3184,48 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS;
romptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8);
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Video BIOS version \"%7s\" found at %p\n",
+ "Video BIOS version \"%7s\" found at 0x%lx\n",
&pSiS->BIOS[romptr], segstart);
}
-
}
- }
- if(pSiS->BIOS) pSiS->sishw_ext.UseROM = TRUE;
- else pSiS->sishw_ext.UseROM = FALSE;
+ }
+ if(pSiS->BIOS) pSiS->sishw_ext.UseROM = TRUE;
+ else pSiS->sishw_ext.UseROM = FALSE;
}
/* Evaluate options */
SiSOptions(pScrn);
+#ifdef SISMERGED
+ /* Due to palette & timing problems we don't support 8bpp in MFBM */
+ if((pSiS->MergedFB) && (pScrn->bitsPerPixel == 8)) {
+ SISErrorLog(pScrn, "MergedFB: Color depth 8 not supported, %s\n", mergeddisstr);
+ pSiS->MergedFB = pSiS->MergedFBAuto = FALSE;
+ }
+#endif
+
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
if(!pSiS->SecondHead) {
- /* TW: Copy some option settings to entity private */
+ /* Copy some option settings to entity private */
pSiSEnt->HWCursor = pSiS->HWCursor;
+ pSiSEnt->NoAccel = pSiS->NoAccel;
+ pSiSEnt->restorebyset = pSiS->restorebyset;
+ pSiSEnt->OptROMUsage = pSiS->OptROMUsage;
+ pSiSEnt->OptUseOEM = pSiS->OptUseOEM;
+ pSiSEnt->TurboQueue = pSiS->TurboQueue;
+ pSiSEnt->forceCRT1 = pSiS->forceCRT1;
+ pSiSEnt->ForceCRT1Type = pSiS->ForceCRT1Type;
pSiSEnt->ForceCRT2Type = pSiS->ForceCRT2Type;
pSiSEnt->ForceTVType = pSiS->ForceTVType;
- pSiSEnt->TurboQueue = pSiS->TurboQueue;
+ pSiSEnt->UsePanelScaler = pSiS->UsePanelScaler;
pSiSEnt->PDC = pSiS->PDC;
+ pSiSEnt->DSTN = pSiS->DSTN;
pSiSEnt->OptTVStand = pSiS->OptTVStand;
pSiSEnt->NonDefaultPAL = pSiS->NonDefaultPAL;
+ pSiSEnt->NonDefaultNTSC = pSiS->NonDefaultNTSC;
pSiSEnt->OptTVOver = pSiS->OptTVOver;
pSiSEnt->OptTVSOver = pSiS->OptTVSOver;
- pSiSEnt->OptROMUsage = pSiS->OptROMUsage;
- pSiSEnt->DSTN = pSiS->DSTN;
- pSiSEnt->XvOnCRT2 = pSiS->XvOnCRT2;
- pSiSEnt->NoAccel = pSiS->NoAccel;
- pSiSEnt->NoXvideo = pSiS->NoXvideo;
- pSiSEnt->forceCRT1 = pSiS->forceCRT1;
pSiSEnt->chtvlumabandwidthcvbs = pSiS->chtvlumabandwidthcvbs;
pSiSEnt->chtvlumabandwidthsvideo = pSiS->chtvlumabandwidthsvideo;
pSiSEnt->chtvlumaflickerfilter = pSiS->chtvlumaflickerfilter;
@@ -1984,9 +3237,28 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiSEnt->sistvedgeenhance = pSiS->sistvedgeenhance;
pSiSEnt->sistvantiflicker = pSiS->sistvantiflicker;
pSiSEnt->sistvsaturation = pSiS->sistvsaturation;
+ pSiSEnt->sistvcfilter = pSiS->sistvcfilter;
+ pSiSEnt->sistvyfilter = pSiS->sistvyfilter;
+ pSiSEnt->sistvcolcalibc = pSiS->sistvcolcalibc;
+ pSiSEnt->sistvcolcalibf = pSiS->sistvcolcalibf;
pSiSEnt->tvxpos = pSiS->tvxpos;
pSiSEnt->tvypos = pSiS->tvypos;
- pSiSEnt->restorebyset = pSiS->restorebyset;
+ pSiSEnt->tvxscale = pSiS->tvxscale;
+ pSiSEnt->tvyscale = pSiS->tvyscale;
+ pSiSEnt->CRT1gamma = pSiS->CRT1gamma;
+ pSiSEnt->CRT1gammaGiven = pSiS->CRT1gammaGiven;
+ pSiSEnt->XvGammaRed = pSiS->XvGammaRed;
+ pSiSEnt->XvGammaGreen = pSiS->XvGammaGreen;
+ pSiSEnt->XvGammaBlue = pSiS->XvGammaBlue;
+ pSiSEnt->XvGamma = pSiS->XvGamma;
+ pSiSEnt->XvGammaGiven = pSiS->XvGammaGiven;
+ pSiSEnt->CRT2gamma = pSiS->CRT2gamma;
+ pSiSEnt->XvOnCRT2 = pSiS->XvOnCRT2;
+ pSiSEnt->AllowHotkey = pSiS->AllowHotkey;
+ pSiSEnt->enablesisctrl = pSiS->enablesisctrl;
+#ifdef SIS_CP
+ SIS_CP_DRIVER_COPYOPTIONSENT
+#endif
} else {
/* We always use same cursor type on both screens */
if(pSiS->HWCursor != pSiSEnt->HWCursor) {
@@ -1997,85 +3269,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
"Master head ruled: HWCursor shall be %s\n",
pSiS->HWCursor ? "enabled" : "disabled");
}
- /* We need to use identical CRT2 Type setting */
- if(pSiS->ForceCRT2Type != pSiSEnt->ForceCRT2Type) {
- if(pSiS->ForceCRT2Type != CRT2_DEFAULT) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Ignoring inconsistent ForceCRT2Type setting. Master head rules\n");
- }
- pSiS->ForceCRT2Type = pSiSEnt->ForceCRT2Type;
- }
- if(pSiS->ForceTVType != pSiSEnt->ForceTVType) {
- if(pSiS->ForceTVType != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Ignoring inconsistent ForceTVType setting. Master head rules\n");
- }
- pSiS->ForceTVType = pSiSEnt->ForceTVType;
- }
- /* We need identical TurboQueue setting */
- if(pSiS->TurboQueue != pSiSEnt->TurboQueue) {
- pSiS->TurboQueue = pSiSEnt->TurboQueue;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent TurboQueue setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: Turboqueue shall be %s\n",
- pSiS->TurboQueue ? "enabled" : "disabled");
- }
- /* We need identical PDC setting */
- if(pSiS->PDC != pSiSEnt->PDC) {
- pSiS->PDC = pSiSEnt->PDC;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent PanelDelayCompensation setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: PanelDelayCompensation shall be %d%s\n",
- pSiS->PDC,
- (pSiS->PDC == -1) ? " (autodetected)" : "");
- }
- /* We need identical TVStandard setting */
- if( (pSiS->OptTVStand != pSiSEnt->OptTVStand) ||
- (pSiS->NonDefaultPAL != pSiSEnt->NonDefaultPAL) ) {
- if(pSiS->OptTVStand != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent TVStandard setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: TVStandard shall be %s\n",
- (pSiSEnt->OptTVStand ?
- ( (pSiSEnt->NonDefaultPAL == -1) ? "PAL" :
- ((pSiSEnt->NonDefaultPAL) ? "PALM" : "PALN") )
- : "NTSC"));
- }
- pSiS->OptTVStand = pSiSEnt->OptTVStand;
- pSiS->NonDefaultPAL = pSiSEnt->NonDefaultPAL;
- }
- /* We need identical UseROMData setting */
- if(pSiS->OptROMUsage != pSiSEnt->OptROMUsage) {
- if(pSiS->OptROMUsage != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent UseROMData setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: Video ROM data usage shall be %s\n",
- pSiSEnt->OptROMUsage ? "enabled" : "disabled");
- }
- pSiS->OptROMUsage = pSiSEnt->OptROMUsage;
- }
- /* We need identical DSTN setting */
- if(pSiS->DSTN != pSiSEnt->DSTN) {
- pSiS->DSTN = pSiSEnt->DSTN;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent DSTN setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: DSTN shall be %s\n",
- pSiS->DSTN ? "enabled" : "disabled");
- }
- /* We need identical XvOnCRT2 setting */
- if(pSiS->XvOnCRT2 != pSiSEnt->XvOnCRT2) {
- pSiS->XvOnCRT2 = pSiSEnt->XvOnCRT2;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent XvOnCRT2 setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: Xv shall be used on CRT%d\n",
- pSiS->XvOnCRT2 ? 2 : 1);
- }
+
/* We need identical NoAccel setting */
if(pSiS->NoAccel != pSiSEnt->NoAccel) {
pSiS->NoAccel = pSiSEnt->NoAccel;
@@ -2085,197 +3279,103 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
"Master head ruled: Acceleration shall be %s\n",
pSiS->NoAccel ? "disabled" : "enabled");
}
- /* We need identical ForceCRT1 setting */
- if(pSiS->forceCRT1 != pSiSEnt->forceCRT1) {
- if(pSiS->forceCRT1 != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent ForceCRT1 setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: CRT1 shall be %s\n",
- pSiSEnt->forceCRT1 ? "enabled" : "disabled");
- }
- pSiS->forceCRT1 = pSiSEnt->forceCRT1;
- }
- /* We need identical TVOverscan setting */
- if(pSiS->OptTVOver != pSiSEnt->OptTVOver) {
- if(pSiS->OptTVOver != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVOverscan setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: CHTVOverscan shall be %s\n",
- pSiSEnt->OptTVOver ? "true (=overscan)" : "false (=underscan)");
- }
- pSiS->OptTVOver = pSiSEnt->OptTVOver;
- }
- /* We need identical TVSOverscan setting */
- if(pSiS->OptTVSOver != pSiSEnt->OptTVSOver) {
- if(pSiS->OptTVSOver != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVSuperOverscan setting\n");
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Master head ruled: CHTVSuperOverscan shall be %s\n",
- pSiSEnt->OptTVSOver ? "true" : "false");
- }
- pSiS->OptTVSOver = pSiSEnt->OptTVSOver;
- }
- /* We need identical TV settings */
- if(pSiS->chtvtype != pSiSEnt->chtvtype) {
- if(pSiS->chtvtype != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVType setting; set to %s\n",
- (pSiSEnt->chtvtype) ? "SCART" : "HDTV");
- }
- pSiS->chtvtype = pSiSEnt->chtvtype;
- }
- if(pSiS->chtvlumabandwidthcvbs != pSiSEnt->chtvlumabandwidthcvbs) {
- if(pSiS->chtvlumabandwidthcvbs != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVLumaBandWidthCVBS setting; set to %d\n",
- pSiSEnt->chtvlumabandwidthcvbs);
- }
- pSiS->chtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs;
- }
- if(pSiS->chtvlumabandwidthsvideo != pSiSEnt->chtvlumabandwidthsvideo) {
- if(pSiS->chtvlumabandwidthsvideo != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVLumaBandWidthSVIDEO setting; set to %d\n",
- pSiSEnt->chtvlumabandwidthsvideo);
- }
- pSiS->chtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo;
- }
- if(pSiS->chtvlumaflickerfilter != pSiSEnt->chtvlumaflickerfilter) {
- if(pSiS->chtvlumaflickerfilter != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVLumaFlickerFilter setting; set to %d\n",
- pSiSEnt->chtvlumaflickerfilter);
- }
- pSiS->chtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter;
- }
- if(pSiS->chtvchromabandwidth != pSiSEnt->chtvchromabandwidth) {
- if(pSiS->chtvchromabandwidth != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVChromaBandWidth setting; set to %d\n",
- pSiSEnt->chtvchromabandwidth);
- }
- pSiS->chtvchromabandwidth = pSiSEnt->chtvchromabandwidth;
- }
- if(pSiS->chtvchromaflickerfilter != pSiSEnt->chtvchromaflickerfilter) {
- if(pSiS->chtvchromaflickerfilter != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVChromaFlickerFilter setting; set to %d\n",
- pSiSEnt->chtvchromaflickerfilter);
- }
- pSiS->chtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter;
- }
- if(pSiS->chtvcvbscolor != pSiSEnt->chtvcvbscolor) {
- if(pSiS->chtvcvbscolor != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVCVBSColor setting; set to %s\n",
- pSiSEnt->chtvcvbscolor ? "true" : "false");
- }
- pSiS->chtvcvbscolor = pSiSEnt->chtvcvbscolor;
- }
- if(pSiS->chtvtextenhance != pSiSEnt->chtvtextenhance) {
- if(pSiS->chtvtextenhance != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVTextEnhance setting; set to %d\n",
- pSiSEnt->chtvtextenhance);
- }
- pSiS->chtvtextenhance = pSiSEnt->chtvtextenhance;
- }
- if(pSiS->chtvcontrast != pSiSEnt->chtvcontrast) {
- if(pSiS->chtvcontrast != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent CHTVContrast setting; set to %d\n",
- pSiSEnt->chtvcontrast);
- }
- pSiS->chtvcontrast = pSiSEnt->chtvcontrast;
- }
- if(pSiS->sistvedgeenhance != pSiSEnt->sistvedgeenhance) {
- if(pSiS->sistvedgeenhance != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent SISTVEdgeEnhance setting; set to %d\n",
- pSiSEnt->sistvedgeenhance);
- }
- pSiS->sistvedgeenhance = pSiSEnt->sistvedgeenhance;
- }
- if(pSiS->sistvantiflicker != pSiSEnt->sistvantiflicker) {
- if(pSiS->sistvantiflicker != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent SISTVAntiFlicker setting; set to %d\n",
- pSiSEnt->sistvantiflicker);
- }
- pSiS->sistvantiflicker = pSiSEnt->sistvantiflicker;
- }
- if(pSiS->sistvsaturation != pSiSEnt->sistvsaturation) {
- if(pSiS->sistvsaturation != -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent SISTVSaturation setting; set to %d\n",
- pSiSEnt->sistvsaturation);
- }
- pSiS->sistvsaturation = pSiSEnt->sistvsaturation;
- }
- if(pSiS->tvxpos != pSiSEnt->tvxpos) {
- if(pSiS->tvxpos != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent TVXPosOffset setting; set to %d\n",
- pSiSEnt->tvxpos);
- }
- pSiS->tvxpos = pSiSEnt->tvxpos;
+
+ pSiS->TurboQueue = pSiSEnt->TurboQueue;
+ pSiS->restorebyset = pSiSEnt->restorebyset;
+ pSiS->AllowHotkey = pSiS->AllowHotkey;
+ pSiS->OptROMUsage = pSiSEnt->OptROMUsage;
+ pSiS->OptUseOEM = pSiSEnt->OptUseOEM;
+ pSiS->forceCRT1 = pSiSEnt->forceCRT1;
+ pSiS->nocrt2ddcdetection = FALSE;
+ pSiS->forcecrt2redetection = FALSE;
+ pSiS->ForceCRT1Type = pSiSEnt->ForceCRT1Type;
+ pSiS->ForceCRT2Type = pSiSEnt->ForceCRT2Type;
+ pSiS->UsePanelScaler = pSiSEnt->UsePanelScaler;
+ pSiS->PDC = pSiSEnt->PDC;
+ pSiS->DSTN = pSiSEnt->DSTN;
+ pSiS->OptTVStand = pSiSEnt->OptTVStand;
+ pSiS->NonDefaultPAL = pSiSEnt->NonDefaultPAL;
+ pSiS->NonDefaultNTSC = pSiSEnt->NonDefaultNTSC;
+ pSiS->chtvtype = pSiSEnt->chtvtype;
+ pSiS->ForceTVType = pSiSEnt->ForceTVType;
+ pSiS->OptTVOver = pSiSEnt->OptTVOver;
+ pSiS->OptTVSOver = pSiSEnt->OptTVSOver;
+ pSiS->chtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs;
+ pSiS->chtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo;
+ pSiS->chtvlumaflickerfilter = pSiSEnt->chtvlumaflickerfilter;
+ pSiS->chtvchromabandwidth = pSiSEnt->chtvchromabandwidth;
+ pSiS->chtvchromaflickerfilter = pSiSEnt->chtvchromaflickerfilter;
+ pSiS->chtvcvbscolor = pSiSEnt->chtvcvbscolor;
+ pSiS->chtvtextenhance = pSiSEnt->chtvtextenhance;
+ pSiS->chtvcontrast = pSiSEnt->chtvcontrast;
+ pSiS->sistvedgeenhance = pSiSEnt->sistvedgeenhance;
+ pSiS->sistvantiflicker = pSiSEnt->sistvantiflicker;
+ pSiS->sistvsaturation = pSiSEnt->sistvsaturation;
+ pSiS->sistvcfilter = pSiSEnt->sistvcfilter;
+ pSiS->sistvyfilter = pSiSEnt->sistvyfilter;
+ pSiS->sistvcolcalibc = pSiSEnt->sistvcolcalibc;
+ pSiS->sistvcolcalibf = pSiSEnt->sistvcolcalibf;
+ pSiS->tvxpos = pSiSEnt->tvxpos;
+ pSiS->tvypos = pSiSEnt->tvypos;
+ pSiS->tvxscale = pSiSEnt->tvxscale;
+ pSiS->tvyscale = pSiSEnt->tvyscale;
+ if(!pSiS->CRT1gammaGiven) {
+ if(pSiSEnt->CRT1gammaGiven)
+ pSiS->CRT1gamma = pSiSEnt->CRT1gamma;
}
- if(pSiS->tvypos != pSiSEnt->tvypos) {
- if(pSiS->tvypos != 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Ignoring inconsistent TVYPosOffset setting; set to %d\n",
- pSiSEnt->tvypos);
+ pSiS->CRT2gamma = pSiSEnt->CRT2gamma;
+ if(!pSiS->XvGammaGiven) {
+ if(pSiSEnt->XvGammaGiven) {
+ pSiS->XvGamma = pSiSEnt->XvGamma;
+ pSiS->XvGammaRed = pSiS->XvGammaRedDef = pSiSEnt->XvGammaRed;
+ pSiS->XvGammaGreen = pSiS->XvGammaGreenDef = pSiSEnt->XvGammaGreen;
+ pSiS->XvGammaBlue = pSiS->XvGammaBlueDef = pSiSEnt->XvGammaBlue;
}
- pSiS->tvypos = pSiSEnt->tvypos;
- }
- if(pSiS->restorebyset != pSiSEnt->restorebyset) {
- pSiS->restorebyset = pSiSEnt->restorebyset;
}
+ pSiS->XvOnCRT2 = pSiSEnt->XvOnCRT2;
+ pSiS->enablesisctrl = pSiSEnt->enablesisctrl;
+ /* Copy gamma brightness to Ent for Xinerama */
+ pSiSEnt->GammaBriR = pSiS->GammaBriR;
+ pSiSEnt->GammaBriG = pSiS->GammaBriG;
+ pSiSEnt->GammaBriB = pSiS->GammaBriB;
+ pSiSEnt->GammaPBriR = pSiS->GammaPBriR;
+ pSiSEnt->GammaPBriG = pSiS->GammaPBriG;
+ pSiSEnt->GammaPBriB = pSiS->GammaPBriB;
+#ifdef SIS_CP
+ SIS_CP_DRIVER_COPYOPTIONS
+#endif
}
}
#endif
- /* TW: Handle UseROMData and NoOEM options */
+
+ /* Handle UseROMData, NoOEM and UsePanelScaler options */
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
from = X_PROBED;
if(pSiS->OptROMUsage == 0) {
- pSiS->sishw_ext.UseROM = FALSE;
- from = X_CONFIG;
+ pSiS->sishw_ext.UseROM = FALSE;
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Video ROM data usage is disabled\n");
}
- xf86DrvMsg(pScrn->scrnIndex, from, "Video ROM data usage is %s\n",
- pSiS->sishw_ext.UseROM ? "enabled" : "disabled");
if(!pSiS->OptUseOEM)
- xf86DrvMsg(pScrn->scrnIndex, from, "Internal OEM LCD/TV data usage is disabled\n");
-
- if(pSiS->sbiosn) {
- if(pSiS->BIOS) {
- FILE *fd = NULL;
- int i;
- if((fd = fopen(pSiS->sbiosn, "w" ))) {
- i = fwrite(pSiS->BIOS, 65536, 1, fd);
- fclose(fd);
- }
- }
- xfree(pSiS->sbiosn);
- }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Internal OEM LCD/TV/VGA2 data usage is disabled\n");
+
+ pSiS->SiS_Pr->UsePanelScaler = pSiS->UsePanelScaler;
}
/* Do basic configuration */
SiSSetup(pScrn);
from = X_PROBED;
- if (pSiS->pEnt->device->MemBase != 0) {
- /*
- * XXX Should check that the config file value matches one of the
- * PCI base address values.
- */
- pSiS->FbAddress = pSiS->pEnt->device->MemBase;
- from = X_CONFIG;
+ if(pSiS->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pSiS->FbAddress = pSiS->pEnt->device->MemBase;
+ from = X_CONFIG;
} else {
- pSiS->FbAddress = pSiS->PciInfo->memBase[0] & 0xFFFFFFF0;
+ pSiS->FbAddress = pSiS->PciInfo->memBase[0] & 0xFFFFFFF0;
}
pSiS->realFbAddress = pSiS->FbAddress;
@@ -2289,15 +3389,15 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
(unsigned long)pSiS->FbAddress);
- if (pSiS->pEnt->device->IOBase != 0) {
+ if(pSiS->pEnt->device->IOBase != 0) {
/*
* XXX Should check that the config file value matches one of the
* PCI base address values.
*/
- pSiS->IOAddress = pSiS->pEnt->device->IOBase;
- from = X_CONFIG;
+ pSiS->IOAddress = pSiS->pEnt->device->IOBase;
+ from = X_CONFIG;
} else {
- pSiS->IOAddress = pSiS->PciInfo->memBase[1] & 0xFFFFFFF0;
+ pSiS->IOAddress = pSiS->PciInfo->memBase[1] & 0xFFFFFFF0;
}
xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
@@ -2306,24 +3406,29 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Register the PCI-assigned resources. */
if(xf86RegisterResources(pSiS->pEnt->index, NULL, ResExclusive)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf86RegisterResources() found resource conflicts\n");
+ SISErrorLog(pScrn, "xf86RegisterResources() found resource conflicts\n");
#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
}
from = X_PROBED;
- if (pSiS->pEnt->device->videoRam != 0) {
- pScrn->videoRam = pSiS->pEnt->device->videoRam;
- from = X_CONFIG;
+ if(pSiS->pEnt->device->videoRam != 0) {
+ if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ pScrn->videoRam = pSiS->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"VideoRAM\" ignored\n");
+ }
}
pSiS->RealVideoRam = pScrn->videoRam;
+
if((pSiS->Chipset == PCI_CHIP_SIS6326)
&& (pScrn->videoRam > 4096)
&& (from != X_CONFIG)) {
@@ -2331,9 +3436,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, from,
"SiS6326: Detected %d KB VideoRAM, limiting to %d KB\n",
pSiS->RealVideoRam, pScrn->videoRam);
- } else
+ } else {
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n",
pScrn->videoRam);
+ }
if((pSiS->Chipset == PCI_CHIP_SIS6326) &&
(pScrn->videoRam > 4096)) {
@@ -2351,21 +3457,27 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->sishw_ext.ulVideoMemorySize = pScrn->videoRam * 1024;
pSiS->sishw_ext.bSkipDramSizing = TRUE;
- /* TW: Calculate real availMem according to Accel/TurboQueue and
- * HWCursur setting. Also, initialize some variables used
- * in other modules.
+ /* Calculate real availMem according to Accel/TurboQueue and
+ * HWCursur setting. Also, initialize some variables used
+ * in other modules.
*/
+
pSiS->cursorOffset = 0;
- switch (pSiS->VGAEngine) {
+ pSiS->CurARGBDest = NULL;
+ pSiS->CurMonoSrc = NULL;
+ pSiS->CurFGCol = pSiS->CurBGCol = 0;
+
+ switch(pSiS->VGAEngine) {
+
case SIS_300_VGA:
pSiS->TurboQueueLen = 512;
if(pSiS->TurboQueue) {
- pSiS->availMem -= (pSiS->TurboQueueLen*1024);
- pSiS->cursorOffset = 512;
+ pSiS->availMem -= (pSiS->TurboQueueLen*1024);
+ pSiS->cursorOffset = 512;
}
- if(pSiS->HWCursor) {
- pSiS->availMem -= pSiS->CursorSize;
- if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize;
+ if(pSiS->HWCursor) {
+ pSiS->availMem -= pSiS->CursorSize;
+ if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize;
}
pSiS->CmdQueLenMask = 0xFFFF;
pSiS->CmdQueLenFix = 0;
@@ -2374,150 +3486,255 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(pSiSEnt) pSiSEnt->cursorBufferNum = 0;
#endif
break;
+
case SIS_315_VGA:
+#ifdef SISVRAMQ
+ pSiS->cmdQueueSizeMask = pSiS->cmdQueueSize - 1; /* VRAM Command Queue is variable (in therory) */
+ pSiS->cmdQueueOffset = (pScrn->videoRam * 1024) - pSiS->cmdQueueSize;
+ pSiS->cmdQueueLen = 0;
+ pSiS->cmdQueueLenMin = 0x200;
+ pSiS->cmdQueueLenMax = pSiS->cmdQueueSize - pSiS->cmdQueueLenMin;
+ pSiS->cmdQueueSize_div2 = pSiS->cmdQueueSize / 2;
+ pSiS->cmdQueueSize_div4 = pSiS->cmdQueueSize / 4;
+ pSiS->cmdQueueSize_4_3 = (pSiS->cmdQueueSize / 4) * 3;
+ pSiS->availMem -= pSiS->cmdQueueSize;
+ pSiS->cursorOffset = (pSiS->cmdQueueSize / 1024);
+#else
if(pSiS->TurboQueue) {
- pSiS->availMem -= (512*1024); /* Command Queue is 512k */
- pSiS->cursorOffset = 512;
+ pSiS->availMem -= (512*1024); /* MMIO Command Queue is 512k (variable in theory) */
+ pSiS->cursorOffset = 512;
}
- if(pSiS->HWCursor) {
- pSiS->availMem -= pSiS->CursorSize;
- if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize;
+#endif
+ if(pSiS->HWCursor) {
+ pSiS->availMem -= pSiS->CursorSize;
+ if(pSiS->OptUseColorCursor) pSiS->availMem -= pSiS->CursorSize;
}
pSiS->cursorBufferNum = 0;
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->cursorBufferNum = 0;
#endif
break;
+
default:
- /* TW: cursorOffset not used in cursor functions for 530 and
- * older chips, because the cursor is *above* the TQ.
- * On 5597 and older revisions of the 6326, the TQ is
- * max 32K, on newer 6326 revisions and the 530 either 30
- * (or 32?) or 62K (or 64?). However, to make sure, we
- * use only 30K (or 32?), but reduce the available memory
- * by 64, and locate the TQ at the beginning of this last
- * 64K block. (We do this that way even when using the
- * HWCursor, because the cursor only takes 2K, and the queue
- * does not seem to last that far anyway.)
- * The TQ must be located at 32KB boundaries.
+ /* cursorOffset not used in cursor functions for 530 and
+ * older chips, because the cursor is *above* the TQ.
+ * On 5597 and older revisions of the 6326, the TQ is
+ * max 32K, on newer 6326 revisions and the 530 either 30
+ * (or 32?) or 62K (or 64?). However, to make sure, we
+ * use only 30K (or 32?), but reduce the available memory
+ * by 64, and locate the TQ at the beginning of this last
+ * 64K block. (We do this that way even when using the
+ * HWCursor, because the cursor only takes 2K and the
+ * queue does not seem to last that far anyway.)
+ * The TQ must be located at 32KB boundaries.
*/
if(pSiS->RealVideoRam < 3072) {
- if(pSiS->TurboQueue) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
- }
- pSiS->TurboQueue = FALSE;
+ if(pSiS->TurboQueue) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
+ pSiS->TurboQueue = FALSE;
+ }
}
pSiS->CmdQueMaxLen = 32;
if(pSiS->TurboQueue) {
pSiS->availMem -= (64*1024);
- pSiS->CmdQueMaxLen = 900; /* TW: To make sure; should be 992 */
- } else if (pSiS->HWCursor) {
+ pSiS->CmdQueMaxLen = 900; /* To make sure; should be 992 */
+ } else if(pSiS->HWCursor) {
pSiS->availMem -= pSiS->CursorSize;
}
if(pSiS->Chipset == PCI_CHIP_SIS530) {
- /* TW: Check if Flat Panel is enabled */
+ /* Check if Flat Panel is enabled */
inSISIDXREG(SISSR, 0x0e, tempreg);
if(!tempreg & 0x04) pSiS->availMem -= pSiS->CursorSize;
- /* TW: Set up mask for MMIO register */
+ /* Set up mask for MMIO register */
pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x1FFF : 0x00FF;
} else {
- /* TW: TQ is never used on 6326/5597, because the accelerator
- * always Syncs. So this is just cosmentic work. (And I
- * am not even sure that 0x7fff is correct. MMIO 0x83a8
- * holds 0xec0 if (30k) TQ is enabled, 0x20 if TQ disabled.
- * The datasheet has no real explanation on the queue length
- * if the TQ is enabled. Not syncing and waiting for a
- * suitable queue length instead does not work.
+ /* TQ is never used on 6326/5597, because the accelerator
+ * always Syncs. So this is just cosmentic work. (And I
+ * am not even sure that 0x7fff is correct. MMIO 0x83a8
+ * holds 0xec0 if (30k) TQ is enabled, 0x20 if TQ disabled.
+ * The datasheet has no real explanation on the queue length
+ * if the TQ is enabled. Not syncing and waiting for a
+ * suitable queue length instead does not work.
*/
pSiS->CmdQueLenMask = (pSiS->TurboQueue) ? 0x7FFF : 0x003F;
}
- /* TW: This is to be subtracted from MMIO queue length register contents
- * for getting the real Queue length.
+ /* This is to be subtracted from MMIO queue length register contents
+ * for getting the real Queue length.
*/
pSiS->CmdQueLenFix = (pSiS->TurboQueue) ? 32 : 0;
}
#ifdef SISDUALHEAD
- /* TW: In dual head mode, we share availMem equally - so align it
- * to 8KB; this way, the address of the FB of the second
- * head is aligned to 4KB for mapping.
+ /* In dual head mode, we share availMem equally - so align it
+ * to 8KB; this way, the address of the FB of the second
+ * head is aligned to 4KB for mapping.
*/
- if (pSiS->DualHeadMode)
- pSiS->availMem &= 0xFFFFE000;
+ if(pSiS->DualHeadMode)
+ pSiS->availMem &= 0xFFFFE000;
#endif
- /* TW: Check MaxXFBMem setting */
+ /* Check MaxXFBMem setting */
#ifdef SISDUALHEAD
- /* TW: Since DRI is not supported in dual head mode, we
- don't need MaxXFBMem setting. */
- if (pSiS->DualHeadMode) {
- if(pSiS->maxxfbmem) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ /* Since DRI is not supported in dual head mode, we
+ don't need the MaxXFBMem setting. */
+ if(pSiS->DualHeadMode) {
+ if(pSiS->maxxfbmem) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n");
- }
- pSiS->maxxfbmem = pSiS->availMem;
+ }
+ pSiS->maxxfbmem = pSiS->availMem;
} else
#endif
- if (pSiS->maxxfbmem) {
- if (pSiS->maxxfbmem > pSiS->availMem) {
- if (pSiS->sisfbMem) {
- pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Invalid MaxXFBMem setting. Using sisfb heap start information\n");
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
- pSiS->maxxfbmem = pSiS->availMem;
- }
- } else if (pSiS->sisfbMem) {
- if (pSiS->maxxfbmem > pSiS->sisfbMem * 1024) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MaxXFBMem beyond sisfb heap start. Using sisfb heap start information\n");
- pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
- }
- }
- } else if (pSiS->sisfbMem) {
- pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
+ if(pSiS->maxxfbmem) {
+ if(pSiS->maxxfbmem > pSiS->availMem) {
+ if(pSiS->sisfbMem) {
+ pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid MaxXFBMem setting. Using sisfb heap start information\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
+ pSiS->maxxfbmem = pSiS->availMem;
+ }
+ } else if(pSiS->sisfbMem) {
+ if(pSiS->maxxfbmem > pSiS->sisfbMem * 1024) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "MaxXFBMem beyond sisfb heap start. Using sisfb heap start\n");
+ pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
+ }
+ }
+ } else if(pSiS->sisfbMem) {
+ pSiS->maxxfbmem = pSiS->sisfbMem * 1024;
}
else pSiS->maxxfbmem = pSiS->availMem;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %dK of framebuffer memory\n",
- pSiS->maxxfbmem / 1024);
-
- /* TW: Check if the chipset supports two video overlays */
- pSiS->Flags650 = 0;
- if ( (!pSiS->NoXvideo) &&
- ( pSiS->VGAEngine == SIS_300_VGA ||
- pSiS->VGAEngine == SIS_315_VGA ||
- pSiS->Chipset == PCI_CHIP_SIS530 ||
- pSiS->Chipset == PCI_CHIP_SIS6326 ||
- pSiS->Chipset == PCI_CHIP_SIS5597 ) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n",
+ pSiS->maxxfbmem / 1024);
+
+ /* Find out about sub-classes of some chipsets and check
+ * if the chipset supports two video overlays
+ */
+ if(pSiS->VGAEngine == SIS_300_VGA ||
+ pSiS->VGAEngine == SIS_315_VGA ||
+ pSiS->Chipset == PCI_CHIP_SIS530 ||
+ pSiS->Chipset == PCI_CHIP_SIS6326 ||
+ pSiS->Chipset == PCI_CHIP_SIS5597) {
pSiS->hasTwoOverlays = FALSE;
- switch (pSiS->Chipset) {
+ switch(pSiS->Chipset) {
case PCI_CHIP_SIS300:
case PCI_CHIP_SIS630:
- case PCI_CHIP_SIS550:
- case PCI_CHIP_SIS330: /* ? */
- pSiS->hasTwoOverlays = TRUE;
+ case PCI_CHIP_SIS550:
+ pSiS->hasTwoOverlays = TRUE;
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL;
+ break;
+ case PCI_CHIP_SIS315PRO:
+ pSiS->ChipFlags |= SiSCF_LARGEOVERLAY;
+ break;
+ case PCI_CHIP_SIS330:
+ pSiS->ChipFlags |= SiSCF_LARGEOVERLAY;
+ pSiS->ChipFlags |= SiSCF_CRT2HWCKaputt;
break;
+ case PCI_CHIP_SIS660:
+ {
+#if 0
+ static const char *id661str[] = {
+ "661 ?", "661 ?", "661 ?", "661 ?",
+ "661 ?", "661 ?", "661 ?", "661 ?",
+ "661 ?", "661 ?", "661 ?", "661 ?",
+ "661 ?", "661 ?", "661 ?", "661 ?"
+ };
+#endif
+ pSiS->ChipFlags |= SiSCF_LARGEOVERLAY;
+ pSiS->hasTwoOverlays = TRUE;
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL;
+#if 0
+ if(pSiS->sishw_ext.jChipType == SIS_661) {
+ inSISIDXREG(SISCR, 0x5f, CR5F);
+ CR5F &= 0xf0;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS661FX revision ID %x (%s)\n", CR5F, id661str[CR5F >> 4]);
+ }
+#endif
+ break;
+ }
case PCI_CHIP_SIS650:
{
+ unsigned char tempreg1, tempreg2;
static const char *id650str[] = {
- "0", "0", "0", "0",
- "0 A0 AA", "0 A2 CA", "0", "0",
- "0M A0", "0M A1 AA", "1 A0 AA", "1 A1 AA"
- "0", "0", "0", "0"
+ "650", "650", "650", "650",
+ "650 A0 AA", "650 A2 CA", "650", "650",
+ "M650 A0", "M650 A1 AA","651 A0 AA", "651 A1 AA",
+ "M650", "65?", "651", "65?"
};
- inSISIDXREG(SISCR, 0x5F, CR5F);
- CR5F &= 0xf0;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "SiS650 revision ID %x (SiS65%s)\n", CR5F, id650str[CR5F >> 4]);
- if((CR5F == 0x80) || (CR5F == 0x90) || (CR5F == 0xa0) || (CR5F == 0xb0)) {
- pSiS->hasTwoOverlays = TRUE; /* TW: This is an M650 or 651 */
- pSiS->Flags650 |= SiS650_LARGEOVERLAY;
+ pSiS->ChipFlags |= SiSCF_LARGEOVERLAY;
+ if(pSiS->sishw_ext.jChipType == SIS_650) {
+ inSISIDXREG(SISCR, 0x5f, CR5F);
+ CR5F &= 0xf0;
+ andSISIDXREG(SISCR, 0x5c, 0x07);
+ inSISIDXREG(SISCR, 0x5c, tempreg1);
+ tempreg1 &= 0xf8;
+ orSISIDXREG(SISCR, 0x5c, 0xf8);
+ inSISIDXREG(SISCR, 0x5c, tempreg2);
+ tempreg2 &= 0xf8;
+ if((!tempreg1) || (tempreg2)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS650 revision ID %x (%s)\n", CR5F, id650str[CR5F >> 4]);
+ if(CR5F & 0x80) {
+ pSiS->hasTwoOverlays = TRUE; /* M650 or 651 */
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL;
+ }
+ switch(CR5F) {
+ case 0xa0:
+ case 0xb0:
+ case 0xe0:
+ pSiS->ChipFlags |= SiSCF_Is651;
+ break;
+ case 0x80:
+ case 0x90:
+ case 0xc0:
+ pSiS->ChipFlags |= SiSCF_IsM650;
+ break;
+ }
+ } else {
+ pSiS->hasTwoOverlays = TRUE;
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORT2OVL;
+ switch(CR5F) {
+ case 0x90:
+ inSISIDXREG(SISCR, 0x5c, tempreg1);
+ tempreg1 &= 0xf8;
+ switch(tempreg1) {
+ case 0x00:
+ pSiS->ChipFlags |= SiSCF_IsM652;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiSM652 revision ID %x\n", CR5F);
+ break;
+ case 0x40:
+ pSiS->ChipFlags |= SiSCF_IsM653;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiSM653 revision ID %x\n", CR5F);
+ break;
+ default:
+ pSiS->ChipFlags |= SiSCF_IsM650;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiSM650 revision ID %x\n", CR5F);
+ break;
+ }
+ break;
+ case 0xb0:
+ pSiS->ChipFlags |= SiSCF_Is652;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiS652 revision ID %x\n", CR5F);
+ break;
+ default:
+ pSiS->ChipFlags |= SiSCF_IsM650;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "SiSM650 revision ID %x\n", CR5F);
+ break;
+ }
+ }
}
break;
}
@@ -2528,119 +3745,279 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->hasTwoOverlays ? "s" : "");
}
- /* TW: Backup VB connection and CRT1 on/off register */
+ /* Backup VB connection and CRT1 on/off register */
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
- inSISIDXREG(SISCR, 0x32, pSiS->oldCR32);
- inSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
- pSiS->postVBCR32 = pSiS->oldCR32;
- }
-
- if(pSiS->forceCRT1 != -1) {
- if(pSiS->forceCRT1) pSiS->CRT1off = 0;
- else pSiS->CRT1off = 1;
- } else pSiS->CRT1off = -1;
-
- /* TW: There are some strange machines out there which require a special
- * manupulation of ISA bridge registers in order to make the Chrontel
- * work. Try to find out if we're running on such a machine.
+ inSISIDXREG(SISCR, 0x32, pSiS->oldCR32);
+ inSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
+ inSISIDXREG(SISCR, 0x63, pSiS->oldCR63);
+ inSISIDXREG(SISSR, 0x1f, pSiS->oldSR1F);
+ pSiS->postVBCR32 = pSiS->oldCR32;
+ }
+
+ /* There are some machines out there which require a special
+ * setup of the GPIO registers in order to make the Chrontel
+ * work. Try to find out if we're running on such a machine.
+ * Furthermore, there is some highly customized hardware,
+ * which requires some non-standard LVDS timing. Since the
+ * vendors don't seem to care about PCI subsystem ID's we
+ * need to find out using the BIOS version and date strings.
*/
pSiS->SiS_Pr->SiS_ChSW = FALSE;
if(pSiS->Chipset == PCI_CHIP_SIS630) {
- int i=0;
- do {
- if(mychswtable[i].subsysVendor == pSiS->PciInfo->subsysVendor &&
- mychswtable[i].subsysCard == pSiS->PciInfo->subsysCard) {
+ int i = 0;
+ do {
+ if(mychswtable[i].subsysVendor == pSiS->PciInfo->subsysVendor &&
+ mychswtable[i].subsysCard == pSiS->PciInfo->subsysCard) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PCI subsystem ID found in list for Chrontel/GPIO setup\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Vendor/Card: %s %s (ID %04x)\n",
+ mychswtable[i].vendorName,
+ mychswtable[i].cardName,
+ pSiS->PciInfo->subsysCard);
+ pSiS->SiS_Pr->SiS_ChSW = TRUE;
+ break;
+ }
+ i++;
+ } while(mychswtable[i].subsysVendor != 0);
+ }
+
+ if(pSiS->SiS_Pr->SiS_CustomT == CUT_NONE) {
+ int i = 0, j;
+ unsigned short bversptr = 0;
+ BOOLEAN footprint;
+ unsigned long chksum = 0;
+
+ if(pSiS->sishw_ext.UseROM) {
+ bversptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8);
+ for(i=0; i<32768; i++) chksum += pSiS->BIOS[i];
+ }
+
+ i = 0;
+ do {
+ if( (mycustomttable[i].chipID == pSiS->sishw_ext.jChipType) &&
+ ((!strlen(mycustomttable[i].biosversion)) ||
+ (pSiS->sishw_ext.UseROM &&
+ (!strncmp(mycustomttable[i].biosversion, (char *)&pSiS->BIOS[bversptr],
+ strlen(mycustomttable[i].biosversion))))) &&
+ ((!strlen(mycustomttable[i].biosdate)) ||
+ (pSiS->sishw_ext.UseROM &&
+ (!strncmp(mycustomttable[i].biosdate, (char *)&pSiS->BIOS[0x2c],
+ strlen(mycustomttable[i].biosdate))))) &&
+ ((!mycustomttable[i].bioschksum) ||
+ (pSiS->sishw_ext.UseROM &&
+ (mycustomttable[i].bioschksum == chksum))) &&
+ (mycustomttable[i].pcisubsysvendor == pSiS->PciInfo->subsysVendor) &&
+ (mycustomttable[i].pcisubsyscard == pSiS->PciInfo->subsysCard) ) {
+ footprint = TRUE;
+ for(j=0; j<5; j++) {
+ if(mycustomttable[i].biosFootprintAddr[j]) {
+ if(pSiS->sishw_ext.UseROM) {
+ if(pSiS->BIOS[mycustomttable[i].biosFootprintAddr[j]] !=
+ mycustomttable[i].biosFootprintData[j])
+ footprint = FALSE;
+ } else footprint = FALSE;
+ }
+ }
+ if(footprint) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "PCI card/vendor found in list for Chrontel/ISA bridge poking\n");
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Vendor: %s (ID %04x)\n",
- mychswtable[i].vendorName, pSiS->PciInfo->subsysCard);
- pSiS->SiS_Pr->SiS_ChSW = TRUE;
- }
- i++;
- } while(mychswtable[i].subsysVendor != 0);
+ "Identified %s %s, special timing applies\n",
+ mycustomttable[i].vendorName, mycustomttable[i].cardName);
+ pSiS->SiS_Pr->SiS_CustomT = mycustomttable[i].SpecialID;
+ break;
+ }
+ }
+ i++;
+ } while(mycustomttable[i].chipID);
}
- /* TW: Detect video bridge and sense connected devices */
+ /* Handle ForceCRT1 option */
+ if(pSiS->forceCRT1 != -1) {
+ if(pSiS->forceCRT1) pSiS->CRT1off = 0;
+ else pSiS->CRT1off = 1;
+ } else pSiS->CRT1off = -1;
+
+ /* Detect video bridge and sense TV/VGA2 */
SISVGAPreInit(pScrn);
- /* TW: Detect CRT1 */
+
+ /* Detect CRT1 (via DDC1 and DDC2, hence via VGA port; regardless of LCDA) */
SISCRT1PreInit(pScrn);
- /* TW: Detect CRT2-LCD and LCD size */
+
+ /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */
SISLCDPreInit(pScrn);
- /* TW: Detect CRT2-TV and PAL/NTSC mode */
+
+ /* LCDA only supported under these conditions: */
+ if(pSiS->ForceCRT1Type == CRT1_LCDA) {
+ if( ((pSiS->sishw_ext.jChipType != SIS_650) &&
+ (pSiS->sishw_ext.jChipType < SIS_661)) ||
+ (!(pSiS->VBFlags & (VB_301C | VB_302B | VB_301LV | VB_302LV))) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Chipset/Video bridge does not support LCD-via-CRT1\n");
+ pSiS->ForceCRT1Type = CRT1_VGA;
+ } else if(!(pSiS->VBFlags & CRT2_LCD)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No digitally connected LCD panel found, LCD-via-CRT1 disabled\n");
+ pSiS->ForceCRT1Type = CRT1_VGA;
+ } else if(!(pSiS->VBLCDFlags & (VB_LCD_1024x768|VB_LCD_1280x1024|VB_LCD_1400x1050|VB_LCD_1600x1200))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "LCD-via-CRT1 not supported for this LCD resolution\n");
+ pSiS->ForceCRT1Type = CRT1_VGA;
+ }
+ }
+
+ /* Detect CRT2-TV and PAL/NTSC mode */
SISTVPreInit(pScrn);
- /* TW: Detect CRT2-VGA */
+
+ /* Detect CRT2-VGA */
SISCRT2PreInit(pScrn);
- /* TW: Backup detected CRT2 devices */
- pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD | CRT2_TV | CRT2_VGA);
+ /* Backup detected CRT2 devices */
+ pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD | CRT2_TV | CRT2_VGA | TV_AVIDEO | TV_SVIDEO | TV_SCART);
+
+ /* Setup SD flags */
+ pSiS->SiS_SD_Flags |= SiS_SD_ADDLSUPFLAG;
+
+ if(pSiS->VBFlags & (VB_SISTVBRIDGE | VB_CHRONTEL)) {
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTTV;
+ }
+
+ if((pSiS->VBFlags & VB_SISTVBRIDGE) ||
+ ((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_701x))) {
+ pSiS->SiS_SD_Flags |= (SiS_SD_SUPPORTPALMN | SiS_SD_SUPPORTNTSCJ);
+ }
+ if((pSiS->VBFlags & VB_SISTVBRIDGE) ||
+ ((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_700x))) {
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTTVPOS;
+ }
+ if(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) {
+ pSiS->SiS_SD_Flags |= (SiS_SD_SUPPORTSCART | SiS_SD_SUPPORTVGA2);
+ }
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTOVERSCAN;
+ if(pSiS->ChrontelType == CHRONTEL_700x) {
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTSOVER;
+ }
+ }
+
+ if( ((pSiS->sishw_ext.jChipType == SIS_650) ||
+ (pSiS->sishw_ext.jChipType >= SIS_661)) &&
+ (pSiS->VBFlags & (VB_301C | VB_302B | VB_301LV | VB_302LV)) &&
+ (pSiS->VBFlags & CRT2_LCD) &&
+ (pSiS->VBLCDFlags & (VB_LCD_1024x768|VB_LCD_1280x1024|VB_LCD_1400x1050|VB_LCD_1600x1200)) &&
+ (pSiS->VESA != 1) ) {
+ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTLCDA;
+ } else {
+ /* Paranoia */
+ pSiS->ForceCRT1Type = CRT1_VGA;
+ }
+
+ pSiS->VBFlags |= pSiS->ForceCRT1Type;
- /* TW: Eventually overrule detected CRT2 type */
+ /* Eventually overrule detected CRT2 type
+ * If no type forced, use the detected devices in the order VGA2->TV->LCD
+ * Since the Chrontel 7005 sometimes delivers wrong detection results,
+ * we use a different order on such machines (LCD->TV)
+ */
if(pSiS->ForceCRT2Type == CRT2_DEFAULT) {
- if(pSiS->VBFlags & CRT2_VGA)
- pSiS->ForceCRT2Type = CRT2_VGA;
- else if(pSiS->VBFlags & CRT2_LCD)
- pSiS->ForceCRT2Type = CRT2_LCD;
- else if(pSiS->VBFlags & CRT2_TV)
- pSiS->ForceCRT2Type = CRT2_TV;
+ if(pSiS->VBFlags & CRT2_VGA)
+ pSiS->ForceCRT2Type = CRT2_VGA;
+ else if((pSiS->VBFlags & CRT2_TV) && (!((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->VGAEngine == SIS_300_VGA))))
+ pSiS->ForceCRT2Type = CRT2_TV;
+ else if((pSiS->VBFlags & CRT2_LCD) && (pSiS->ForceCRT1Type == CRT1_VGA))
+ pSiS->ForceCRT2Type = CRT2_LCD;
+ else if(pSiS->VBFlags & CRT2_TV)
+ pSiS->ForceCRT2Type = CRT2_TV;
}
switch(pSiS->ForceCRT2Type) {
- case CRT2_TV:
- pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_LCD | CRT2_VGA);
- if(pSiS->VBFlags & VB_VIDEOBRIDGE)
- pSiS->VBFlags = pSiS->VBFlags | CRT2_TV;
- else
- pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV);
- break;
- case CRT2_LCD:
- pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV | CRT2_VGA);
- if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (pSiS->VBLCDFlags))
- pSiS->VBFlags = pSiS->VBFlags | CRT2_LCD;
- else {
- pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_LCD);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Can't force CRT2 to LCD, no panel detected\n");
- }
- break;
- case CRT2_VGA:
- if(pSiS->VBFlags & VB_LVDS) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "LVDS does not support secondary VGA\n");
- break;
- }
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiS30xLV bridge does not support secondary VGA\n");
- break;
- }
- pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_TV | CRT2_LCD);
- if(pSiS->VBFlags & VB_VIDEOBRIDGE)
- pSiS->VBFlags = pSiS->VBFlags | CRT2_VGA;
- else
- pSiS->VBFlags = pSiS->VBFlags & ~(CRT2_VGA);
- break;
- default:
- pSiS->VBFlags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
+ case CRT2_TV:
+ pSiS->VBFlags &= ~(CRT2_LCD | CRT2_VGA);
+ if(pSiS->VBFlags & (VB_SISTVBRIDGE | VB_CHRONTEL))
+ pSiS->VBFlags |= CRT2_TV;
+ else {
+ pSiS->VBFlags &= ~(CRT2_TV);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware does not support TV output\n");
+ }
+ break;
+ case CRT2_LCD:
+ pSiS->VBFlags &= ~(CRT2_TV | CRT2_VGA);
+ if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (pSiS->VBLCDFlags))
+ pSiS->VBFlags |= CRT2_LCD;
+ else {
+ pSiS->VBFlags &= ~(CRT2_LCD);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't force CRT2 to LCD, no LCD detected\n");
+ }
+ break;
+ case CRT2_VGA:
+ pSiS->VBFlags &= ~(CRT2_TV | CRT2_LCD);
+ if(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))
+ pSiS->VBFlags |= CRT2_VGA;
+ else {
+ pSiS->VBFlags &= ~(CRT2_VGA);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware does not support secondary VGA\n");
+ }
+ break;
+ default:
+ pSiS->VBFlags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
}
- /* TW: Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART) */
- if(pSiS->ForceTVType != -1) {
- if(pSiS->VBFlags & VB_SISBRIDGE) {
- pSiS->VBFlags &= ~(TV_INTERFACE);
- pSiS->VBFlags |= pSiS->ForceTVType;
- }
+#ifdef SISDUALHEAD
+ if((!pSiS->DualHeadMode) || (pSiS->SecondHead)) {
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, pSiS->CRT1gammaGiven ? X_CONFIG : X_INFO,
+ "CRT1 gamma correction is %s\n",
+ pSiS->CRT1gamma ? "enabled" : "disabled");
+
+ if((pSiS->VGAEngine == SIS_315_VGA) && (!(pSiS->NoXvideo))) {
+ xf86DrvMsg(pScrn->scrnIndex, pSiS->XvGammaGiven ? X_CONFIG : X_INFO,
+ "Separate Xv gamma correction for CRT1 is %s\n",
+ pSiS->XvGamma ? "enabled" : "disabled");
+ if(pSiS->XvGamma) {
+ xf86DrvMsg(pScrn->scrnIndex, pSiS->XvGammaGiven ? X_CONFIG : X_INFO,
+ "Xv gamma correction: %.3f %.3f %.3f\n",
+ (float)((float)pSiS->XvGammaRed / 1000),
+ (float)((float)pSiS->XvGammaGreen / 1000),
+ (float)((float)pSiS->XvGammaBlue / 1000));
+ if(!pSiS->CRT1gamma) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Separate Xv gamma corr. only effective if CRT1 gamma corr. is enabled\n");
+ }
+ }
+ }
+#ifdef SISDUALHEAD
+ }
+#endif
+
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if( (pSiS->VBFlags & VB_SISBRIDGE) &&
+ (!((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD))) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT2 gamma correction is %s\n",
+ pSiS->CRT2gamma ? "enabled" : "disabled");
+ }
}
- /* TW: Handle ForceCRT1 option */
+ /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART) */
+ if(pSiS->VBFlags & VB_SISTVBRIDGE) {
+ if(pSiS->ForceTVType != -1) {
+ pSiS->VBFlags &= ~(TV_INTERFACE);
+ pSiS->VBFlags |= pSiS->ForceTVType;
+ }
+ }
+
+ /* Handle ForceCRT1 option (part 2) */
pSiS->CRT1changed = FALSE;
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
usScratchCR17 = pSiS->oldCR17;
+ usScratchCR63 = pSiS->oldCR63;
+ usScratchSR1F = pSiS->oldSR1F;
usScratchCR32 = pSiS->postVBCR32;
if(pSiS->VESA != 1) {
- /* TW: Copy forceCRT1 option to CRT1off if option is given */
+ /* Copy forceCRT1 option to CRT1off if option is given */
#ifdef SISDUALHEAD
- /* TW: In DHM, handle this option only for master head, not the slave */
+ /* In DHM, handle this option only for master head, not the slave */
if( (pSiS->forceCRT1 != -1) &&
(!(pSiS->DualHeadMode && pSiS->SecondHead)) ) {
#else
@@ -2650,20 +4027,36 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
"CRT1 detection overruled by ForceCRT1 option\n");
if(pSiS->forceCRT1) {
pSiS->CRT1off = 0;
- if (!(usScratchCR17 & 0x80)) pSiS->CRT1changed = TRUE;
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(!(usScratchCR17 & 0x80)) pSiS->CRT1changed = TRUE;
+ } else {
+ if(usScratchCR63 & 0x40) pSiS->CRT1changed = TRUE;
+ }
usScratchCR17 |= 0x80;
usScratchCR32 |= 0x20;
+ usScratchCR63 &= ~0x40;
+ usScratchSR1F &= ~0xc0;
} else {
if( ! ( (pScrn->bitsPerPixel == 8) &&
- ( (pSiS->VBFlags & VB_LVDS) ||
- ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) {
+ ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) ||
+ ((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD)) ) ) ) {
pSiS->CRT1off = 1;
- if (usScratchCR17 & 0x80) pSiS->CRT1changed = TRUE;
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(usScratchCR17 & 0x80) pSiS->CRT1changed = TRUE;
+ } else {
+ if(!(usScratchCR63 & 0x40)) pSiS->CRT1changed = TRUE;
+ }
usScratchCR32 &= ~0x20;
- /* TW: We must not actually switch off CRT1 before we changed the mode! */
+ /* We must not actually switch off CRT1 before we changed the mode! */
}
}
+ /* Here we can write to CR17 even on 315 series as we only ENABLE
+ * the bit here
+ */
outSISIDXREG(SISCR, 0x17, usScratchCR17);
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ outSISIDXREG(SISCR, 0x63, usScratchCR63);
+ }
outSISIDXREG(SISCR, 0x32, usScratchCR32);
if(pSiS->CRT1changed) {
outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
@@ -2672,29 +4065,30 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"CRT1 status changed by ForceCRT1 option\n");
}
+ outSISIDXREG(SISSR, 0x1f, usScratchSR1F);
}
}
- /* TW: Store the new VB connection register contents for later mode changes */
+ /* Store the new VB connection register contents for later mode changes */
pSiS->newCR32 = usScratchCR32;
}
- /* TW: Check if CRT1 used (or needed; this eg. if no CRT2 detected) */
- if (pSiS->VBFlags & VB_VIDEOBRIDGE) {
-
- /* TW: No CRT2 output? Then we NEED CRT1!
- * We also need CRT1 if depth = 8 and bridge=LVDS|630+301B
+ /* Check if CRT1 used (or needed; this eg. if no CRT2 detected) */
+ if(pSiS->VBFlags & VB_VIDEOBRIDGE) {
+
+ /* No CRT2 output? Then we NEED CRT1!
+ * We also need CRT1 if depth = 8 and bridge=LVDS|301B-DH
*/
- if ( (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) ||
- ( (pScrn->bitsPerPixel == 8) &&
- ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) ||
- ((pSiS->VGAEngine == SIS_300_VGA) && (pSiS->VBFlags & VB_301B)) ) ) ) {
+ if( (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) ||
+ ( (pScrn->bitsPerPixel == 8) &&
+ ( (pSiS->VBFlags & (VB_LVDS | VB_CHRONTEL)) ||
+ ((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD)) ) ) ) {
pSiS->CRT1off = 0;
}
- /* TW: No CRT2 output? Then we can't use Xv on CRT2 */
- if (!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)))
+ /* No CRT2 output? Then we can't use Xv on CRT2 */
+ if(!(pSiS->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)))
pSiS->XvOnCRT2 = FALSE;
- } else { /* TW: no video bridge? */
+ } else { /* no video bridge? */
/* Then we NEED CRT1... */
pSiS->CRT1off = 0;
@@ -2702,86 +4096,146 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->XvOnCRT2 = FALSE;
}
- /* TW: Handle TVStandard option */
- if(pSiS->NonDefaultPAL != -1) {
- if( (!(pSiS->VBFlags & VB_SISBRIDGE)) &&
- (!((pSiS->VBFlags & VB_CHRONTEL)) && (pSiS->ChrontelType == CHRONTEL_701x)) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "PALM and PALN only supported on Chrontel 701x and SiS30x/B/LV\n");
- pSiS->NonDefaultPAL = -1;
- pSiS->VBFlags &= ~(TV_PALN | TV_PALM);
- }
- }
- if(pSiS->NonDefaultPAL != -1) {
- if((pSiS->Chipset == PCI_CHIP_SIS300) || (pSiS->Chipset == PCI_CHIP_SIS540)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "PALM and PALN not supported on SiS300 and SiS540\n");
- pSiS->NonDefaultPAL = -1;
- pSiS->VBFlags &= ~(TV_PALN | TV_PALM);
- }
+ /* LCDA? Then we don't switch off CRT1 */
+ if(pSiS->VBFlags & CRT1_LCDA) pSiS->CRT1off = 0;
+
+ /* Handle TVStandard option */
+ if((pSiS->NonDefaultPAL != -1) || (pSiS->NonDefaultNTSC != -1)) {
+ if( (!(pSiS->VBFlags & VB_SISTVBRIDGE)) &&
+ (!((pSiS->VBFlags & VB_CHRONTEL)) && (pSiS->ChrontelType == CHRONTEL_701x)) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PALM, PALN and NTSCJ not supported on this hardware\n");
+ pSiS->NonDefaultPAL = pSiS->NonDefaultNTSC = -1;
+ pSiS->VBFlags &= ~(TV_PALN | TV_PALM | TV_NTSCJ);
+ pSiS->SiS_SD_Flags &= ~(SiS_SD_SUPPORTPALMN | SiS_SD_SUPPORTNTSCJ);
+ }
}
if(pSiS->OptTVStand != -1) {
- if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
- if(!(pSiS->Flags & (TV_CHSCART | TV_CHHDTV))) {
- pSiS->VBFlags &= ~(TV_PAL | TV_NTSC | TV_PALN | TV_PALM);
- if(pSiS->OptTVStand) pSiS->VBFlags |= TV_PAL;
- else pSiS->VBFlags |= TV_NTSC;
- if(pSiS->NonDefaultPAL == 1) pSiS->VBFlags |= TV_PALM;
- else if(!pSiS->NonDefaultPAL) pSiS->VBFlags |= TV_PALN;
- } else {
- pSiS->OptTVStand = pSiS->NonDefaultPAL = -1;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Option TVStandard ignored for SCART and 480i HDTV\n");
- }
- } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
- pSiS->SiS6326Flags &= ~SIS6326_TVPAL;
- if(pSiS->OptTVStand) pSiS->SiS6326Flags |= SIS6326_TVPAL;
- }
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if(!(pSiS->VBFlags & (TV_CHSCART | TV_CHHDTV))) {
+ pSiS->VBFlags &= ~(TV_PAL | TV_NTSC | TV_PALN | TV_PALM | TV_NTSCJ);
+ if(pSiS->OptTVStand) {
+ pSiS->VBFlags |= TV_PAL;
+ if(pSiS->NonDefaultPAL == 1) pSiS->VBFlags |= TV_PALM;
+ else if(!pSiS->NonDefaultPAL) pSiS->VBFlags |= TV_PALN;
+ } else {
+ pSiS->VBFlags |= TV_NTSC;
+ if(pSiS->NonDefaultNTSC == 1) pSiS->VBFlags |= TV_NTSCJ;
+ }
+ } else {
+ pSiS->OptTVStand = pSiS->NonDefaultPAL = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Option TVStandard ignored for SCART and 480i HDTV\n");
+ }
+ } else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
+ pSiS->SiS6326Flags &= ~SIS6326_TVPAL;
+ if(pSiS->OptTVStand) pSiS->SiS6326Flags |= SIS6326_TVPAL;
+ }
+ }
+
+ /* SCART only supported for PAL */
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if((pSiS->VBFlags & VB_SISBRIDGE) && (pSiS->VBFlags & TV_SCART)) {
+ pSiS->VBFlags &= ~(TV_NTSC | TV_PALN | TV_PALM | TV_NTSCJ);
+ pSiS->VBFlags |= TV_PAL;
+ pSiS->OptTVStand = 1;
+ pSiS->NonDefaultPAL = pSiS->NonDefaultNTSC = -1;
+ }
}
- /* TW: Do some checks */
+#ifdef SIS_CP
+ SIS_CP_DRIVER_RECONFIGOPT
+#endif
+
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ if(pSiS->sis6326tvplug != -1) {
+ pSiS->SiS6326Flags &= ~(SIS6326_TVSVIDEO | SIS6326_TVCVBS);
+ pSiS->SiS6326Flags |= SIS6326_TVDETECTED;
+ if(pSiS->sis6326tvplug == 1) pSiS->SiS6326Flags |= SIS6326_TVCVBS;
+ else pSiS->SiS6326Flags |= SIS6326_TVSVIDEO;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "SiS6326 TV plug type detection overruled by %s\n",
+ (pSiS->SiS6326Flags & SIS6326_TVCVBS) ? "COMPOSITE" : "SVIDEO");
+ }
+ }
+
+ /* Do some checks */
if(pSiS->OptTVOver != -1) {
- if(pSiS->VBFlags & VB_CHRONTEL) {
- pSiS->UseCHOverScan = pSiS->OptTVOver;
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "CHTVOverscan option only supported on CHRONTEL 70xx\n");
- pSiS->UseCHOverScan = -1;
- }
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ pSiS->UseCHOverScan = pSiS->OptTVOver;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "CHTVOverscan only supported on CHRONTEL 70xx\n");
+ pSiS->UseCHOverScan = -1;
+ }
} else pSiS->UseCHOverScan = -1;
-
+
if(pSiS->sistvedgeenhance != -1) {
- if(!(pSiS->VBFlags & VB_301)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "SISTVEdgeEnhance option only supported on SiS301\n");
- pSiS->sistvedgeenhance = -1;
- }
+ if(!(pSiS->VBFlags & VB_301)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SISTVEdgeEnhance only supported on SiS301\n");
+ pSiS->sistvedgeenhance = -1;
+ }
+ }
+ if(pSiS->sistvsaturation != -1) {
+ if(pSiS->VBFlags & VB_301) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "SISTVSaturation not supported on SiS301\n");
+ pSiS->sistvsaturation = -1;
+ }
+ }
+
+ /* Do some MergedFB mode initialisation */
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ pSiS->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
+ if(!pSiS->CRT2pScrn) {
+ SISErrorLog(pScrn, "Failed to allocate memory for 2nd pScrn, %s\n", mergeddisstr);
+ pSiS->MergedFB = FALSE;
+ } else {
+ memcpy(pSiS->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
+ }
}
+#endif
+
- /* TW: Determine CRT1<>CRT2 mode
+ /* Determine CRT1<>CRT2 mode
* Note: When using VESA or if the bridge is in slavemode, display
* is ALWAYS in MIRROR_MODE!
* This requires extra checks in functions using this flag!
* (see sis_video.c for example)
*/
if(pSiS->VBFlags & DISPTYPE_DISP2) {
- if(pSiS->CRT1off) { /* TW: CRT2 only ------------------------------- */
+ if(pSiS->CRT1off) { /* CRT2 only ------------------------------- */
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ SISErrorLog(pScrn,
"CRT1 not detected or forced off. Dual Head mode can't initialize.\n");
if(pSiSEnt) pSiSEnt->DisableDual = TRUE;
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ pSiS->pInt = NULL;
sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
SISFreeRec(pScrn);
return FALSE;
}
#endif
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ if(pSiS->MergedFBAuto) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt1, mergeddisstr);
+ } else {
+ SISErrorLog(pScrn, mergednocrt1, mergeddisstr);
+ }
+ if(pSiS->CRT2pScrn) xfree(pSiS->CRT2pScrn);
+ pSiS->CRT2pScrn = NULL;
+ pSiS->MergedFB = FALSE;
+ }
+#endif
pSiS->VBFlags |= VB_DISPMODE_SINGLE;
- /* TW: No CRT1? Then we use the video overlay on CRT2 */
+ /* No CRT1? Then we use the video overlay on CRT2 */
pSiS->XvOnCRT2 = TRUE;
- } else /* TW: CRT1 and CRT2 - mirror or dual head ----- */
+ } else /* CRT1 and CRT2 - mirror or dual head ----- */
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
pSiS->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1);
@@ -2789,73 +4243,94 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"VESA option not used in Dual Head mode. VESA disabled.\n");
}
- if (pSiSEnt) pSiSEnt->DisableDual = FALSE;
+ if(pSiSEnt) pSiSEnt->DisableDual = FALSE;
pSiS->VESA = 0;
} else
#endif
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
+ if(pSiS->VESA != -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "VESA option not used in MergedFB mode. VESA disabled.\n");
+ }
+ pSiS->VESA = 0;
+ } else
+#endif
pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
- } else { /* TW: CRT1 only ------------------------------- */
+ } else { /* CRT1 only ------------------------------- */
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ SISErrorLog(pScrn,
"No CRT2 output selected or no bridge detected. "
"Dual Head mode can't initialize.\n");
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ pSiS->pInt = NULL;
sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
SISFreeRec(pScrn);
return FALSE;
}
#endif
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ if(pSiS->MergedFBAuto) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt2, mergeddisstr);
+ } else {
+ SISErrorLog(pScrn, mergednocrt2, mergeddisstr);
+ }
+ if(pSiS->CRT2pScrn) xfree(pSiS->CRT2pScrn);
+ pSiS->CRT2pScrn = NULL;
+ pSiS->MergedFB = FALSE;
+ }
+#endif
pSiS->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
}
- if( (pSiS->VGAEngine == SIS_315_VGA) ||
- (pSiS->VGAEngine == SIS_300_VGA) ) {
- if ( (!pSiS->NoXvideo) &&
- (!pSiS->hasTwoOverlays) ) {
- xf86DrvMsg(pScrn->scrnIndex, from,
- "Using Xv overlay on CRT%d\n",
- pSiS->XvOnCRT2 ? 2 : 1);
+ if((pSiS->VGAEngine == SIS_315_VGA) ||
+ (pSiS->VGAEngine == SIS_300_VGA) ) {
+ if((!pSiS->NoXvideo) && (!pSiS->hasTwoOverlays)) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Using Xv overlay by default on CRT%d\n",
+ pSiS->XvOnCRT2 ? 2 : 1);
}
}
- /* TW: Init Ptrs for Save/Restore functions and calc MaxClock */
+ /* Init Ptrs for Save/Restore functions and calc MaxClock */
SISDACPreInit(pScrn);
/* ********** end of VBFlags setup ********** */
- /* TW: VBFlags are initialized now. Back them up for SlaveMode modes. */
+ /* VBFlags are initialized now. Back them up for SlaveMode modes. */
pSiS->VBFlags_backup = pSiS->VBFlags;
- /* TW: Find out about paneldelaycompensation and evaluate option */
+ /* Find out about paneldelaycompensation and evaluate option */
pSiS->sishw_ext.pdc = 0;
if(pSiS->VGAEngine == SIS_300_VGA) {
-
- if(pSiS->VBFlags & (VB_LVDS | VB_301B | VB_302B)) {
- /* TW: Save the current PDC if the panel is used at the moment.
- * This seems by far the safest way to find out about it.
- * If the system is using an old version of sisfb, we can't
- * trust the pdc register value. If sisfb saved the pdc for
- * us, use it.
+ if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) {
+ /* Save the current PDC if the panel is used at the moment.
+ * This seems by far the safest way to find out about it.
+ * If the system is using an old version of sisfb, we can't
+ * trust the pdc register value. If sisfb saved the pdc for
+ * us, use it.
*/
if(pSiS->sisfbpdc) {
pSiS->sishw_ext.pdc = pSiS->sisfbpdc;
} else {
- if(!(pSiS->donttrustpdc)) {
- unsigned char tmp;
- inSISIDXREG(SISCR, 0x30, tmp);
- if(tmp & 0x20) {
- inSISIDXREG(SISPART1, 0x13, pSiS->sishw_ext.pdc);
- } else {
+ if(!(pSiS->donttrustpdc)) {
+ unsigned char tmp;
+ inSISIDXREG(SISCR, 0x30, tmp);
+ if(tmp & 0x20) {
+ inSISIDXREG(SISPART1, 0x13, pSiS->sishw_ext.pdc);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unable to detect LCD PanelDelayCompensation, LCD is not active\n");
+ }
+ } else {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Unable to detect LCD PanelDelayCompensation, LCD is not active\n");
- }
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Unable to detect LCD PanelDelayCompensation, please update sisfb\n");
- }
+ "Unable to detect LCD PanelDelayCompensation, please update sisfb\n");
+ }
}
pSiS->sishw_ext.pdc &= 0x3c;
if(pSiS->sishw_ext.pdc) {
@@ -2872,7 +4347,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(mypdctable[i].subsysVendor == pSiS->PciInfo->subsysVendor &&
mypdctable[i].subsysCard == pSiS->PciInfo->subsysCard) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "PCI card/vendor found in list for non-default PanelDelayCompensation\n");
+ "PCI card/vendor identified for non-default PanelDelayCompensation\n");
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Vendor: %s, card: %s (ID %04x), PanelDelayCompensation: %d\n",
mypdctable[i].vendorName, mypdctable[i].cardName,
@@ -2917,14 +4392,61 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
}
}
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ if(pSiS->VBFlags & (VB_301LV | VB_302LV | VB_302ELV)) {
+ /* Save the current PDC if the panel is used at the moment.
+ * This seems by far the safest way to find out about it.
+ */
+ if(pSiS->sisfbpdc) {
+ pSiS->sishw_ext.pdc = pSiS->sisfbpdc;
+ } else {
+ if(!(pSiS->donttrustpdc)) {
+ unsigned char tmp;
+ inSISIDXREG(SISCR, 0x30, tmp);
+ if(tmp & 0x20) {
+ inSISIDXREG(SISPART1, 0x2D, pSiS->sishw_ext.pdc);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unable to detect LCD PanelDelayCompensation, LCD is not active\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unable to detect LCD PanelDelayCompensation, please update sisfb\n");
+ }
+ }
+ if(pSiS->sishw_ext.pdc) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected LCD PanelDelayCompensation %d\n",
+ pSiS->sishw_ext.pdc);
+ }
+ if(pSiS->PDC != -1) {
+ pSiS->sishw_ext.pdc = pSiS->PDC & 0xff;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using LCD PanelDelayCompensation %d\n",
+ pSiS->sishw_ext.pdc);
+ }
+ } else if(pSiS->Chipset == PCI_CHIP_SIS660) {
+ /* Since I have no idea about the required PDC on
+ * the new chips, let the user specify one. But
+ * we only use the lower nibble.
+ */
+ if(pSiS->PDC != -1) {
+ pSiS->sishw_ext.pdc = pSiS->PDC & 0x0f;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using LCD PanelDelayCompensation %d\n",
+ pSiS->sishw_ext.pdc);
+ }
+ }
+ }
+
#ifdef SISDUALHEAD
- /* TW: In dual head mode, both heads (currently) share the maxxfbmem equally.
- * If memory sharing is done differently, the following has to be changed;
- * the other modules (eg. accel and Xv) use dhmOffset for hardware
- * pointer settings relative to VideoRAM start and won't need to be changed.
+ /* In dual head mode, both heads (currently) share the maxxfbmem equally.
+ * If memory sharing is done differently, the following has to be changed;
+ * the other modules (eg. accel and Xv) use dhmOffset for hardware
+ * pointer settings relative to VideoRAM start and won't need to be changed.
*/
- if (pSiS->DualHeadMode) {
- if (pSiS->SecondHead == FALSE) {
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead == FALSE) {
/* ===== First head (always CRT2) ===== */
/* We use only half of the memory available */
pSiS->maxxfbmem /= 2;
@@ -2936,7 +4458,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiSEnt->slaveFbAddress = pSiS->FbAddress + pSiS->maxxfbmem;
pSiSEnt->slaveFbSize = pSiS->maxxfbmem;
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "%dKB video RAM at 0x%lx available for master head (CRT2)\n",
+ "%ldKB video RAM at 0x%lx available for master head (CRT2)\n",
pSiS->maxxfbmem/1024, pSiS->FbAddress);
} else {
/* ===== Second head (always CRT1) ===== */
@@ -2947,62 +4469,80 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Initialize dhmOffset */
pSiS->dhmOffset = pSiS->availMem - pSiS->maxxfbmem;
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "%dKB video RAM at 0x%lx available for slave head (CRT1)\n",
+ "%ldKB video RAM at 0x%lx available for slave head (CRT1)\n",
pSiS->maxxfbmem/1024, pSiS->FbAddress);
}
} else
pSiS->dhmOffset = 0;
#endif
- /* TW: Note: Do not use availMem for anything from now. Use
- * maxxfbmem instead. (availMem does not take dual head
- * mode into account.)
+ /* Note: Do not use availMem for anything from now. Use
+ * maxxfbmem instead. (availMem does not take dual head
+ * mode into account.)
*/
- /* TW: Now for something completely different: DDC.
- For 300 and 310/325 series, we provide our
- own functions (in order to probe CRT2 as well)
- If these fail, use the VBE.
- All other chipsets will use VBE. No need to re-invent
- the wheel there.
+ pSiS->DRIheapstart = pSiS->maxxfbmem;
+ pSiS->DRIheapend = pSiS->availMem;
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiS->DRIheapstart = pSiS->DRIheapend = 0;
+ } else
+#endif
+ if(pSiS->DRIheapstart == pSiS->DRIheapend) {
+#if 0 /* For future use */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "No memory for DRI heap. Please set the option \"MaxXFBMem\" to\n"
+ "\tlimit the memory XFree should use and leave the rest to DRI\n");
+#endif
+ pSiS->DRIheapstart = pSiS->DRIheapend = 0;
+ }
+
+ /* Now for something completely different: DDC.
+ * For 300 and 315/330 series, we provide our
+ * own functions (in order to probe CRT2 as well)
+ * If these fail, use the VBE.
+ * All other chipsets will use VBE. No need to re-invent
+ * the wheel there.
*/
pSiS->pVbe = NULL;
didddc2 = FALSE;
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
- if(xf86LoadSubModule(pScrn, "ddc")) {
+ if(xf86LoadSubModule(pScrn, "ddc")) {
+ int crtnum = 0;
xf86LoaderReqSymLists(ddcSymbols, NULL);
- if((pMonitor = SiSDoPrivateDDC(pScrn))) {
+ if((pMonitor = SiSDoPrivateDDC(pScrn, &crtnum))) {
didddc2 = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "DDC monitor info:\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, crtnum);
xf86PrintEDID(pMonitor);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "End of DDC monitor info\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, crtnum);
xf86SetDDCproperties(pScrn, pMonitor);
pScrn->monitor->DDC = pMonitor;
}
- }
+ }
}
#ifdef SISDUALHEAD
- /* TW: In dual head mode, probe DDC using VBE only for CRT1 (second head) */
+ /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */
if((pSiS->DualHeadMode) && (!didddc2) && (!pSiS->SecondHead))
didddc2 = TRUE;
#endif
- /* TW: If CRT1 is off (eventually forced), skip DDC */
- if((!didddc2) && (pSiS->CRT1off)) didddc2 = TRUE;
+ if(!didddc2) {
+ /* If CRT1 is off or LCDA, skip DDC via VBE */
+ if((pSiS->CRT1off) || (pSiS->VBFlags & CRT1_LCDA))
+ didddc2 = TRUE;
+ }
- /* TW: Now (re-)load and initialize the DDC module */
+ /* Now (re-)load and initialize the DDC module */
if(!didddc2) {
if(xf86LoadSubModule(pScrn, "ddc")) {
xf86LoaderReqSymLists(ddcSymbols, NULL);
- /* TW: Now load and initialize VBE module. */
+ /* Now load and initialize VBE module. */
if(xf86LoadSubModule(pScrn, "vbe")) {
xf86LoaderReqSymLists(vbeSymbols, NULL);
#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
@@ -3023,10 +4563,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(pSiS->pVbe) {
if((pMonitor = vbeDoEDID(pSiS->pVbe,NULL))) {
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "VBE DDC monitor info:\n");
+ "VBE CRT1 DDC monitor info:\n");
xf86SetDDCproperties(pScrn, xf86PrintEDID(pMonitor));
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "End of VBE DDC monitor info:\n");
+ "End of VBE CRT1 DDC monitor info:\n");
pScrn->monitor->DDC = pMonitor;
}
} else {
@@ -3036,16 +4576,118 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
}
}
-#if 0 /* TW: DDC1 obviously no longer supported by SiS chipsets */
- if (!ret && pSiS->ddc1Read)
- xf86SetDDCproperties(pScrn, xf86PrintEDID(xf86DoEDID_DDC1(
- pScrn->scrnIndex,vgaHWddc1SetSpeed,pSiS->ddc1Read )));
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ pSiS->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
+ if(pSiS->CRT2pScrn->monitor) {
+ DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
+ memcpy(pSiS->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
+ pSiS->CRT2pScrn->monitor->DDC = NULL;
+ pSiS->CRT2pScrn->monitor->Modes = NULL;
+ tempm = pScrn->monitor->Modes;
+ while(tempm) {
+ if(!(newm = xalloc(sizeof(DisplayModeRec)))) break;
+ memcpy(newm, tempm, sizeof(DisplayModeRec));
+ if(!(newm->name = xalloc(strlen(tempm->name) + 1))) {
+ xfree(newm);
+ break;
+ }
+ strcpy(newm->name, tempm->name);
+ if(!pSiS->CRT2pScrn->monitor->Modes) pSiS->CRT2pScrn->monitor->Modes = newm;
+ if(currentm) {
+ currentm->next = newm;
+ newm->prev = currentm;
+ }
+ currentm = newm;
+ tempm = tempm->next;
+ }
+ if(pSiS->CRT2HSync) {
+ pSiS->CRT2pScrn->monitor->nHsync =
+ SiSStrToRanges(pSiS->CRT2pScrn->monitor->hsync, pSiS->CRT2HSync, MAX_HSYNC);
+ }
+ if(pSiS->CRT2VRefresh) {
+ pSiS->CRT2pScrn->monitor->nVrefresh =
+ SiSStrToRanges(pSiS->CRT2pScrn->monitor->vrefresh, pSiS->CRT2VRefresh, MAX_VREFRESH);
+ }
+ if((pMonitor = SiSInternalDDC(pSiS->CRT2pScrn, 1))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, 2);
+ xf86PrintEDID(pMonitor);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, 2);
+ xf86SetDDCproperties(pSiS->CRT2pScrn, pMonitor);
+ pSiS->CRT2pScrn->monitor->DDC = pMonitor;
+ /* use DDC data if no ranges in config file */
+ if(!pSiS->CRT2HSync) {
+ pSiS->CRT2pScrn->monitor->nHsync = 0;
+ }
+ if(!pSiS->CRT2VRefresh) {
+ pSiS->CRT2pScrn->monitor->nVrefresh = 0;
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Failed to read DDC data for CRT2\n");
+ }
+ } else {
+ SISErrorLog(pScrn, "Failed to allocate memory for CRT2 monitor, %s.\n",
+ mergeddisstr);
+ if(pSiS->CRT2pScrn) xfree(pSiS->CRT2pScrn);
+ pSiS->CRT2pScrn = NULL;
+ pSiS->MergedFB = FALSE;
+ }
+ }
+#endif
+
+ /* If there is no HSync or VRefresh data for the monitor,
+ * derive it from DDC data. Done by common layer since
+ * 4.3.99.14.
+ */
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0)
+ if(pScrn->monitor->DDC) {
+ if(pScrn->monitor->nHsync <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, subshstr,
+#ifdef SISDUALHEAD
+ pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) :
+#endif
+ pSiS->CRT1off ? 2 : 1);
+ SiSSetSyncRangeFromEdid(pScrn, 1);
+ }
+ if(pScrn->monitor->nVrefresh <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, subsvstr,
+#ifdef SISDUALHEAD
+ pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) :
+#endif
+ pSiS->CRT1off ? 2 : 1);
+ SiSSetSyncRangeFromEdid(pScrn, 0);
+ }
+ }
+#endif
+
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0)
+ if(pSiS->CRT2pScrn->monitor->DDC) {
+ if(pSiS->CRT2pScrn->monitor->nHsync <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, subshstr, 2);
+ SiSSetSyncRangeFromEdid(pSiS->CRT2pScrn, 1);
+ }
+ if(pSiS->CRT2pScrn->monitor->nVrefresh <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, subsvstr, 2);
+ SiSSetSyncRangeFromEdid(pSiS->CRT2pScrn, 0);
+ }
+ }
#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 1);
+ }
+#endif
/* end of DDC */
+ /* From here, we mainly deal with clocks and modes */
+
/* Set the min pixel clock */
- pSiS->MinClock = 12000; /* XXX Guess, need to check this (TW: good for even 50Hz interlace) */
+ pSiS->MinClock = 5000;
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ pSiS->MinClock = 12000;
+ }
xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
pSiS->MinClock / 1000);
@@ -3091,106 +4733,109 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
clockRanges->interlaceAllowed = TRUE;
clockRanges->doubleScanAllowed = TRUE;
- /* TW: If there is no HSync or VRefresh data for the monitor,
- derive it from DDC data. (Idea taken from radeon driver)
- */
- if(pScrn->monitor->DDC) {
- if(pScrn->monitor->nHsync <= 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Substituting missing monitor HSync data by DDC data\n");
- SiSSetSyncRangeFromEdid(pScrn, 1);
- }
- if(pScrn->monitor->nVrefresh <= 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Substituting missing monitor VRefresh data by DDC data\n");
- SiSSetSyncRangeFromEdid(pScrn, 0);
- }
- }
-
/*
- * TW: Since we have lots of built-in modes for 300/310/325/330 series
- * with vb support, we replace the given default mode list with our
- * own. In case the video bridge is to be used, no other than our
- * built-in modes are supported; therefore, delete the entire modelist
- * given.
+ * Since we have lots of built-in modes for 300/315/330 series
+ * with vb support, we replace the given default mode list with our
+ * own. In case the video bridge is to be used, we only allow other
+ * modes if
+ * -) vbtype is 301, 301B, 301C or 302B, and
+ * -) crt2 device is not TV, and
+ * -) crt1 is not LCDA
*/
-
- pSiS->HaveCustomModes = FALSE;
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
- if(!(pSiS->noInternalModes)) {
- if((mymodes = SiSBuildBuiltInModeList(pScrn))) {
-#ifdef SISDUALHEAD
- if( (pSiS->UseVESA) ||
- ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ||
- ((!pSiS->DualHeadMode) && (pSiS->VBFlags & DISPTYPE_DISP2)) ) {
-#else
- if((pSiS->UseVESA) || (pSiS->VBFlags & DISPTYPE_DISP2)) {
-#endif
- while(pScrn->monitor->Modes)
- xf86DeleteMode(&pScrn->monitor->Modes, pScrn->monitor->Modes);
- pScrn->monitor->Modes = mymodes;
- } else {
- delmode = pScrn->monitor->Modes;
- while(delmode) {
- if(delmode->type & M_T_DEFAULT) {
- tempmode = delmode->next;
- xf86DeleteMode(&pScrn->monitor->Modes, delmode);
- delmode = tempmode;
- } else {
- delmode = delmode->next;
- }
- }
- tempmode = pScrn->monitor->Modes;
- if(tempmode) pSiS->HaveCustomModes = TRUE;
- pScrn->monitor->Modes = mymodes;
- while(mymodes) {
- if(!mymodes->next) break;
- else mymodes = mymodes->next;
- }
- mymodes->next = tempmode;
- if(tempmode) {
- tempmode->prev = mymodes;
- }
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Replaced %s mode list with built-in modes\n",
- pSiS->HaveCustomModes ? "default" : "entire");
+ if(!(pSiS->noInternalModes)) {
+ BOOLEAN acceptcustommodes = TRUE;
+ BOOLEAN includelcdmodes = TRUE;
+ BOOLEAN isfordvi = FALSE;
+ if(pSiS->UseVESA) {
+ acceptcustommodes = FALSE;
+ includelcdmodes = FALSE;
+ }
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->SecondHead) {
+ if((pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && (!(pSiS->VBFlags & VB_30xBDH))) {
+ if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE;
+ if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE;
+ if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE;
+ } else {
+ acceptcustommodes = FALSE;
+ includelcdmodes = FALSE;
+ }
+ clockRanges->interlaceAllowed = FALSE;
+ } else {
+ includelcdmodes = FALSE;
+ if(pSiS->VBFlags & CRT1_LCDA) {
+ acceptcustommodes = FALSE;
+ /* Ignore interlace, mode switching code will handle this */
+ }
+ }
+ } else
+#endif
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ includelcdmodes = FALSE;
+ if(pSiS->VBFlags & CRT1_LCDA) {
+ acceptcustommodes = FALSE;
+ /* Ignore interlace, mode switching code will handle this */
+ }
+ } else
+#endif
+ if((pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && (!(pSiS->VBFlags & VB_30xBDH))) {
+ if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE;
+ if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE;
+ if(pSiS->VBFlags & (CRT2_TV|CRT1_LCDA)) acceptcustommodes = FALSE;
+ } else if(pSiS->VBFlags & (CRT2_ENABLE | CRT1_LCDA)) {
+ acceptcustommodes = FALSE;
+ includelcdmodes = FALSE;
+ } else {
+ includelcdmodes = FALSE;
+ }
+ /* Ignore interlace, mode switching code will handle this */
+
+ pSiS->HaveCustomModes = FALSE;
+ if(SiSMakeOwnModeList(pScrn, acceptcustommodes, includelcdmodes, isfordvi, &pSiS->HaveCustomModes)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Replaced %s mode list with built-in modes\n",
+ pSiS->HaveCustomModes ? "default" : "entire");
#ifdef TWDEBUG
- pScrn->modes = pScrn->monitor->Modes;
- xf86PrintModes(pScrn);
- pScrn->modes = NULL;
-#endif
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ pScrn->modes = pScrn->monitor->Modes;
+ xf86PrintModes(pScrn);
+ pScrn->modes = NULL;
+#endif
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Building list of built-in modes failed, using XFree86 defaults\n");
- }
- }
+ }
+ } else {
+ pSiS->HaveCustomModes = TRUE;
+ }
}
/*
- * TW: Add our built-in modes for TV on the 6326
+ * Add our built-in modes for TV on the 6326
*/
if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
- if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Adding %s TV modes for 6326 to mode list:\n",
(pSiS->SiS6326Flags & SIS6326_TVPAL) ? "PAL" : "NTSC");
- if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
- SiS6326PAL800x600Mode.next = pScrn->monitor->Modes;
- pScrn->monitor->Modes = &SiS6326PAL640x480Mode;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\"PAL800x600\" \"PAL800x600U\" \"PAL720x540\" \"PAL640x480\"\n");
- } else {
- SiS6326NTSC640x480Mode.next = pScrn->monitor->Modes;
- pScrn->monitor->Modes = &SiS6326NTSC640x400Mode;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\"NTSC640x480\" \"NTSC640x480U\" \"NTSC640x400\"\n");
- }
- }
+ if(pSiS->SiS6326Flags & SIS6326_TVPAL) {
+ SiS6326PAL800x600Mode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &SiS6326PAL640x480Mode;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\t\"PAL800x600\" \"PAL800x600U\" \"PAL720x540\" \"PAL640x480\"\n");
+ } else {
+ SiS6326NTSC640x480Mode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &SiS6326NTSC640x400Mode;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\t\"NTSC640x480\" \"NTSC640x480U\" \"NTSC640x400\"\n");
+ }
+ }
}
/*
- * TW: Add our built-in hi-res modes on the 6326
+ * Add our built-in hi-res modes on the 6326
*/
if(pSiS->Chipset == PCI_CHIP_SIS6326) {
if(pScrn->bitsPerPixel == 8) {
@@ -3223,21 +4868,44 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Select valid modes from those available */
/*
- * Assuming min pitch 256, max 4096 ==> 8192
- * Assuming min height 128, max 4096
+ * Assuming min pitch 256, min height 128
*/
- i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
- pScrn->display->modes, clockRanges,
- NULL, 256, 8192,
- pScrn->bitsPerPixel * 8, 128, 4096,
+ {
+ int minpitch, maxpitch, minheight, maxheight;
+ minpitch = 256;
+ minheight = 128;
+ switch(pSiS->VGAEngine) {
+ case SIS_OLD_VGA:
+ case SIS_530_VGA:
+ maxpitch = 2040;
+ maxheight = 2048;
+ break;
+ case SIS_300_VGA:
+ case SIS_315_VGA:
+ maxpitch = 4088;
+ maxheight = 4096;
+ break;
+ default:
+ maxpitch = 2048;
+ maxheight = 2048;
+ break;
+ }
+#ifdef SISMERGED
+ pSiS->CheckForCRT2 = FALSE;
+#endif
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges, NULL,
+ minpitch, maxpitch,
+ pScrn->bitsPerPixel * 8,
+ minheight, maxheight,
pScrn->display->virtualX,
pScrn->display->virtualY,
pSiS->maxxfbmem,
LOOKUP_BEST_REFRESH);
+ }
if(i == -1) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf86ValidateModes() error\n");
+ SISErrorLog(pScrn, "xf86ValidateModes() error\n");
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -3247,129 +4915,74 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
- /* TW: Go through mode list and mark all those modes as bad,
- * - which are unsuitable for dual head mode (if running dhm),
- * - which exceed the LCD panels specs (if running on LCD)
- * - TODO: which exceed TV capabilities (if running on TV)
- * Also, find the highest used pixelclock on the master head.
- */
-#ifdef SISDUALHEAD
- if(pSiS->DualHeadMode) {
- if(!pSiS->SecondHead) pSiSEnt->maxUsedClock = 0;
- }
-#endif
- if((p = first = pScrn->modes)) {
- do {
- n = p->next;
-
- /* TW: Check the modes if they comply with our built-in tables.
- * This is of practical use only if the user disabled the
- * usage of the internal (built-in) modes.
- */
- if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
- if(p->type & M_T_DEFAULT) {
- if( ( (strcmp(p->name, "320x200") != 0) &&
- (strcmp(p->name, "320x240") != 0) &&
- (strcmp(p->name, "400x300") != 0) &&
- (strcmp(p->name, "512x384") != 0) ) &&
- (p->Flags & V_DBLSCAN) ) {
- p->status = MODE_NO_DBLESCAN;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (mode not supported as doublescan)\n", p->name);
- }
- if( ( (strcmp(p->name, "1024x768") != 0) &&
- (strcmp(p->name, "1280x1024") != 0) &&
- (strcmp(p->name, "848x480") != 0) &&
- (strcmp(p->name, "856x480") != 0)) &&
- (p->Flags & V_INTERLACE) ) {
- p->status = MODE_NO_INTERLACE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (mode not supported as interlaced)\n", p->name);
- }
- if( ( (strcmp(p->name, "320x200") == 0) ||
- (strcmp(p->name, "320x240") == 0) ||
- (strcmp(p->name, "400x300") == 0) ||
- (strcmp(p->name, "512x384") == 0) ) &&
- (!(p->Flags & V_DBLSCAN)) ) {
- p->status = MODE_CLOCK_RANGE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (only supported as doublescan)\n", p->name);
- }
- }
- }
+ /* Check the virtual screen against the available memory */
+ {
+ unsigned long memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8)) * pScrn->virtualY;
+
+ if(memreq > pSiS->maxxfbmem) {
+ SISErrorLog(pScrn,
+ "Virtual screen too big for memory; %ldK needed, %ldK available\n",
+ memreq/1024, pSiS->maxxfbmem/1024);
#ifdef SISDUALHEAD
- /* TW: Modes that require the bridge to operate in SlaveMode
- * are not suitable for Dual Head mode. Also check for
- * modes that exceed panel dimension.
- */
- if(pSiS->DualHeadMode) {
- if(pSiS->SecondHead == FALSE) {
- if( (strcmp(p->name, "320x200") == 0) ||
- (strcmp(p->name, "320x240") == 0) ||
- (strcmp(p->name, "400x300") == 0) ||
- (strcmp(p->name, "512x384") == 0) ||
- (strcmp(p->name, "640x400") == 0) ) {
- p->status = MODE_BAD;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (not suitable for dual head mode)\n",
- p->name);
- }
- }
- if(pSiS->VBFlags & DISPTYPE_DISP2) {
- if(pSiS->VBFlags & CRT2_LCD) {
- if(pSiS->SecondHead == FALSE) {
- if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) {
- p->status = MODE_PANEL;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name);
- }
- if(p->Flags & V_INTERLACE) {
- p->status = MODE_BAD;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (interlace on LCD not supported)\n",
- p->name);
- }
- }
- }
- /* TO DO: TV */
- }
- /* TW: Search for the highest clock on first head in order to calculate
- * max clock for second head (CRT1)
- */
- if(!pSiS->SecondHead) {
- if((p->status == MODE_OK) && (p->Clock > pSiSEnt->maxUsedClock)) {
- pSiSEnt->maxUsedClock = p->Clock;
- }
- }
- } else {
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->VBFlags & DISPTYPE_DISP2) {
- if(pSiS->VBFlags & CRT2_LCD) {
- if((p->HDisplay > pSiS->LCDwidth) || (p->VDisplay > pSiS->LCDheight)) {
- p->status = MODE_PANEL;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (exceeds LCD panel dimension)\n", p->name);
- }
- if(p->Flags & V_INTERLACE) {
- p->status = MODE_BAD;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%s\" (interlace on LCD not supported)\n",
- p->name);
- }
- }
- }
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ pSiS->pInt = NULL;
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* Dual Head:
+ * -) Go through mode list and mark all those modes as bad,
+ * which are unsuitable for dual head mode.
+ * -) Find the highest used pixelclock on the master head.
+ */
#ifdef SISDUALHEAD
- }
-#endif
- p = n;
- } while (p != NULL && p != first);
+ if(pSiS->DualHeadMode) {
+
+ if(!pSiS->SecondHead) {
+
+ pSiSEnt->maxUsedClock = 0;
+
+ if((p = first = pScrn->modes)) {
+ do {
+ n = p->next;
+
+ /* Modes that require the bridge to operate in SlaveMode
+ * are not suitable for Dual Head mode.
+ */
+ if( (pSiS->VGAEngine == SIS_300_VGA) &&
+ ( (strcmp(p->name, "320x200") == 0) ||
+ (strcmp(p->name, "320x240") == 0) ||
+ (strcmp(p->name, "400x300") == 0) ||
+ (strcmp(p->name, "512x384") == 0) ||
+ (strcmp(p->name, "640x400") == 0) ) ) {
+ p->status = MODE_BAD;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, notsuitablestr, p->name, "dual head");
+ }
+
+ /* Search for the highest clock on first head in order to calculate
+ * max clock for second head (CRT1)
+ */
+ if((p->status == MODE_OK) && (p->Clock > pSiSEnt->maxUsedClock)) {
+ pSiSEnt->maxUsedClock = p->Clock;
+ }
+
+ p = n;
+
+ } while (p != NULL && p != first);
+ }
+ }
}
+#endif
/* Prune the modes marked as invalid */
xf86PruneDriverModes(pScrn);
if(i == 0 || pScrn->modes == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ SISErrorLog(pScrn, "No valid modes found\n");
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -3384,50 +4997,191 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Set the current mode to the first in the list */
pScrn->currentMode = pScrn->modes;
- /* TW: Copy to CurrentLayout */
+ /* Copy to CurrentLayout */
pSiS->CurrentLayout.mode = pScrn->currentMode;
pSiS->CurrentLayout.displayWidth = pScrn->displayWidth;
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 1);
+ }
+#endif
+
/* Print the list of modes being used */
xf86PrintModes(pScrn);
-#ifdef SISDUALHEAD
- /* TW: Due to palette & timing problems we don't support 8bpp in DHM */
- if((pSiS->DualHeadMode) && (pScrn->bitsPerPixel == 8)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Colordepth 8 not supported in Dual Head mode.\n");
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ BOOLEAN acceptcustommodes = TRUE;
+ BOOLEAN includelcdmodes = TRUE;
+ BOOLEAN isfordvi = FALSE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 2);
+
+ clockRanges->next = NULL;
+ clockRanges->minClock = pSiS->MinClock;
+ clockRanges->maxClock = SiSMemBandWidth(pSiS->CRT2pScrn, TRUE);
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ clockRanges->doubleScanAllowed = TRUE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock for CRT2 is %d MHz\n",
+ clockRanges->minClock / 1000);
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Max pixel clock for CRT2 is %d MHz\n",
+ clockRanges->maxClock / 1000);
+
+ if((pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && (!(pSiS->VBFlags & VB_30xBDH))) {
+ if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE;
+ if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE;
+ if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE;
+ } else {
+ includelcdmodes = FALSE;
+ acceptcustommodes = FALSE;
+ }
+
+ pSiS->HaveCustomModes2 = FALSE;
+ if(!SiSMakeOwnModeList(pSiS->CRT2pScrn, acceptcustommodes, includelcdmodes, isfordvi, &pSiS->HaveCustomModes2)) {
+
+ SISErrorLog(pScrn, "Building list of built-in modes for CRT2 failed, %s\n",
+ mergeddisstr);
+ SiSFreeCRT2Structs(pSiS);
+ pSiS->MergedFB = FALSE;
+
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Replaced %s mode list for CRT2 with built-in modes\n",
+ pSiS->HaveCustomModes2 ? "default" : "entire");
+ }
+
+ }
+
+ if(pSiS->MergedFB) {
+
+ pSiS->CheckForCRT2 = TRUE;
+ i = xf86ValidateModes(pSiS->CRT2pScrn, pSiS->CRT2pScrn->monitor->Modes,
+ pSiS->CRT2pScrn->display->modes, clockRanges,
+ NULL, 256, 4088,
+ pSiS->CRT2pScrn->bitsPerPixel * 8, 128, 4096,
+ pScrn->display->virtualX ? pScrn->virtualX : 0,
+ pScrn->display->virtualY ? pScrn->virtualY : 0,
+ pSiS->maxxfbmem,
+ LOOKUP_BEST_REFRESH);
+ pSiS->CheckForCRT2 = FALSE;
+
+ if(i == -1) {
+ SISErrorLog(pScrn, "xf86ValidateModes() error, %s.\n", mergeddisstr);
+ SiSFreeCRT2Structs(pSiS);
+ pSiS->MergedFB = FALSE;
+ }
+
+ }
+
+ if(pSiS->MergedFB) {
+
+ if((p = first = pSiS->CRT2pScrn->modes)) {
+ do {
+ n = p->next;
+ if( (pSiS->VGAEngine == SIS_300_VGA) &&
+ ( (strcmp(p->name, "320x200") == 0) ||
+ (strcmp(p->name, "320x240") == 0) ||
+ (strcmp(p->name, "400x300") == 0) ||
+ (strcmp(p->name, "512x384") == 0) ||
+ (strcmp(p->name, "640x400") == 0) ) ) {
+ p->status = MODE_BAD;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, notsuitablestr, p->name, "MergedFB");
+ }
+ p = n;
+ } while (p != NULL && p != first);
+ }
+
+ xf86PruneDriverModes(pSiS->CRT2pScrn);
+
+ if(i == 0 || pSiS->CRT2pScrn->modes == NULL) {
+ SISErrorLog(pScrn, "No valid modes found for CRT2; %s\n", mergeddisstr);
+ SiSFreeCRT2Structs(pSiS);
+ pSiS->MergedFB = FALSE;
+ }
+
+ }
+
+ if(pSiS->MergedFB) {
+
+ xf86SetCrtcForModes(pSiS->CRT2pScrn, INTERLACE_HALVE_V);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 2);
+
+ xf86PrintModes(pSiS->CRT2pScrn);
+
+ pSiS->CRT1Modes = pScrn->modes;
+ pSiS->CRT1CurrentMode = pScrn->currentMode;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Generating MergedFB mode list\n");
+
+ pScrn->modes = SiSGenerateModeList(pScrn, pSiS->MetaModes,
+ pSiS->CRT1Modes, pSiS->CRT2pScrn->modes,
+ pSiS->CRT2Position);
+
+ if(!pScrn->modes) {
+
+ SISErrorLog(pScrn, "Failed to parse MetaModes or no modes found. %s.\n",
+ mergeddisstr);
+ SiSFreeCRT2Structs(pSiS);
+ pScrn->modes = pSiS->CRT1Modes;
+ pSiS->CRT1Modes = NULL;
+ pSiS->MergedFB = FALSE;
+
+ }
+
+ }
+
+ if(pSiS->MergedFB) {
+
+ /* If no virtual dimension was given by the user,
+ * calculate a sane one now. Adapts pScrn->virtualX,
+ * pScrn->virtualY and pScrn->displayWidth.
+ */
+ SiSRecalcDefaultVirtualSize(pScrn);
+
+ pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Update CurrentLayout */
+ pSiS->CurrentLayout.mode = pScrn->currentMode;
+ pSiS->CurrentLayout.displayWidth = pScrn->displayWidth;
+
}
#endif
/* Set display resolution */
- xf86SetDpi(pScrn, 0, 0);
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ SiSMergedFBSetDpi(pScrn, pSiS->CRT2pScrn, pSiS->CRT2Position);
+ } else
+#endif
+ xf86SetDpi(pScrn, 0, 0);
- /* Load bpp-specific modules */
+ /* Load fb module */
switch(pScrn->bitsPerPixel) {
- case 1:
- mod = "xf1bpp";
- Sym = "xf1bppScreenInit";
- break;
- case 4:
- mod = "xf4bpp";
- Sym = "xf4bppScreenInit";
- break;
case 8:
case 16:
case 24:
case 32:
- mod = "fb";
+ if(!xf86LoadSubModule(pScrn, "fb")) {
+ SISErrorLog(pScrn, "Failed to load fb module");
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
break;
- }
-
- if(mod && xf86LoadSubModule(pScrn, mod) == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not load %s module", mod);
+ default:
+ SISErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n", pScrn->bitsPerPixel);
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -3436,21 +5190,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
SISFreeRec(pScrn);
return FALSE;
}
-
- if(mod) {
- if(Sym) {
- xf86LoaderReqSymbols(Sym, NULL);
- } else {
- xf86LoaderReqSymLists(fbSymbols, NULL);
- }
- }
+ xf86LoaderReqSymLists(fbSymbols, NULL);
/* Load XAA if needed */
if(!pSiS->NoAccel) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n");
if(!xf86LoadSubModule(pScrn, "xaa")) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not load xaa module\n");
+ SISErrorLog(pScrn, "Could not load xaa module\n");
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -3465,8 +5211,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Load shadowfb if needed */
if(pSiS->ShadowFB) {
if(!xf86LoadSubModule(pScrn, "shadowfb")) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not load shadowfb module\n");
+ SISErrorLog(pScrn, "Could not load shadowfb module\n");
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
@@ -3478,8 +5223,22 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
xf86LoaderReqSymLists(shadowSymbols, NULL);
}
+ /* Load the dri module if requested. */
+#ifdef XF86DRI
+ if(pSiS->loadDRI) {
+ if(xf86LoadSubModule(pScrn, "dri")) {
+ xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL);
+ } else {
+#ifdef SISDUALHEAD
+ if(!pSiS->DualHeadMode)
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Remove >Load \"dri\"< from the Module section of your XF86Config file\n");
+ }
+ }
+#endif
- /* TW: Now load and initialize VBE module for VESA. */
+ /* Now load and initialize VBE module for VESA and mode restoring. */
pSiS->UseVESA = 0;
if(pSiS->VESA == 1) {
if(!pSiS->pVbe) {
@@ -3489,24 +5248,27 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->pVbe = VBEInit(pSiS->pInt,pSiS->pEnt->index);
#else
pSiS->pVbe = VBEExtendedInit(pSiS->pInt,pSiS->pEnt->index,
- SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+ SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
#endif
}
}
if(pSiS->pVbe) {
- vbe = VBEGetVBEInfo(pSiS->pVbe);
- pSiS->vesamajor = (unsigned)(vbe->VESAVersion >> 8);
- pSiS->vesaminor = vbe->VESAVersion & 0xff;
- pSiS->vbeInfo = vbe;
- SiSBuildVesaModeList(pScrn, pSiS->pVbe, vbe);
- VBEFreeVBEInfo(vbe);
- pSiS->UseVESA = 1;
+ vbe = VBEGetVBEInfo(pSiS->pVbe);
+ pSiS->vesamajor = (unsigned)(vbe->VESAVersion >> 8);
+ pSiS->vesaminor = vbe->VESAVersion & 0xff;
+ pSiS->vbeInfo = vbe;
+ if(pSiS->VESA == 1) {
+ SiSBuildVesaModeList(pScrn, pSiS->pVbe, vbe);
+ VBEFreeVBEInfo(vbe);
+ pSiS->UseVESA = 1;
+ }
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Could not load and initialize VBE module. VESA disabled.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not load and initialize VBE module.%s\n",
+ (pSiS->VESA == 1) ? " VESA disabled." : "");
}
- }
-
+ }
+
if(pSiS->pVbe) {
vbeFree(pSiS->pVbe);
pSiS->pVbe = NULL;
@@ -3521,6 +5283,28 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
pSiS->pInt = NULL;
+ if(pSiS->VGAEngine == SIS_315_VGA) pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTXVGAMMA1;
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ pSiS->SiS_SD_Flags |= SiS_SD_ISDUALHEAD;
+ if(pSiS->SecondHead) pSiS->SiS_SD_Flags |= SiS_SD_ISDHSECONDHEAD;
+ else pSiS->SiS_SD_Flags &= ~(SiS_SD_SUPPORTXVGAMMA1);
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ pSiS->SiS_SD_Flags |= SiS_SD_ISDHXINERAMA;
+ pSiS->SiS_SD_Flags &= ~(SiS_SD_SUPPORTXVGAMMA1);
+ }
+#endif
+ }
+#endif
+
+#ifdef SISMERGED
+ if(pSiS->MergedFB) pSiS->SiS_SD_Flags |= SiS_SD_ISMERGEDFB;
+#endif
+
+ if(pSiS->enablesisctrl) pSiS->SiS_SD_Flags |= SiS_SD_ENABLED;
+
return TRUE;
}
@@ -3560,7 +5344,7 @@ SISMapMem(ScrnInfoPtr pScrn)
if(pSiS->DualHeadMode) {
pSiSEnt->MapCountIOBase++;
if(!(pSiSEnt->IOBase)) {
- /* TW: Only map if not mapped previously */
+ /* Only map if not mapped previously */
pSiSEnt->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
pSiS->PciTag, pSiS->IOAddress, 0x10000);
}
@@ -3571,8 +5355,7 @@ SISMapMem(ScrnInfoPtr pScrn)
pSiS->PciTag, pSiS->IOAddress, 0x10000);
if(pSiS->IOBase == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not map MMIO area\n");
+ SISErrorLog(pScrn, "Could not map MMIO area\n");
return FALSE;
}
@@ -3585,7 +5368,7 @@ SISMapMem(ScrnInfoPtr pScrn)
if(pSiS->DualHeadMode) {
pSiSEnt->MapCountIOBaseDense++;
if(!(pSiSEnt->IOBaseDense)) {
- /* TW: Only map if not mapped previously */
+ /* Only map if not mapped previously */
pSiSEnt->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
pSiS->PciTag, pSiS->IOAddress, 0x10000);
}
@@ -3596,9 +5379,8 @@ SISMapMem(ScrnInfoPtr pScrn)
pSiS->PciTag, pSiS->IOAddress, 0x10000);
if(pSiS->IOBaseDense == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not map MMIO dense area\n");
- return FALSE;
+ SISErrorLog(pScrn, "Could not map MMIO dense area\n");
+ return FALSE;
}
#endif /* __alpha__ */
@@ -3607,14 +5389,14 @@ SISMapMem(ScrnInfoPtr pScrn)
if(pSiS->DualHeadMode) {
pSiSEnt->MapCountFbBase++;
if(!(pSiSEnt->FbBase)) {
- /* TW: Only map if not mapped previously */
+ /* Only map if not mapped previously */
pSiSEnt->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
pSiS->PciTag, (unsigned long)pSiS->realFbAddress,
pSiS->FbMapSize);
pSiS->sishw_ext.pjVideoMemoryAddress = (UCHAR *)pSiSEnt->FbBase;
}
pSiS->FbBase = pSiSEnt->FbBase;
- /* TW: Adapt FbBase (for DHM; dhmOffset is 0 otherwise) */
+ /* Adapt FbBase (for DHM; dhmOffset is 0 otherwise) */
pSiS->FbBase += pSiS->dhmOffset;
} else {
#endif
@@ -3627,9 +5409,8 @@ SISMapMem(ScrnInfoPtr pScrn)
#endif
if(pSiS->FbBase == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not map framebuffer area\n");
- return FALSE;
+ SISErrorLog(pScrn, "Could not map framebuffer area\n");
+ return FALSE;
}
return TRUE;
@@ -3654,14 +5435,14 @@ SISUnmapMem(ScrnInfoPtr pScrn)
pSiSEnt = pSiS->entityPrivate;
#endif
-/* TW: In dual head mode, we must not unmap if the other head still
- * assumes memory as mapped
-*/
+/* In dual head mode, we must not unmap if the other head still
+ * assumes memory as mapped
+ */
#ifdef SISDUALHEAD
- if (pSiS->DualHeadMode) {
- if (pSiSEnt->MapCountIOBase) {
+ if(pSiS->DualHeadMode) {
+ if(pSiSEnt->MapCountIOBase) {
pSiSEnt->MapCountIOBase--;
- if ((pSiSEnt->MapCountIOBase == 0) || (pSiSEnt->forceUnmapIOBase)) {
+ if((pSiSEnt->MapCountIOBase == 0) || (pSiSEnt->forceUnmapIOBase)) {
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBase, 0x10000);
pSiSEnt->IOBase = NULL;
pSiSEnt->MapCountIOBase = 0;
@@ -3670,9 +5451,9 @@ SISUnmapMem(ScrnInfoPtr pScrn)
pSiS->IOBase = NULL;
}
#ifdef __alpha__
- if (pSiSEnt->MapCountIOBaseDense) {
+ if(pSiSEnt->MapCountIOBaseDense) {
pSiSEnt->MapCountIOBaseDense--;
- if ((pSiSEnt->MapCountIOBaseDense == 0) || (pSiSEnt->forceUnmapIOBaseDense)) {
+ if((pSiSEnt->MapCountIOBaseDense == 0) || (pSiSEnt->forceUnmapIOBaseDense)) {
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBaseDense, 0x10000);
pSiSEnt->IOBaseDense = NULL;
pSiSEnt->MapCountIOBaseDense = 0;
@@ -3681,9 +5462,9 @@ SISUnmapMem(ScrnInfoPtr pScrn)
pSiS->IOBaseDense = NULL;
}
#endif /* __alpha__ */
- if (pSiSEnt->MapCountFbBase) {
+ if(pSiSEnt->MapCountFbBase) {
pSiSEnt->MapCountFbBase--;
- if ((pSiSEnt->MapCountFbBase == 0) || (pSiSEnt->forceUnmapFbBase)) {
+ if((pSiSEnt->MapCountFbBase == 0) || (pSiSEnt->forceUnmapFbBase)) {
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->FbBase, pSiS->FbMapSize);
pSiSEnt->FbBase = NULL;
pSiSEnt->MapCountFbBase = 0;
@@ -3721,39 +5502,51 @@ SISSave(ScrnInfoPtr pScrn)
pSiS = SISPTR(pScrn);
#ifdef SISDUALHEAD
- /* TW: We always save master & slave */
+ /* We always save master & slave */
if(pSiS->DualHeadMode && pSiS->SecondHead) return;
#endif
vgaReg = &VGAHWPTR(pScrn)->SavedReg;
sisReg = &pSiS->SavedReg;
- vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (SiSBridgeIsInSlaveMode(pScrn))) {
+ vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE);
+ SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30);
+ SiSSetLVDSetc(pSiS->SiS_Pr, &pSiS->sishw_ext, 0);
+ SiS_GetVBType(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS);
+ SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ } else {
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+ }
+ } else {
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+ }
sisSaveUnlockExtRegisterLock(pSiS,&sisReg->sisRegs3C4[0x05],&sisReg->sisRegs3D4[0x80]);
(*pSiS->SiSSave)(pScrn, sisReg);
-
+
if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_SAVE);
-
- /* TW: Save these as they may have been changed prior to SISSave() call */
+
+ /* "Save" these again as they may have been changed prior to SISSave() call */
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
- sisReg->sisRegs3D4[0x17] = pSiS->oldCR17;
- if(vgaReg->numCRTC >= 0x17) vgaReg->CRTC[0x17] = pSiS->oldCR17;
- sisReg->sisRegs3D4[0x32] = pSiS->oldCR32;
+ sisReg->sisRegs3D4[0x17] = pSiS->oldCR17;
+ if(vgaReg->numCRTC >= 0x17) vgaReg->CRTC[0x17] = pSiS->oldCR17;
+ sisReg->sisRegs3D4[0x32] = pSiS->oldCR32;
+ sisReg->sisRegs3C4[0x1f] = pSiS->oldSR1F;
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ sisReg->sisRegs3D4[0x63] = pSiS->oldCR63;
+ }
}
}
-/*
- * TW: Just adapted from the std* functions in vgaHW.c
- */
static void
SiS_WriteAttr(SISPtr pSiS, int index, int value)
{
- CARD8 tmp;
-
- tmp = inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET);
-
+ (void) inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET);
index |= 0x20;
outb(pSiS->IODBase + VGA_ATTR_INDEX, index);
outb(pSiS->IODBase + VGA_ATTR_DATA_W, value);
@@ -3762,15 +5555,13 @@ SiS_WriteAttr(SISPtr pSiS, int index, int value)
static int
SiS_ReadAttr(SISPtr pSiS, int index)
{
- CARD8 tmp;
-
- tmp = inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET);
-
+ (void) inb(pSiS->IODBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET);
index |= 0x20;
outb(pSiS->IODBase + VGA_ATTR_INDEX, index);
- return (inb(pSiS->IODBase + VGA_ATTR_DATA_R));
+ return(inb(pSiS->IODBase + VGA_ATTR_DATA_R));
}
+#define SIS_FONTS_SIZE (8 * 8192)
static void
SiS_SaveFonts(ScrnInfoPtr pScrn)
@@ -3783,15 +5574,17 @@ SiS_SaveFonts(ScrnInfoPtr pScrn)
pointer vgaIOBase = VGAHWPTR(pScrn)->Base;
#endif
- if (pSiS->fonts != NULL)
- return;
+ if(pSiS->fonts) return;
/* If in graphics mode, don't save anything */
attr10 = SiS_ReadAttr(pSiS, 0x10);
- if (attr10 & 0x01)
- return;
+ if(attr10 & 0x01) return;
- pSiS->fonts = xalloc(16384);
+ if(!(pSiS->fonts = xalloc(SIS_FONTS_SIZE * 2))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not save console fonts, mem allocation failed\n");
+ return;
+ }
/* save the registers that are needed here */
miscOut = inSISREG(SISMISCR);
@@ -3817,7 +5610,7 @@ SiS_SaveFonts(ScrnInfoPtr pScrn)
outSISIDXREG(SISGR, 0x04, 0x02); /* read plane 2 */
outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
- slowbcopy_frombus(vgaIOBase, pSiS->fonts, 8192);
+ slowbcopy_frombus(vgaIOBase, pSiS->fonts, SIS_FONTS_SIZE);
/* font2 */
outSISIDXREG(SISSR, 0x02, 0x08); /* write to plane 3 */
@@ -3825,7 +5618,7 @@ SiS_SaveFonts(ScrnInfoPtr pScrn)
outSISIDXREG(SISGR, 0x04, 0x03); /* read plane 3 */
outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
- slowbcopy_frombus(vgaIOBase, pSiS->fonts + 8192, 8192);
+ slowbcopy_frombus(vgaIOBase, pSiS->fonts + SIS_FONTS_SIZE, SIS_FONTS_SIZE);
inSISIDXREG(SISSR, 0x01, scrn);
outSISIDXREG(SISSR, 0x00, 0x01);
@@ -3853,13 +5646,7 @@ SiS_RestoreFonts(ScrnInfoPtr pScrn)
pointer vgaIOBase = VGAHWPTR(pScrn)->Base;
#endif
- if (pSiS->fonts == NULL)
- return;
-
-#if 0
- if (pVesa->mapPhys == 0xa0000 && pVesa->curBank != 0)
- VESABankSwitch(pScrn->pScreen, 0);
-#endif
+ if(!pSiS->fonts) return;
/* save the registers that are needed here */
miscOut = inSISREG(SISMISCR);
@@ -3881,10 +5668,10 @@ SiS_RestoreFonts(ScrnInfoPtr pScrn)
outSISIDXREG(SISSR, 0x00, 0x03);
SiS_WriteAttr(pSiS, 0x10, 0x01); /* graphics mode */
- if (pScrn->depth == 4) {
- outSISIDXREG(SISGR, 0x03, 0x00); /* don't rotate, write unmodified */
- outSISIDXREG(SISGR, 0x08, 0xFF); /* write all bits in a byte */
- outSISIDXREG(SISGR, 0x01, 0x00); /* all planes come from CPU */
+ if(pScrn->depth == 4) {
+ outSISIDXREG(SISGR, 0x03, 0x00); /* don't rotate, write unmodified */
+ outSISIDXREG(SISGR, 0x08, 0xFF); /* write all bits in a byte */
+ outSISIDXREG(SISGR, 0x01, 0x00); /* all planes come from CPU */
}
outSISIDXREG(SISSR, 0x02, 0x04); /* write to plane 2 */
@@ -3892,14 +5679,14 @@ SiS_RestoreFonts(ScrnInfoPtr pScrn)
outSISIDXREG(SISGR, 0x04, 0x02); /* read plane 2 */
outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
- slowbcopy_tobus(pSiS->fonts, vgaIOBase, 8192);
+ slowbcopy_tobus(pSiS->fonts, vgaIOBase, SIS_FONTS_SIZE);
outSISIDXREG(SISSR, 0x02, 0x08); /* write to plane 3 */
outSISIDXREG(SISSR, 0x04, 0x06); /* enable plane graphics */
outSISIDXREG(SISGR, 0x04, 0x03); /* read plane 3 */
outSISIDXREG(SISGR, 0x05, 0x00); /* write mode 0, read mode 0 */
outSISIDXREG(SISGR, 0x06, 0x05); /* set graphics */
- slowbcopy_tobus(pSiS->fonts + 8192, vgaIOBase, 8192);
+ slowbcopy_tobus(pSiS->fonts + SIS_FONTS_SIZE, vgaIOBase, SIS_FONTS_SIZE);
inSISIDXREG(SISSR, 0x01, scrn);
outSISIDXREG(SISSR, 0x00, 0x01);
@@ -3919,93 +5706,62 @@ SiS_RestoreFonts(ScrnInfoPtr pScrn)
outSISIDXREG(SISSR, 0x04, seq4);
}
-/* TW: VESASaveRestore taken from vesa driver */
+#undef SIS_FONTS_SIZE
+
+/* VESASaveRestore taken from vesa driver */
static void
SISVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function)
{
- SISPtr pSiS;
-
- pSiS = SISPTR(pScrn);
+ SISPtr pSiS = SISPTR(pScrn);
/* Query amount of memory to save state */
- if (function == MODE_QUERY ||
- (function == MODE_SAVE && pSiS->state == NULL)) {
-
- /* Make sure we save at least this information in case of failure */
- (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode);
- SiS_SaveFonts(pScrn);
+ if((function == MODE_QUERY) ||
+ (function == MODE_SAVE && pSiS->state == NULL)) {
- if (pSiS->vesamajor > 1) {
- if (!VBESaveRestore(pSiS->pVbe,function,(pointer)&pSiS->state,
- &pSiS->stateSize,&pSiS->statePage))
- return;
+ /* Make sure we save at least this information in case of failure */
+ (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode);
+ SiS_SaveFonts(pScrn);
- }
+ if(pSiS->vesamajor > 1) {
+ if(!VBESaveRestore(pSiS->pVbe, function, (pointer)&pSiS->state,
+ &pSiS->stateSize, &pSiS->statePage)) {
+ return;
+ }
+ }
}
/* Save/Restore Super VGA state */
- if (function != MODE_QUERY) {
- Bool retval = TRUE;
-
- if (pSiS->vesamajor > 1) {
- if (function == MODE_RESTORE)
- memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize);
-
- if ((retval = VBESaveRestore(pSiS->pVbe,function,
- (pointer)&pSiS->state,
- &pSiS->stateSize,&pSiS->statePage))
- && function == MODE_SAVE) {
- /* don't rely on the memory not being touched */
- if (pSiS->pstate == NULL)
- pSiS->pstate = xalloc(pSiS->stateSize);
- memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize);
- }
- }
+ if(function != MODE_QUERY) {
- if (function == MODE_RESTORE) {
- VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL);
- SiS_RestoreFonts(pScrn);
- }
-#if 0
- if (!retval)
- return (FALSE);
-#endif
+ if(pSiS->vesamajor > 1) {
+ if(function == MODE_RESTORE) {
+ memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize);
+ }
+
+ if(VBESaveRestore(pSiS->pVbe,function,(pointer)&pSiS->state,
+ &pSiS->stateSize,&pSiS->statePage) &&
+ (function == MODE_SAVE)) {
+ /* don't rely on the memory not being touched */
+ if(!pSiS->pstate) {
+ pSiS->pstate = xalloc(pSiS->stateSize);
+ }
+ memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize);
+ }
+ }
+
+ if(function == MODE_RESTORE) {
+ VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL);
+ SiS_RestoreFonts(pScrn);
+ }
}
-#if 0
- if ( (pSiS->vesamajor > 1) &&
- (function == MODE_SAVE || pSiS->pstate) ) {
- if (function == MODE_RESTORE)
- memcpy(pSiS->state, pSiS->pstate, pSiS->stateSize);
- if ((VBESaveRestore(pSiS->pVbe,function,
- (pointer)&pSiS->state,
- &pSiS->stateSize,&pSiS->statePage))) {
- if (function == MODE_SAVE) {
- /* don't rely on the memory not being touched */
- if (pSiS->pstate == NULL)
- pSiS->pstate = xalloc(pSiS->stateSize);
- memcpy(pSiS->pstate, pSiS->state, pSiS->stateSize);
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "VBESaveRestore done with success\n");
- return;
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "VBESaveRestore done\n");
- } else {
- if (function == MODE_SAVE)
- (void)VBEGetVBEMode(pSiS->pVbe, &pSiS->stateMode);
- else
- VBESetVBEMode(pSiS->pVbe, pSiS->stateMode, NULL);
- }
-#endif
}
/*
* Initialise a new mode. This is currently done using the
* "initialise struct, restore/write struct to HW" model for
* the old chipsets (5597/530/6326). For newer chipsets,
- * we use either VESA or our own mode switching code.
+ * we use our own mode switching code (or VESA).
*/
static Bool
@@ -4015,197 +5771,226 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
vgaRegPtr vgaReg;
SISPtr pSiS = SISPTR(pScrn);
SISRegPtr sisReg;
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = NULL;
+#endif
- vgaHWUnlock(hwp);
+ andSISIDXREG(SISCR,0x11,0x7f); /* Unlock CRTC registers */
- SISModifyModeInfo(mode);
+ SISModifyModeInfo(mode); /* Quick check of the mode parameters */
- /* TW: Initialize SiS Port Register definitions for externally used
- * BIOS emulation (native code switching) functions.
- */
- if( pSiS->VGAEngine == SIS_300_VGA ||
- pSiS->VGAEngine == SIS_315_VGA ) {
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30);
}
- if (pSiS->UseVESA) { /* With VESA: */
+ if(pSiS->UseVESA) { /* With VESA: */
#ifdef SISDUALHEAD
- /* TW: No dual head mode when using VESA */
- if (pSiS->SecondHead) return TRUE;
+ /* No dual head mode when using VESA */
+ if(pSiS->SecondHead) return TRUE;
#endif
- /*
- * TW: This order is required:
- * The video bridge needs to be adjusted before the
- * BIOS is run as the BIOS sets up CRT2 according to
- * these register settings.
- * After the BIOS is run, the bridges and turboqueue
- * registers need to be readjusted as the BIOS may
- * very probably have messed them up.
- */
- if( pSiS->VGAEngine == SIS_300_VGA ||
- pSiS->VGAEngine == SIS_315_VGA ) {
- SiSPreSetMode(pScrn, mode);
- }
- if(!SiSSetVESAMode(pScrn, mode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiSSetVESAMode() failed\n");
- return FALSE;
- }
- sisSaveUnlockExtRegisterLock(pSiS,NULL,NULL);
- if( pSiS->VGAEngine == SIS_300_VGA ||
- pSiS->VGAEngine == SIS_315_VGA ) {
- SiSPreSetMode(pScrn, mode);
- SiSPostSetMode(pScrn, &pSiS->ModeReg);
- }
- /* TW: Prepare some register contents and set
- * up some mode dependent variables.
- */
+
+ pScrn->vtSema = TRUE;
+
+ /*
+ * This order is required:
+ * The video bridge needs to be adjusted before the
+ * BIOS is run as the BIOS sets up CRT2 according to
+ * these register settings.
+ * After the BIOS is run, the bridges and turboqueue
+ * registers need to be readjusted as the BIOS may
+ * very probably have messed them up.
+ */
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+ SiSPreSetMode(pScrn, mode, SIS_MODE_SIMU);
+ }
+ if(!SiSSetVESAMode(pScrn, mode)) {
+ SISErrorLog(pScrn, "SiSSetVESAMode() failed\n");
+ return FALSE;
+ }
+ sisSaveUnlockExtRegisterLock(pSiS,NULL,NULL);
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+ SiSPreSetMode(pScrn, mode, SIS_MODE_SIMU);
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
+ }
#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
#endif
- if (!(*pSiS->ModeInit)(pScrn, mode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ModeInit() failed\n");
- return FALSE;
- }
-
- pScrn->vtSema = TRUE;
+ if(!(*pSiS->ModeInit)(pScrn, mode)) {
+ SISErrorLog(pScrn, "ModeInit() failed\n");
+ return FALSE;
+ }
- /* Program the registers */
- vgaHWProtect(pScrn, TRUE);
- (*pSiS->SiSRestore)(pScrn, &pSiS->ModeReg);
- vgaHWProtect(pScrn, FALSE);
- PDEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "HDisplay: %d, VDisplay: %d \n",
- mode->HDisplay, mode->VDisplay));
+ vgaHWProtect(pScrn, TRUE);
+ (*pSiS->SiSRestore)(pScrn, &pSiS->ModeReg);
+ vgaHWProtect(pScrn, FALSE);
} else { /* Without VESA: */
+
#ifdef SISDUALHEAD
- if(pSiS->DualHeadMode) {
- if(!(*pSiS->ModeInit)(pScrn, mode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ModeInit() failed\n");
- return FALSE;
- }
+ if(pSiS->DualHeadMode) {
- pScrn->vtSema = TRUE;
-
- if(!(pSiS->SecondHead)) {
- /* TW: Head 1 (master) is always CRT2 */
- SiSPreSetMode(pScrn, mode);
- if (!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiSBIOSSetModeCRT2() failed\n");
- return FALSE;
- }
- SiSPostSetMode(pScrn, &pSiS->ModeReg);
- } else {
- /* TW: Head 2 (slave) is always CRT1 */
- SiSPreSetMode(pScrn, mode);
- if (!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiSBIOSSetModeCRT1() failed\n");
- return FALSE;
- }
- SiSPostSetMode(pScrn, &pSiS->ModeReg);
- }
- } else {
+ if(!(*pSiS->ModeInit)(pScrn, mode)) {
+ SISErrorLog(pScrn, "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ pSiSEnt = pSiS->entityPrivate;
+
+ if(!(pSiS->SecondHead)) {
+ /* Head 1 (master) is always CRT2 */
+ SiSPreSetMode(pScrn, mode, SIS_MODE_CRT2);
+ if(!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) {
+ SISErrorLog(pScrn, "SiSBIOSSetModeCRT2() failed\n");
+ return FALSE;
+ }
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
+ SISAdjustFrame(pSiSEnt->pScrn_2->scrnIndex,
+ pSiSEnt->pScrn_2->frameX0,
+ pSiSEnt->pScrn_2->frameY0, 0);
+ } else {
+ /* Head 2 (slave) is always CRT1 */
+ SiSPreSetMode(pScrn, mode, SIS_MODE_CRT1);
+ if(!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) {
+ SISErrorLog(pScrn, "SiSBIOSSetModeCRT1() failed\n");
+ return FALSE;
+ }
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
+ SISAdjustFrame(pSiSEnt->pScrn_1->scrnIndex,
+ pSiSEnt->pScrn_1->frameX0,
+ pSiSEnt->pScrn_1->frameY0, 0);
+ }
+
+ } else {
#endif
- if(pSiS->VGAEngine == SIS_300_VGA ||
- pSiS->VGAEngine == SIS_315_VGA) {
-
- /* TW: Prepare the register contents; On 300/310/325,
- * we actually "abuse" this only for setting
- * up some variables; the registers are NOT
- * being written to the hardware as the BIOS
- * emulation (native mode switching code)
- * takes care of this.
- */
- if(!(*pSiS->ModeInit)(pScrn, mode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ModeInit() failed\n");
- return FALSE;
- }
- pScrn->vtSema = TRUE;
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
- /* 300/310/325 series: Use our own code for mode switching */
- SiSPreSetMode(pScrn, mode);
+ if(!(*pSiS->ModeInit)(pScrn, mode)) {
+ SISErrorLog(pScrn, "ModeInit() failed\n");
+ return FALSE;
+ }
- if(!SiSBIOSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiSBIOSSetMode() failed\n");
- return FALSE;
- }
+ pScrn->vtSema = TRUE;
- SiSPostSetMode(pScrn, &pSiS->ModeReg);
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "REAL REGISTER CONTENTS AFTER SETMODE:\n");
- (*pSiS->ModeInit)(pScrn, mode);
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+
+ xf86DrvMsg(0, X_INFO, "Setting MergedFB mode %dx%d\n",
+ mode->HDisplay, mode->VDisplay);
+
+ SiSPreSetMode(pScrn, mode, SIS_MODE_CRT1);
+
+ if(!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn,
+ ((SiSMergedDisplayModePtr)mode->Private)->CRT1,
+ pSiS->IsCustom)) {
+ SISErrorLog(pScrn, "SiSBIOSSetModeCRT1() failed\n");
+ return FALSE;
+ }
+
+ SiSPreSetMode(pScrn, mode, SIS_MODE_CRT2);
+
+ if(!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn,
+ ((SiSMergedDisplayModePtr)mode->Private)->CRT2,
+ pSiS->IsCustomCRT2)) {
+ SISErrorLog(pScrn, "SiSBIOSSetModeCRT2() failed\n");
+ return FALSE;
+ }
+
+ } else {
#endif
+
+ if(pSiS->VBFlags & CRT1_LCDA) {
+ SiSPreSetMode(pScrn, mode, SIS_MODE_CRT1);
+ if(!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn,
+ mode, pSiS->IsCustom)) {
+ SISErrorLog(pScrn, "SiSBIOSSetModeCRT1() failed\n");
+ return FALSE;
+ }
+ SiSPreSetMode(pScrn, mode, SIS_MODE_CRT2);
+ if(!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn,
+ mode, pSiS->IsCustom)) {
+ SISErrorLog(pScrn, "SiSBIOSSetModeCRT2() failed\n");
+ return FALSE;
+ }
} else {
+ SiSPreSetMode(pScrn, mode, SIS_MODE_SIMU);
+ if(!SiSBIOSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn,
+ mode, pSiS->IsCustom)) {
+ SISErrorLog(pScrn, "SiSBIOSSetModeCRT() failed\n");
+ return FALSE;
+ }
+ }
- /* For other chipsets, use the old method */
+#ifdef SISMERGED
+ }
+#endif
+ SiSPostSetMode(pScrn, &pSiS->ModeReg);
- /* Initialise the ModeReg values */
- if(!vgaHWInit(pScrn, mode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "vgaHWInit() failed\n");
- return FALSE;
- }
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+ (*pSiS->ModeInit)(pScrn, mode);
+#endif
- /* Reset our PIOOffset as vgaHWInit might have reset it */
- VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380;
+ } else {
- /* Prepare the register contents */
- if(!(*pSiS->ModeInit)(pScrn, mode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ModeInit() failed\n");
- return FALSE;
- }
+ /* For other chipsets, use the old method */
- pScrn->vtSema = TRUE;
+ /* Initialise the ModeReg values */
+ if(!vgaHWInit(pScrn, mode)) {
+ SISErrorLog(pScrn, "vgaHWInit() failed\n");
+ return FALSE;
+ }
- /* Program the registers */
- vgaHWProtect(pScrn, TRUE);
- vgaReg = &hwp->ModeReg;
- sisReg = &pSiS->ModeReg;
+ /* Reset our PIOOffset as vgaHWInit might have reset it */
+ VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380;
- vgaReg->Attribute[0x10] = 0x01;
- if(pScrn->bitsPerPixel > 8) {
- vgaReg->Graphics[0x05] = 0x00;
- }
+ /* Prepare the register contents */
+ if(!(*pSiS->ModeInit)(pScrn, mode)) {
+ SISErrorLog(pScrn, "ModeInit() failed\n");
+ return FALSE;
+ }
- vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ pScrn->vtSema = TRUE;
- (*pSiS->SiSRestore)(pScrn, sisReg);
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ sisReg = &pSiS->ModeReg;
- if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
- SiS6326PostSetMode(pScrn, &pSiS->ModeReg);
- }
+ vgaReg->Attribute[0x10] = 0x01;
+ if(pScrn->bitsPerPixel > 8) {
+ vgaReg->Graphics[0x05] = 0x00;
+ }
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ (*pSiS->SiSRestore)(pScrn, sisReg);
+
+ if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
+ SiS6326PostSetMode(pScrn, &pSiS->ModeReg);
+ }
#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"REAL REGISTER CONTENTS AFTER SETMODE:\n");
- (*pSiS->ModeInit)(pScrn, mode);
+ (*pSiS->ModeInit)(pScrn, mode);
#endif
- vgaHWProtect(pScrn, FALSE);
- }
+ vgaHWProtect(pScrn, FALSE);
+ }
#ifdef SISDUALHEAD
- }
+ }
#endif
}
- /* TW: Update Currentlayout */
+ /* Update Currentlayout */
pSiS->CurrentLayout.mode = mode;
- /* Debug */
-/* SiSDumpModeInfo(pScrn, mode); */
-
return TRUE;
}
@@ -4217,28 +6002,94 @@ SiSSetVESAMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
pSiS = SISPTR(pScrn);
- if (!(mode = SiSCalcVESAModeIndex(pScrn, pMode))) return FALSE;
+ if(!(mode = SiSCalcVESAModeIndex(pScrn, pMode))) return FALSE;
- mode |= 1 << 15; /* TW: Don't clear framebuffer */
- mode |= 1 << 14; /* TW: Use linear adressing */
+ mode |= (1 << 15); /* Don't clear framebuffer */
+ mode |= (1 << 14); /* Use linear adressing */
if(VBESetVBEMode(pSiS->pVbe, mode, NULL) == FALSE) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Setting VESA mode 0x%x failed\n",
+ SISErrorLog(pScrn, "Setting VESA mode 0x%x failed\n",
mode & 0x0fff);
- return (FALSE);
+ return (FALSE);
}
- if(pMode->HDisplay != pScrn->virtualX)
- VBESetLogicalScanline(pSiS->pVbe, pScrn->virtualX);
+ if(pMode->HDisplay != pScrn->virtualX) {
+ VBESetLogicalScanline(pSiS->pVbe, pScrn->virtualX);
+ }
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Setting VESA mode 0x%x succeeded\n",
- mode & 0x0fff);
+ "Setting VESA mode 0x%x succeeded\n",
+ mode & 0x0fff);
return (TRUE);
}
+static void
+SISSpecialRestore(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr sisReg = &pSiS->SavedReg;
+ unsigned char temp;
+ int i;
+
+ /* 1.11.04 and later for 651 and 301B(DH) do strange register
+ * fiddling after the usual mode change. This happens
+ * depending on the result of a call of int 2f (with
+ * ax=0x1680) and if modeno <= 0x13. I have no idea if
+ * that is specific for the 651 or that very machine.
+ * So this perhaps requires some more checks in the beginning
+ * (although it should not do any harm on other chipsets/bridges
+ * etc.) However, even if I call the VBE to restore mode 0x03,
+ * these registers don't get restored correctly, possibly
+ * because that int-2f-call for some reason results non-zero. So
+ * what I do here is to restore these few registers
+ * manually.
+ */
+
+ if(!(pSiS->ChipFlags & SiSCF_Is65x)) return;
+ inSISIDXREG(SISCR, 0x34, temp);
+ if(temp > 0x13) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
+#endif
+
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext);
+
+ outSISIDXREG(SISCAP, 0x3f, sisReg->sisCapt[0x3f]);
+ outSISIDXREG(SISCAP, 0x00, sisReg->sisCapt[0x00]);
+ for(i = 0; i < 0x4f; i++) {
+ outSISIDXREG(SISCAP, i, sisReg->sisCapt[i]);
+ }
+ outSISIDXREG(SISVID, 0x32, (sisReg->sisVid[0x32] & ~0x05));
+ outSISIDXREG(SISVID, 0x30, sisReg->sisVid[0x30]);
+ outSISIDXREG(SISVID, 0x32, ((sisReg->sisVid[0x32] & ~0x04) | 0x01));
+ outSISIDXREG(SISVID, 0x30, sisReg->sisVid[0x30]);
+
+ if(!(pSiS->ChipFlags & SiSCF_Is651)) return;
+ if(!(pSiS->VBFlags & VB_SISBRIDGE)) return;
+
+ inSISIDXREG(SISCR, 0x30, temp);
+ if(temp & 0x40) {
+ unsigned char myregs[] = {
+ 0x2f, 0x08, 0x09, 0x03, 0x0a, 0x0c,
+ 0x0b, 0x0d, 0x0e, 0x12, 0x0f, 0x10,
+ 0x11, 0x04, 0x05, 0x06, 0x07, 0x00,
+ 0x2e
+ };
+ for(i = 0; i <= 18; i++) {
+ outSISIDXREG(SISPART1, myregs[i], sisReg->VBPart1[myregs[i]]);
+ }
+ } else if((temp & 0x20) || (temp & 0x9c)) {
+ unsigned char myregs[] = {
+ 0x04, 0x05, 0x06, 0x07, 0x00, 0x2e
+ };
+ for(i = 0; i <= 5; i++) {
+ outSISIDXREG(SISPART1, myregs[i], sisReg->VBPart1[myregs[i]]);
+ }
+ }
+}
+
/*
* Restore the initial mode. To be used internally only!
*/
@@ -4250,15 +6101,26 @@ SISRestore(ScrnInfoPtr pScrn)
vgaHWPtr hwp = VGAHWPTR(pScrn);
vgaRegPtr vgaReg = &hwp->SavedReg;
Bool doit = FALSE, doitlater = FALSE;
+ Bool vesasuccess = FALSE;
+
+ /* WARNING: Don't ever touch this. It now seems to work on
+ * all chipset/bridge combinations - but finding out the
+ * correct combination was pure hell.
+ */
+
+ /* Wait for the accelerators */
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ }
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
#ifdef SISDUALHEAD
- /* TW: We always restore master AND slave */
+ /* We always restore master AND slave */
if(pSiS->DualHeadMode && pSiS->SecondHead) return;
#endif
- /* TW: We must not disable the sequencer if the bridge is in SlaveMode! */
+ /* We must not disable the sequencer if the bridge is in SlaveMode! */
if(!(SiSBridgeIsInSlaveMode(pScrn))) {
vgaHWProtect(pScrn, TRUE);
}
@@ -4267,66 +6129,127 @@ SISRestore(ScrnInfoPtr pScrn)
sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
#endif
- /* TW: First, restore CRT1 on/off and VB connection registers */
+ /* First, restore CRT1 on/off and VB connection registers */
outSISIDXREG(SISCR, 0x32, pSiS->oldCR32);
- if(!(pSiS->oldCR17 & 0x80)) { /* TW: CRT1 was off */
- if(!(SiSBridgeIsInSlaveMode(pScrn))) { /* TW: Bridge is NOT in SlaveMode now -> do it */
- doit = TRUE;
- } else {
- doitlater = TRUE;
- }
- } else { /* TW: CRT1 was on -> do it now */
- doit = TRUE;
+ if(!(pSiS->oldCR17 & 0x80)) { /* CRT1 was off */
+ if(!(SiSBridgeIsInSlaveMode(pScrn))) { /* Bridge is NOT in SlaveMode now -> do it */
+ doit = TRUE;
+ } else {
+ doitlater = TRUE;
+ }
+ } else { /* CRT1 was on -> do it now */
+ doit = TRUE;
}
if(doit) {
- outSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
+ outSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
}
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ outSISIDXREG(SISCR, 0x63, pSiS->oldCR63);
+ }
+
+ outSISIDXREG(SISSR, 0x1f, pSiS->oldSR1F);
- /* TW: For 30xB/LV, restoring the registers does not
- * work. We "manually" set the old mode, instead.
- * The same applies for SiS730 machines with LVDS.
- * Finally, this behavior can be forced by setting
- * the option RestoreBySetMode.
+ /* For 30xB/LV, restoring the registers does not
+ * work. We "manually" set the old mode, instead.
+ * The same applies for SiS730 machines with LVDS.
+ * Finally, this behavior can be forced by setting
+ * the option RestoreBySetMode.
*/
if( ( (pSiS->restorebyset) ||
- (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) ||
+ (pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) ||
((pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ) &&
(pSiS->OldMode) ) {
- if(pSiS->AccelInfoPtr) {
- (*pSiS->AccelInfoPtr->Sync)(pScrn);
- }
-
+ Bool changedmode = FALSE;
+
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"Restoring by setting old mode 0x%02x\n", pSiS->OldMode);
+
+ if(((pSiS->OldMode <= 0x13) || (!pSiS->sisfbfound)) && (pSiS->pVbe)) {
+ int vmode = SiSTranslateToVESA(pScrn, pSiS->OldMode);
+ if(vmode > 0) {
+ if(vmode > 0x13) vmode |= ((1 << 15) | (1 << 14));
+ if(VBESetVBEMode(pSiS->pVbe, vmode, NULL) == TRUE) {
+ SISSpecialRestore(pScrn);
+ SiS_GetSetModeID(pScrn,pSiS->OldMode);
+ vesasuccess = TRUE;
+ } else {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "VBE failed to restore mode 0x%x\n", pSiS->OldMode);
+ }
+ } else {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Can't identify VESA mode number for mode 0x%x\n", pSiS->OldMode);
+ }
+ }
+
+ if(vesasuccess == FALSE) {
+
+ int backupscaler = pSiS->SiS_Pr->UsePanelScaler;
+ unsigned long backupspecialtiming = pSiS->SiS_Pr->SiS_CustomT;
+
+ if((pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV))) {
+ /* !!! REQUIRED for 630+301B-DH, otherwise the text modes
+ * will not be restored correctly !!!
+ * !!! Do this ONLY for LCD; VGA2 will not be restored
+ * correctly otherwise.
+ */
+ unsigned char temp;
+ inSISIDXREG(SISCR, 0x30, temp);
+ if(temp & 0x20) {
+ if(pSiS->OldMode == 0x03) {
+ pSiS->OldMode = 0x13;
+ changedmode = TRUE;
+ }
+ }
+ }
+
+ pSiS->SiS_Pr->UseCustomMode = FALSE;
+ pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE;
+ pSiS->SiS_Pr->UsePanelScaler = pSiS->sisfbscalelcd;
+ pSiS->SiS_Pr->SiS_CustomT = pSiS->sisfbspecialtiming;
+ SiSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, pSiS->OldMode, FALSE);
+ if(changedmode) {
+ pSiS->OldMode = 0x03;
+ outSISIDXREG(SISCR,0x34,0x03);
+ }
+ SISSpecialRestore(pScrn);
+ SiS_GetSetModeID(pScrn,pSiS->OldMode);
+ pSiS->SiS_Pr->UsePanelScaler = backupscaler;
+ pSiS->SiS_Pr->SiS_CustomT = backupspecialtiming;
- if( (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) &&
- (!pSiS->restorebyset) ) {
- if(pSiS->OldMode == 0x03) pSiS->OldMode = 0x13;
}
-
- pSiS->SiS_Pr->UseCustomMode = FALSE;
- pSiS->SiS_Pr->CRT1UsesCustomMode = FALSE;
- SiSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, pSiS->OldMode, FALSE);
-#ifdef TWDEBUG
- {
- SISRegPtr pReg = &pSiS->ModeReg;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "REAL REGISTER CONTENTS AFTER RESTORE BY SETMODE:\n");
- (*pSiS->SiSSave)(pScrn, pReg);
- }
+
+ /* Restore CRT1 status */
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ outSISIDXREG(SISCR, 0x63, pSiS->oldCR63);
+ }
+ outSISIDXREG(SISSR, 0x1f, pSiS->oldSR1F);
+
+#ifdef SISVRAMQ
+ /* Restore queue mode registers on 315/330 series */
+ /* (This became necessary due to the switch to VRAM queue) */
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ unsigned char tempCR55;
+ inSISIDXREG(SISCR,0x55,tempCR55);
+ andSISIDXREG(SISCR,0x55,0x33);
+ outSISIDXREG(SISSR,0x26,0x01);
+ MMIO_OUT32(pSiS->IOBase, 0x85c4, 0);
+ outSISIDXREG(SISSR,0x27,sisReg->sisRegs3C4[0x27]);
+ outSISIDXREG(SISSR,0x26,sisReg->sisRegs3C4[0x26]);
+ MMIO_OUT32(pSiS->IOBase, 0x85C0, sisReg->sisMMIO85C0);
+ outSISIDXREG(SISCR,0x55,tempCR55);
+ }
#endif
} else {
if(pSiS->VBFlags & VB_VIDEOBRIDGE) {
- /* TW: If a video bridge is present, we need to restore
- * non-extended (=standard VGA) SR and CR registers
- * before restoring the extended ones and the bridge
- * registers itself. Unfortunately, the vgaHWRestore
- * routine clears CR17[7] - which must not be done if
- * the bridge is in slave mode.
+ /* If a video bridge is present, we need to restore
+ * non-extended (=standard VGA) SR and CR registers
+ * before restoring the extended ones and the bridge
+ * registers itself.
*/
if(!(SiSBridgeIsInSlaveMode(pScrn))) {
vgaHWProtect(pScrn, TRUE);
@@ -4345,41 +6268,56 @@ SISRestore(ScrnInfoPtr pScrn)
outSISIDXREG(SISCR, 0x17, pSiS->oldCR17);
}
- sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[0x05],sisReg->sisRegs3D4[0x80]);
-
- if( ( (pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ||
- (pSiS->restorebyset) ) {
-
- /* TW: SiS730/LVDS has extreme problems restoring the text display due
- * to over-sensible LCD panels
- */
-
- vgaHWProtect(pScrn, TRUE);
-
- if(pSiS->Primary) {
- vgaHWRestore(pScrn, vgaReg, (VGA_SR_FONTS | VGA_SR_CMAP));
- }
-
- vgaHWProtect(pScrn, FALSE);
-
- } else {
-
- vgaHWProtect(pScrn, TRUE);
-
- if(pSiS->Primary) {
+ if(pSiS->Primary) {
+ if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (SiSBridgeIsInSlaveMode(pScrn))) {
+ /* IMPORTANT: The 30xLV does not handle well being disabled if in
+ * LCDA mode! In LCDA mode, the bridge is NOT in slave mode,
+ * so this is the only safe way: Disable the bridge ONLY if
+ * in Slave Mode, and don't bother if not.
+ */
+ SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30);
+ SiSSetLVDSetc(pSiS->SiS_Pr, &pSiS->sishw_ext, 0);
+ SiS_GetVBType(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext);
+
+ vgaHWProtect(pScrn, TRUE);
+
+ /* We now restore ALL to overcome the vga=extended problem */
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ andSISIDXREG(SISSR, 0x01, ~0x20); /* Display on */
+ } else {
+ vgaHWProtect(pScrn, TRUE);
+
+ /* We now restore ALL to overcome the vga=extended problem */
vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+
+ vgaHWProtect(pScrn, FALSE);
}
-
- vgaHWProtect(pScrn, FALSE);
-
}
+
+#ifdef TWDEBUG
+ {
+ SISRegPtr pReg = &pSiS->ModeReg;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER RESTORE BY SETMODE:\n");
+ (*pSiS->SiSSave)(pScrn, pReg);
+ }
+#endif
+
+ sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[0x05],sisReg->sisRegs3D4[0x80]);
} else { /* All other chipsets */
vgaHWProtect(pScrn, TRUE);
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
#endif
+
(*pSiS->SiSRestore)(pScrn, sisReg);
vgaHWProtect(pScrn, TRUE);
@@ -4387,36 +6325,36 @@ SISRestore(ScrnInfoPtr pScrn)
vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
}
- /* TW: Restore TV. This is rather complicated, but if we don't do it,
- * TV output will flicker terribly
+ /* Restore TV. This is rather complicated, but if we don't do it,
+ * TV output will flicker terribly
*/
if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) {
- if(sisReg->sis6326tv[0] & 0x04) {
- unsigned char tmp;
- int val;
-
- orSISIDXREG(SISSR, 0x01, 0x20);
- tmp = SiS6326GetTVReg(pScrn,0x00);
- tmp &= ~0x04;
- while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
- SiS6326SetTVReg(pScrn,0x00,tmp);
- for(val=0; val < 2; val++) {
- while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
- while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
- }
- SiS6326SetTVReg(pScrn, 0x00, sisReg->sis6326tv[0]);
- tmp = inSISREG(SISINPSTAT);
- outSISREG(SISAR, 0x20);
- tmp = inSISREG(SISINPSTAT);
- while(inSISREG(SISINPSTAT) & 0x01);
- while(!(inSISREG(SISINPSTAT) & 0x01));
- andSISIDXREG(SISSR, 0x01, ~0x20);
- for(val=0; val < 10; val++) {
+ if(sisReg->sis6326tv[0] & 0x04) {
+ unsigned char tmp;
+ int val;
+
+ orSISIDXREG(SISSR, 0x01, 0x20);
+ tmp = SiS6326GetTVReg(pScrn,0x00);
+ tmp &= ~0x04;
while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
- while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
- }
- andSISIDXREG(SISSR, 0x01, ~0x20);
- }
+ SiS6326SetTVReg(pScrn,0x00,tmp);
+ for(val=0; val < 2; val++) {
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
+ }
+ SiS6326SetTVReg(pScrn, 0x00, sisReg->sis6326tv[0]);
+ tmp = inSISREG(SISINPSTAT);
+ outSISREG(SISAR, 0x20);
+ tmp = inSISREG(SISINPSTAT);
+ while(inSISREG(SISINPSTAT) & 0x01);
+ while(!(inSISREG(SISINPSTAT) & 0x01));
+ andSISIDXREG(SISSR, 0x01, ~0x20);
+ for(val=0; val < 10; val++) {
+ while(!(inSISREG(SISINPSTAT) & 0x08)); /* Wait while NOT vb */
+ while(inSISREG(SISINPSTAT) & 0x08); /* wait while vb */
+ }
+ andSISIDXREG(SISSR, 0x01, ~0x20);
+ }
}
sisRestoreExtRegisterLock(pSiS,sisReg->sisRegs3C4[5],sisReg->sisRegs3D4[0x80]);
@@ -4430,10 +6368,28 @@ SISVESARestore(ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
- if(pSiS->UseVESA) SISVESASaveRestore(pScrn, MODE_RESTORE);
+ if(pSiS->UseVESA) {
+ SISVESASaveRestore(pScrn, MODE_RESTORE);
+#ifdef SISVRAMQ
+ /* Restore queue mode registers on 315/330 series */
+ /* (This became necessary due to the switch to VRAM queue) */
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ SISRegPtr sisReg = &pSiS->SavedReg;
+ unsigned char tempCR55;
+ inSISIDXREG(SISCR,0x55,tempCR55);
+ andSISIDXREG(SISCR,0x55,0x33);
+ outSISIDXREG(SISSR,0x26,0x01);
+ MMIO_OUT32(pSiS->IOBase, 0x85c4, 0);
+ outSISIDXREG(SISSR,0x27,sisReg->sisRegs3C4[0x27]);
+ outSISIDXREG(SISSR,0x26,sisReg->sisRegs3C4[0x26]);
+ MMIO_OUT32(pSiS->IOBase, 0x85C0, sisReg->sisMMIO85C0);
+ outSISIDXREG(SISCR,0x55,tempCR55);
+ }
+#endif
+ }
}
-/* TW: Restore bridge registers - to be called BEFORE VESARestore */
+/* Restore bridge config registers - to be called BEFORE VESARestore */
static void
SISBridgeRestore(ScrnInfoPtr pScrn)
{
@@ -4449,7 +6405,7 @@ SISBridgeRestore(ScrnInfoPtr pScrn)
}
}
-/* TW: Our generic BlockHandler for Xv */
+/* Our generic BlockHandler for Xv */
static void
SISBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
{
@@ -4462,16 +6418,20 @@ SISBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
pScreen->BlockHandler = SISBlockHandler;
if(pSiS->VideoTimerCallback) {
- (*pSiS->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ (*pSiS->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ }
+
+ if(pSiS->RenderCallback) {
+ (*pSiS->RenderCallback)(pScrn);
}
}
/* Mandatory
* This gets called at the start of each server generation
*
- * TW: We use pScrn and not CurrentLayout here, because the
- * properties we use have not changed (displayWidth,
- * depth, bitsPerPixel)
+ * We use pScrn and not CurrentLayout here, because the
+ * properties we use have not changed (displayWidth,
+ * depth, bitsPerPixel)
*/
static Bool
SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
@@ -4480,7 +6440,6 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
vgaHWPtr hwp;
SISPtr pSiS;
int ret;
- int init_picture = 0;
VisualPtr visual;
unsigned long OnScreenSize;
int height, width, displayWidth;
@@ -4495,19 +6454,28 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pSiS = SISPTR(pScrn);
- if(pSiS->UseVESA) {
+#ifdef SISDUALHEAD
+ if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) {
+#endif
+ if(xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
- pSiS->pVbe = VBEInit(NULL, pSiS->pEnt->index);
+ pSiS->pVbe = VBEInit(NULL, pSiS->pEnt->index);
#else
- pSiS->pVbe = VBEExtendedInit(NULL, pSiS->pEnt->index,
+ pSiS->pVbe = VBEExtendedInit(NULL, pSiS->pEnt->index,
SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
#endif
+ } else {
+ SISErrorLog(pScrn, "Failed to load VBE submodule\n");
+ }
+#ifdef SISDUALHEAD
}
+#endif
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
- pSiSEnt = pSiS->entityPrivate;
- pSiSEnt->refCount++;
+ pSiSEnt = pSiS->entityPrivate;
+ pSiSEnt->refCount++;
}
#endif
@@ -4515,69 +6483,107 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if(pSiS->Primary) {
hwp->MapSize = 0x10000; /* Standard 64k VGA window */
if(!vgaHWMapMem(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Could not map VGA window\n");
+ SISErrorLog(pScrn, "Could not map VGA memory window\n");
return FALSE;
}
}
vgaHWGetIOBase(hwp);
-
- /* TW: Patch the PIOOffset inside vgaHW to use
- * our relocated IO ports.
+
+ /* Patch the PIOOffset inside vgaHW to use
+ * our relocated IO ports.
*/
VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380;
/* Map the SIS memory and MMIO areas */
if(!SISMapMem(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiSMapMem() failed\n");
- return FALSE;
+ SISErrorLog(pScrn, "SiSMapMem() failed\n");
+ return FALSE;
}
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
- /* TW: Enable TurboQueue so that SISSave() saves it in enabled
- * state. If we don't do this, X will hang after a restart!
- * (Happens for some unknown reason only when using VESA
- * for mode switching; assumingly a BIOS issue.)
- * This is done on 300 and 310/325 series only.
+ /* Enable TurboQueue so that SISSave() saves it in enabled
+ * state. If we don't do this, X will hang after a restart!
+ * (Happens for some unknown reason only when using VESA
+ * for mode switching; assumingly a BIOS issue.)
+ * This is done on 300 and 315 series only.
*/
if(pSiS->UseVESA) {
- SiSEnableTurboQueue(pScrn);
+#ifdef SISVRAMQ
+ if(pSiS->VGAEngine != SIS_315_VGA)
+#endif
+ SiSEnableTurboQueue(pScrn);
+
}
/* Save the current state */
SISSave(pScrn);
- /* TW: Save the current mode number */
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
- inSISIDXREG(SISCR, 0x34, pSiS->OldMode);
+
+ if(!pSiS->OldMode) {
+
+ /* Try to find out current (=old) mode number
+ * (Do this only if not sisfb has told us its mode yet)
+ */
+
+ /* Read 0:449 which the BIOS sets to the current mode number
+ * Unfortunately, this not reliable since the int10 emulation
+ * does not change this. So if we call the VBE later, this
+ * byte won't be touched. (which is why we set this manually
+ * then)
+ */
+ unsigned char myoldmode = SiS_GetSetModeID(pScrn,0xFF);
+ unsigned char cr30, cr31;
+
+ /* Read CR34 which the BIOS sets to the current mode number for CRT2
+ * This is - of course - not reliable if the machine has no video
+ * bridge...
+ */
+ inSISIDXREG(SISCR, 0x34, pSiS->OldMode);
+ inSISIDXREG(SISCR, 0x30, cr30);
+ inSISIDXREG(SISCR, 0x31, cr31);
+
+ /* What if CR34 is different from the BIOS byte? */
+ if(pSiS->OldMode != myoldmode) {
+ /* If no bridge output is active, trust the BIOS byte */
+ if(!cr31 && !cr30) pSiS->OldMode = myoldmode;
+ /* ..else trust CR34 */
+ }
+
+ /* Newer 650 BIOSes set CR34 to 0xff if the mode has been
+ * "patched", for instance for 80x50 text mode. (That mode
+ * has no number of its own, it's 0x03 like 80x25). In this
+ * case, we trust the BIOS byte (provided that any of these
+ * two is valid).
+ */
+ if(pSiS->OldMode > 0x7f) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Previous video mode (%02x) invalid, using BIOS scratch (%02x)\n",
+ pSiS->OldMode, myoldmode);
+ pSiS->OldMode = myoldmode;
+ }
+ }
}
/* Initialise the first mode */
if(!SISModeInit(pScrn, pScrn->currentMode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiSModeInit() failed\n");
- return FALSE;
+ SISErrorLog(pScrn, "SiSModeInit() failed\n");
+ return FALSE;
}
/* Darken the screen for aesthetic reasons */
- /* TW: Not using Dual Head variant on purpose; we darken
- * the screen for both displays, and un-darken
- * it when the second head is finished
+ /* Not using Dual Head variant on purpose; we darken
+ * the screen for both displays, and un-darken
+ * it when the second head is finished
*/
SISSaveScreen(pScreen, SCREEN_SAVER_ON);
/* Set the viewport */
SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
- /* Clear frame buffer */
- OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
- * (pScrn->bitsPerPixel / 8);
- bzero(pSiS->FbBase, OnScreenSize);
-
/*
* The next step is to setup the screen's visuals, and initialise the
* framebuffer code. In cases where the framebuffer's default
@@ -4601,23 +6607,14 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* For bpp > 8, the default visuals are not acceptable because we only
* support TrueColor and not DirectColor.
*/
- if(pScrn->bitsPerPixel > 8) {
- if(!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
- pScrn->defaultVisual)) {
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "miSetVisualTypes() failed (bpp %d)\n", pScrn->bitsPerPixel);
- return FALSE;
- }
- } else {
- if(!miSetVisualTypes(pScrn->depth,
- miGetDefaultVisualMask(pScrn->depth),
- pScrn->rgbBits, pScrn->defaultVisual)) {
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "miSetVisualTypes() failed (bpp %d)\n", pScrn->bitsPerPixel);
- return FALSE;
- }
+ if(!miSetVisualTypes(pScrn->depth,
+ (pScrn->bitsPerPixel > 8) ?
+ TrueColorMask : miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n",
+ pScrn->bitsPerPixel);
+ return FALSE;
}
width = pScrn->virtualX;
@@ -4625,132 +6622,124 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
displayWidth = pScrn->displayWidth;
if(pSiS->Rotate) {
- height = pScrn->virtualX;
- width = pScrn->virtualY;
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
}
if(pSiS->ShadowFB) {
- pSiS->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
- pSiS->ShadowPtr = xalloc(pSiS->ShadowPitch * height);
- displayWidth = pSiS->ShadowPitch / (pScrn->bitsPerPixel >> 3);
- FBStart = pSiS->ShadowPtr;
+ pSiS->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pSiS->ShadowPtr = xalloc(pSiS->ShadowPitch * height);
+ displayWidth = pSiS->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pSiS->ShadowPtr;
} else {
- pSiS->ShadowPtr = NULL;
- FBStart = pSiS->FbBase;
+ pSiS->ShadowPtr = NULL;
+ FBStart = pSiS->FbBase;
}
if(!miSetPixmapDepths()) {
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "miSetPixmapDepths() failed\n");
- return FALSE;
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISErrorLog(pScrn, "miSetPixmapDepths() failed\n");
+ return FALSE;
}
+ /* Point cmdQueuePtr to pSiSEnt for shared usage
+ * (same technique is then eventually used in DRIScreeninit)
+ * For 315/330 series, this is done in EnableTurboQueue
+ * which has already been called during ModeInit().
+ */
#ifdef SISDUALHEAD
if(pSiS->SecondHead)
- pSiS->cmdQueueLenPtr = &(SISPTR(pSiSEnt->pScrn_1)->cmdQueueLen);
+ pSiS->cmdQueueLenPtr = &(SISPTR(pSiSEnt->pScrn_1)->cmdQueueLen);
else
#endif
- pSiS->cmdQueueLenPtr = &(pSiS->cmdQueueLen);
+ pSiS->cmdQueueLenPtr = &(pSiS->cmdQueueLen);
- pSiS->cmdQueueLen = 0; /* TW: Force an EngineIdle() at start */
+ pSiS->cmdQueueLen = 0; /* Force an EngineIdle() at start */
#ifdef XF86DRI
+ if(pSiS->loadDRI) {
#ifdef SISDUALHEAD
- /* TW: No DRI in dual head mode */
- if(pSiS->DualHeadMode) {
- pSiS->directRenderingEnabled = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ /* No DRI in dual head mode */
+ if(pSiS->DualHeadMode) {
+ pSiS->directRenderingEnabled = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"DRI not supported in Dual Head mode\n");
- } else
+ } else
#endif
- /* Force the initialization of the context */
- if(pSiS->VGAEngine != SIS_315_VGA) {
- pSiS->directRenderingEnabled = SISDRIScreenInit(pScreen);
+ /* Force the initialization of the context */
+ if(pSiS->VGAEngine != SIS_315_VGA) {
+ pSiS->directRenderingEnabled = SISDRIScreenInit(pScreen);
} else {
xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED,
- "DRI not supported on this chipset\n");
+ "DRI not supported on this chipset\n");
pSiS->directRenderingEnabled = FALSE;
}
+ }
#endif
/*
* Call the framebuffer layer's ScreenInit function, and fill in other
* pScreen fields.
*/
-
switch(pScrn->bitsPerPixel) {
- case 1:
- ret = xf1bppScreenInit(pScreen, FBStart, width,
- height, pScrn->xDpi, pScrn->yDpi,
- displayWidth);
- break;
- case 4:
- ret = xf4bppScreenInit(pScreen, FBStart, width,
- height, pScrn->xDpi, pScrn->yDpi,
- displayWidth);
- break;
+ case 24:
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
+ ret = FALSE;
+ break;
+ }
case 8:
case 16:
- case 24:
case 32:
ret = fbScreenInit(pScreen, FBStart, width,
height, pScrn->xDpi, pScrn->yDpi,
displayWidth, pScrn->bitsPerPixel);
-
- init_picture = 1;
break;
default:
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Internal error: invalid bpp (%d) in SISScrnInit\n",
- pScrn->bitsPerPixel);
- ret = FALSE;
+ ret = FALSE;
break;
}
- if (!ret) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf1bpp/xf4bpp/fbScreenInit() failed\n");
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
- return FALSE;
+ if(!ret) {
+ SISErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n",
+ pScrn->bitsPerPixel);
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ return FALSE;
}
if(pScrn->bitsPerPixel > 8) {
- /* Fixup RGB ordering */
- 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) {
- SIS1bppColorMap(pScrn);
+ /* Fixup RGB ordering */
+ 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;
+ }
+ }
}
/* Initialize RENDER ext; must be after RGB ordering fixed */
- if(init_picture) fbPictureInit(pScreen, 0, 0);
+ fbPictureInit(pScreen, 0, 0);
/* hardware cursor needs to wrap this layer <-- TW: what does that mean? */
- if(!pSiS->ShadowFB) SISDGAInit(pScreen);
+ if(!pSiS->ShadowFB) SISDGAInit(pScreen);
xf86SetBlackWhitePixels(pScreen);
if(!pSiS->NoAccel) {
- switch(pSiS->VGAEngine) {
+ switch(pSiS->VGAEngine) {
case SIS_530_VGA:
case SIS_300_VGA:
SiS300AccelInit(pScreen);
break;
case SIS_315_VGA:
- SiS310AccelInit(pScreen);
+ SiS315AccelInit(pScreen);
break;
default:
SiSAccelInit(pScreen);
- }
+ }
}
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -4759,26 +6748,33 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* Initialise cursor functions */
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
- if(pSiS->HWCursor)
- SiSHWCursorInit(pScreen);
+ if(pSiS->HWCursor) {
+ SiSHWCursorInit(pScreen);
+ }
/* Initialise default colourmap */
if(!miCreateDefColormap(pScreen)) {
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "miCreateDefColormap() failed\n");
- return FALSE;
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISErrorLog(pScrn, "miCreateDefColormap() failed\n");
+ return FALSE;
}
-
+
if(!xf86HandleColormaps(pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
SISLoadPalette, NULL,
CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "xf86HandleColormaps() failed\n");
- return FALSE;
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISErrorLog(pScrn, "xf86HandleColormaps() failed\n");
+ return FALSE;
}
+#if 0
+ if((pSiS->GammaBriR != 1000) || (pSiS->GammaBriG != 1000) ||
+ (pSiS->GammaBriB != 1000) || (pSiS->GammaPBriR != 1000) ||
+ (pSiS->GammaPBriG != 1000) || (pSiS->GammaPBriB != 1000)) {
+ SISCalculateGammaRamp(pScrn);
+ }
+#endif
+
if(pSiS->ShadowFB) {
RefreshAreaFuncPtr refreshArea = SISRefreshArea;
@@ -4794,104 +6790,114 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
case 24: refreshArea = SISRefreshArea24; break;
case 32: refreshArea = SISRefreshArea32; break;
}
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,0,0,0)
+ xf86DisableRandR();
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Driver rotation enabled, RandR disabled\n");
+#endif
}
ShadowFBInit(pScreen, refreshArea);
}
-#ifdef SISDUALHEAD
- if(pSiS->DualHeadMode)
- /* TW: DPMS for dual head mode */
- xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSetDH, 0);
- else
-#endif
- xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0);
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0);
/* Init memPhysBase and fbOffset in pScrn */
pScrn->memPhysBase = pSiS->FbAddress;
pScrn->fbOffset = 0;
+
+ pSiS->ResetXv = pSiS->ResetXvGamma = NULL;
-#ifdef XvExtension
+#if (XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,99,0,0)) || (defined(XvExtension))
if(!pSiS->NoXvideo) {
-#ifdef SISDUALHEAD
- /* TW: On chipsets with only one overlay, we support
- * Xv only in "real" dual head mode, not Xinerama
- */
- if ( ((pSiS->VGAEngine == SIS_300_VGA) ||
- (pSiS->VGAEngine == SIS_315_VGA) )
- &&
- ((pSiS->hasTwoOverlays) ||
- (!pSiS->DualHeadMode) ||
- (noPanoramiXExtension) ) ) {
-#else
- if ( (pSiS->VGAEngine == SIS_300_VGA) ||
- (pSiS->VGAEngine == SIS_315_VGA) ) {
-#endif
-#ifdef SISDUALHEAD
- if (pSiS->DualHeadMode) {
- if ( pSiS->hasTwoOverlays ||
- (pSiS->XvOnCRT2 && (!pSiS->SecondHead)) ||
- ((!pSiS->XvOnCRT2 && pSiS->SecondHead)) ) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using SiS300/310/325 series HW Xv on CRT%d\n",
- (pSiS->SecondHead ? 1 : 2));
- SISInitVideo(pScreen);
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using SiS300/310/325 series HW Xv on CRT%d\n",
- (pSiS->SecondHead ? 1 : 2));
+ if( (pSiS->VGAEngine == SIS_300_VGA) ||
+ (pSiS->VGAEngine == SIS_315_VGA) ) {
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using SiS300/315 series HW Xv on CRT%d\n",
+ (pSiS->SecondHead ? 1 : 2));
+ if(!pSiS->hasTwoOverlays) {
+ if( (pSiS->XvOnCRT2 && pSiS->SecondHead) ||
+ (!pSiS->XvOnCRT2 && !pSiS->SecondHead) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "However, overlay will by default only be visible on CRT%d\n",
+ pSiS->XvOnCRT2 ? 2 : 1);
+ }
}
+ SISInitVideo(pScreen);
} else {
#endif
- if (pSiS->hasTwoOverlays)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using SiS300/310/325 series HW Xv\n" );
+ if(pSiS->hasTwoOverlays)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using SiS300/315/330 series HW Xv\n" );
else
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using SiS300/310/325 series HW Xv on CRT%d\n",
- (pSiS->XvOnCRT2 ? 2 : 1));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using SiS300/315/330 series HW Xv by default on CRT%d\n",
+ (pSiS->XvOnCRT2 ? 2 : 1));
SISInitVideo(pScreen);
#ifdef SISDUALHEAD
}
#endif
-#ifdef USE6326VIDEO
} else if( pSiS->Chipset == PCI_CHIP_SIS6326 ||
pSiS->Chipset == PCI_CHIP_SIS530 ||
pSiS->Chipset == PCI_CHIP_SIS5597 ) {
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Using SiS5597/5598/6326/530/620 HW Xv\n" );
SIS6326InitVideo(pScreen);
-#endif
+
} else { /* generic Xv */
XF86VideoAdaptorPtr *ptr;
int n;
n = xf86XVListGenericAdaptors(pScrn, &ptr);
- if (n) {
+ if(n) {
xf86XVScreenInit(pScreen, ptr, n);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using generic Xv\n" );
}
- if (!noPanoramiXExtension)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "HW Xv not supported in Xinerama mode\n");
+
}
}
#endif
#ifdef XF86DRI
- if(pSiS->directRenderingEnabled) {
- /* Now that mi, drm and others have done their thing,
- * complete the DRI setup.
- */
- pSiS->directRenderingEnabled = SISDRIFinishScreenInit(pScreen);
+ if(pSiS->loadDRI) {
+ if(pSiS->directRenderingEnabled) {
+ /* Now that mi, drm and others have done their thing,
+ * complete the DRI setup.
+ */
+ pSiS->directRenderingEnabled = SISDRIFinishScreenInit(pScreen);
+ }
+ if(pSiS->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
+ /* TODO */
+ /* SISSetLFBConfig(pSiS); */
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n");
+ }
}
- if(pSiS->directRenderingEnabled) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
- /* TODO */
- /* SISSetLFBConfig(pSiS); */
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n");
+#endif
+
+ /* Wrap some funcs and setup remaining SD flags */
+
+ pSiS->SiS_SD_Flags &= ~(SiS_SD_PSEUDOXINERAMA);
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ pSiS->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = SISMergePointerMoved;
+ pSiS->Rotate = FALSE;
+ pSiS->ShadowFB = FALSE;
+#ifdef SISXINERAMA
+ if(pSiS->UseSiSXinerama) {
+ SiSnoPanoramiXExtension = FALSE;
+ SiSXineramaExtensionInit(pScrn);
+ if(!SiSnoPanoramiXExtension) {
+ pSiS->SiS_SD_Flags |= SiS_SD_PSEUDOXINERAMA;
+ }
+ }
+#endif
}
#endif
@@ -4899,10 +6905,10 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScreen->CloseScreen = SISCloseScreen;
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode)
- pScreen->SaveScreen = SISSaveScreenDH;
+ pScreen->SaveScreen = SISSaveScreenDH;
else
#endif
- pScreen->SaveScreen = SISSaveScreen;
+ pScreen->SaveScreen = SISSaveScreen;
/* Install BlockHandler */
pSiS->BlockHandler = pScreen->BlockHandler;
@@ -4910,18 +6916,45 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* Report any unused options (only for the first generation) */
if(serverGeneration == 1) {
- xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
}
+ /* Clear frame buffer */
+ /* For CRT2, we don't do that at this point in dual head
+ * mode since the mode isn't switched at this time (it will
+ * be reset when setting the CRT1 mode). Hence, we just
+ * save the necessary data and clear the screen when
+ * going through this for CRT1.
+ */
+
+ OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
+ * (pScrn->bitsPerPixel >> 3);
+
/* Turn on the screen now */
- /* TW: We do this in dual head mode after second head is finished */
+ /* We do this in dual head mode after second head is finished */
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
- if(pSiS->SecondHead)
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
- } else
+ if(pSiS->SecondHead) {
+ bzero(pSiS->FbBase, OnScreenSize);
+ bzero(pSiSEnt->FbBase1, pSiSEnt->OnScreenSize1);
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ } else {
+ pSiSEnt->FbBase1 = pSiS->FbBase;
+ pSiSEnt->OnScreenSize1 = OnScreenSize;
+ }
+ } else {
#endif
- SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ SISSaveScreen(pScreen, SCREEN_SAVER_OFF);
+ bzero(pSiS->FbBase, OnScreenSize);
+#ifdef SISDUALHEAD
+ }
+#endif
+
+ pSiS->SiS_SD_Flags &= ~SiS_SD_ISDEPTH8;
+ if(pSiS->CurrentLayout.bitsPerPixel == 8) {
+ pSiS->SiS_SD_Flags |= SiS_SD_ISDEPTH8;
+ pSiS->SiS_SD_Flags &= ~SiS_SD_SUPPORTXVGAMMA1;
+ }
return TRUE;
}
@@ -4935,187 +6968,701 @@ SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
if(!pSiS->NoAccel) {
if(pSiS->AccelInfoPtr) {
- (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
}
}
- return SISModeInit(xf86Screens[scrnIndex], mode);
+ if(!(SISModeInit(xf86Screens[scrnIndex], mode))) return FALSE;
+
+ /* Since RandR (indirectly) uses SwitchMode(), we need to
+ * update our Xinerama info here, too, in case of resizing
+ */
+#ifdef SISMERGED
+#ifdef SISXINERAMA
+ if(pSiS->MergedFB) {
+ SiSUpdateXineramaScreenInfo(pScrn);
+ }
+#endif
+#endif
+ return TRUE;
}
-#ifdef CYCLECRT2
-/* TW: Cycle CRT2 output devices */
Bool
-SISCycleCRT2Type(int scrnIndex, DisplayModePtr mode)
+SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags)
{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
SISPtr pSiS = SISPTR(pScrn);
- int i = 0;
+ BOOLEAN hcm;
+ DisplayModePtr mode = pScrn->currentMode;
- /* TW: Only on 300 and 310/325 series */
+ /* Do NOT use this to switch from CRT2_LCD to CRT1_LCDA */
+
+ /* Only on 300 and 315/330 series */
if(pSiS->VGAEngine != SIS_300_VGA &&
pSiS->VGAEngine != SIS_315_VGA) return FALSE;
- /* TW: Only if there is a video bridge */
- if(pSiS->VBFlags & VB_VIDEOBRIDGE) return FALSE;
+ /* Only if there is a video bridge */
+ if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return FALSE;
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) return FALSE;
+#endif
+
+#define SiS_NewVBMask (CRT2_ENABLE|CRT1_LCDA|TV_PAL|TV_NTSC|TV_PALM|TV_PALN|TV_NTSCJ|TV_AVIDEO|TV_SVIDEO|TV_SCART)
+
+ newvbflags &= SiS_NewVBMask;
+ newvbflags |= pSiS->VBFlags & ~SiS_NewVBMask;
+
+ if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTLCDA)) {
+ newvbflags &= ~CRT1_LCDA;
+ }
+
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ if(!(newvbflags & CRT2_ENABLE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "CRT2 can't be switched off in MergedFB mode\n");
+ return FALSE;
+ }
+ hcm = pSiS->HaveCustomModes2;
+ if(mode->Private) {
+ mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2;
+ }
+ } else
+#endif
+ hcm = pSiS->HaveCustomModes;
+
+ if((!(newvbflags & CRT2_ENABLE)) && (!newvbflags & DISPTYPE_CRT1)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "CRT2 can't be switched off while CRT1 is off\n");
+ return FALSE;
+ }
- /* TW: Only if there were more than 1 CRT2 devices detected */
- if(pSiS->detectedCRT2Devices & CRT2_VGA) i++;
- if(pSiS->detectedCRT2Devices & CRT2_LCD) i++;
- if(pSiS->detectedCRT2Devices & CRT2_TV) i++;
- if(i <= 1) return FALSE;
+ /* CRT2_LCD overrules LCDA */
+ if(newvbflags & CRT2_LCD) {
+ newvbflags &= ~CRT1_LCDA;
+ }
- /* TW: Cycle CRT2 type */
- i = (pSiS->VBFlags & DISPTYPE_DISP2) << 1;
- while(!(i & pSiS->detectedCRT2Devices)) {
- i <<= 1;
- if(i > CRT2_VGA) i = CRT2_LCD;
+ /* Check if the current mode is suitable for desired output device (if any) */
+ if(newvbflags & CRT2_ENABLE) {
+ if(!SiS_CheckCalcModeIndex(pScrn, mode, newvbflags, hcm)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Current mode not suitable for desired CRT2 output device\n");
+ return FALSE;
+ }
}
- /* TW: Check if mode is suitable for desired output device */
- if(!SiS_CheckCalcModeIndex(pScrn, pScrn->currentMode,
- ((pSiS->VBFlags & ~(DISPTYPE_DISP2)) | i))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Current mode not suitable for desired CRT2 output device\n");
- return FALSE;
+ /* Remember: Dualhead not supported */
+ newvbflags &= ~(SINGLE_MODE | MIRROR_MODE);
+ if((newvbflags & DISPTYPE_CRT1) && (newvbflags & CRT2_ENABLE)) {
+ newvbflags |= MIRROR_MODE;
+ } else {
+ newvbflags |= SINGLE_MODE;
}
- /* TW: Sync the accelerators */
+ /* Sync the accelerators */
if(!pSiS->NoAccel) {
- if(pSiS->AccelInfoPtr) {
- (*pSiS->AccelInfoPtr->Sync)(pScrn);
- }
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ }
}
- pSiS->VBFlags &= ~(DISPTYPE_DISP2);
- pSiS->VBFlags |= i;
+ pSiS->VBFlags = pSiS->VBFlags_backup = newvbflags;
- return SISModeInit(xf86Screens[scrnIndex], mode);
+ if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE;
+ SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+Bool
+SISCheckModeIndexForCRT2Type(ScrnInfoPtr pScrn, unsigned short cond, unsigned short index, Bool quiet)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ BOOLEAN hcm = pSiS->HaveCustomModes;
+ DisplayModePtr mode = pScrn->modes, mastermode;
+ int i;
+ unsigned long vbflags = pSiS->VBFlags;
+
+ /* This has been extended to handle LCDA as well */
+
+ /* Only on 300 and 315/330 series */
+ if(pSiS->VGAEngine != SIS_300_VGA &&
+ pSiS->VGAEngine != SIS_315_VGA) return FALSE;
+
+ /* Mode is OK if there is no video bridge */
+ /* (Requires screen size check in app) */
+ if(!(pSiS->VBFlags & VB_VIDEOBRIDGE)) return TRUE;
+
+ /* No special treatment for NTSC-J here */
+ if(cond) {
+ vbflags &= ~(CRT2_ENABLE | TV_TYPE | TV_PALM | TV_PALN | CRT1_LCDA);
+ if(cond & SiS_CF2_LCD) {
+ vbflags |= CRT2_LCD;
+ } else if(cond & SiS_CF2_TV) {
+ vbflags |= CRT2_TV;
+ if(cond & SiS_CF2_TVPAL) vbflags |= TV_PAL;
+ else if(cond & SiS_CF2_TVPALM) vbflags |= (TV_PAL | TV_PALM);
+ else if(cond & SiS_CF2_TVPALN) vbflags |= (TV_PAL | TV_PALN);
+ else if(cond & SiS_CF2_TVNTSC) vbflags |= TV_NTSC;
+ } else if(cond & SiS_CF2_VGA2) {
+ vbflags |= CRT2_VGA;
+ } else if(cond & SiS_CF2_CRT1LCDA) {
+ vbflags |= CRT1_LCDA;
+ }
+ }
+
+ /* Mode is obviously OK if video bridge is disabled */
+ /* (Requires extra check for eventual screen size problems in app) */
+ if(!(vbflags & (CRT2_ENABLE | CRT1_LCDA))) return TRUE;
+
+ /* Find mode of given index */
+ if(index) {
+ for(i = 0; i < index; i++) {
+ if(!mode) return FALSE;
+ mode = mode->next;
+ }
+ }
+
+ mastermode = mode;
+
+#ifdef SISDUALHEAD
+ if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) {
+#endif
+
+ if(vbflags & CRT2_ENABLE) {
+
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ hcm = pSiS->HaveCustomModes2;
+ if(mode->Private) {
+ mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2;
+ }
+ }
+#endif
+
+ /* For RandR */
+ if((mode->HDisplay > pScrn->virtualX) || (mode->VDisplay > pScrn->virtualY)) {
+ if(!quiet) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Desired mode too large for current screen size\n");
+ }
+ return FALSE;
+ }
+
+ /* Check if the desired mode is suitable for current CRT2 output device */
+ if(!SiS_CheckCalcModeIndex(pScrn, mode, vbflags, hcm)) {
+ if((!cond) && (!quiet)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Desired mode not suitable for current CRT2 output device\n");
+ }
+ return FALSE;
+ }
+
+ }
+
+#ifdef SISDUALHEAD
+ }
+#endif
+
+ mode = mastermode;
+
+#ifdef SISDUALHEAD
+ if((!pSiS->DualHeadMode) || (pSiS->SecondHead)) {
+#endif
+
+ if(vbflags & CRT1_LCDA) {
+
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ hcm = pSiS->HaveCustomModes;
+ if(mode->Private) {
+ mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1;
+ }
+ }
+#endif
+
+ /* For RandR */
+ if((mode->HDisplay > pScrn->virtualX) || (mode->VDisplay > pScrn->virtualY)) {
+ if(!quiet) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Desired mode too large for current screen size\n");
+ }
+ return FALSE;
+ }
+
+ /* Check if the desired mode is suitable for current CRT1 output device */
+ if(!SiS_CalcModeIndex(pScrn, mode, vbflags, hcm)) {
+ if((!cond) && (!quiet)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Desired mode not suitable for current CRT1 output device\n");
+ }
+ return FALSE;
+ }
+
+ }
+
+#ifdef SISDUALHEAD
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool
+SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ DisplayModePtr mode = pScrn->currentMode;
+ unsigned long vbflags = pSiS->VBFlags;
+ int crt1off;
+
+ /* onoff: 0=OFF, 1=ON(VGA), 2=ON(LCDA) */
+ /* Switching to LCDA will disable CRT2 if previously LCD */
+
+ /* Do NOT use this to switch from CRT1_LCDA to CRT2_LCD */
+
+ /* Only on 300 and 315/330 series */
+ if(pSiS->VGAEngine != SIS_300_VGA &&
+ pSiS->VGAEngine != SIS_315_VGA) return FALSE;
+
+ /* Off only if at least one CRT2 device is active */
+ if((!onoff) && (!(vbflags & CRT2_ENABLE))) return FALSE;
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) return FALSE;
+#endif
+
+ /* Can't switch to LCDA of not supported (duh!) */
+ if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTLCDA)) {
+ if(onoff == 2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "LCD-via-CRT1 not supported on this hardware\n");
+ return FALSE;
+ }
+ }
+
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ if(!onoff) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "CRT1 can't be switched off in MergedFB mode\n");
+ return FALSE;
+ } else if(onoff == 2) {
+ if(vbflags & CRT2_LCD) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "CRT2 type can't be LCD while CRT1 is LCD-via-CRT1\n");
+ return FALSE;
+ }
+ }
+ if(mode->Private) {
+ mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1;
+ }
+ }
+#endif
+
+ vbflags &= ~(DISPTYPE_CRT1 | SINGLE_MODE | MIRROR_MODE | CRT1_LCDA);
+ crt1off = 1;
+ if(onoff > 0) {
+ vbflags |= DISPTYPE_CRT1;
+ crt1off = 0;
+ if(onoff == 2) {
+ vbflags |= CRT1_LCDA;
+ vbflags &= ~CRT2_LCD;
+ }
+ /* Remember: Dualhead not supported */
+ if(vbflags & CRT2_ENABLE) vbflags |= MIRROR_MODE;
+ else vbflags |= SINGLE_MODE;
+ } else {
+ vbflags |= SINGLE_MODE;
+ }
+
+ if(vbflags & CRT1_LCDA) {
+ if(!SiS_CalcModeIndex(pScrn, mode, vbflags, pSiS->HaveCustomModes)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Current mode not suitable for LCD-via-CRT1\n");
+ return FALSE;
+ }
+ }
+
+ pSiS->CRT1off = crt1off;
+ pSiS->VBFlags = pSiS->VBFlags_backup = vbflags;
+
+ /* Sync the accelerators */
+ if(!pSiS->NoAccel) {
+ if(pSiS->AccelInfoPtr) {
+ (*pSiS->AccelInfoPtr->Sync)(pScrn);
+ }
+ }
+
+ if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE;
+ SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+static void
+SISSetStartAddressCRT1(SISPtr pSiS, unsigned long base)
+{
+ unsigned char cr11backup;
+
+ inSISIDXREG(SISCR, 0x11, cr11backup); /* Unlock CRTC registers */
+ andSISIDXREG(SISCR, 0x11, 0x7F);
+ outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
+ outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
+ }
+ /* Eventually lock CRTC registers */
+ setSISIDXREG(SISCR, 0x11, 0x7F,(cr11backup & 0x80));
+}
+
+static void
+SISSetStartAddressCRT2(SISPtr pSiS, unsigned long base)
+{
+ SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext);
+ outSISIDXREG(SISPART1, 0x06, GETVAR8(base));
+ outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8));
+ outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16));
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
+ }
+ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext);
+}
+
+#ifdef SISMERGED
+Bool
+InRegion(int x, int y, region r)
+{
+ return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
+}
+
+static void
+SISAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned long base;
+
+ base = y * pSiS->CurrentLayout.displayWidth + x;
+ switch(pSiS->CurrentLayout.bitsPerPixel) {
+ case 16: base >>= 1; break;
+ case 32: break;
+ default: base >>= 2;
+ }
+ SISSetStartAddressCRT1(pSiS, base);
+}
+
+static void
+SISAdjustFrameHW_CRT2(ScrnInfoPtr pScrn, int x, int y)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned long base;
+
+ base = y * pSiS->CurrentLayout.displayWidth + x;
+ switch(pSiS->CurrentLayout.bitsPerPixel) {
+ case 16: base >>= 1; break;
+ case 32: break;
+ default: base >>= 2;
+ }
+ SISSetStartAddressCRT2(pSiS, base);
+}
+
+static void
+SISMergePointerMoved(int scrnIndex, int x, int y)
+{
+ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+ SISPtr pSiS = SISPTR(pScrn1);
+ ScrnInfoPtr pScrn2 = pSiS->CRT2pScrn;
+ region out, in1, in2, f2, f1;
+ int deltax, deltay;
+
+ f1.x0 = pSiS->CRT1frameX0;
+ f1.x1 = pSiS->CRT1frameX1;
+ f1.y0 = pSiS->CRT1frameY0;
+ f1.y1 = pSiS->CRT1frameY1;
+ f2.x0 = pScrn2->frameX0;
+ f2.x1 = pScrn2->frameX1;
+ f2.y0 = pScrn2->frameY0;
+ f2.y1 = pScrn2->frameY1;
+
+ /* Define the outer region. Crossing this causes all frames to move */
+ out.x0 = pScrn1->frameX0;
+ out.x1 = pScrn1->frameX1;
+ out.y0 = pScrn1->frameY0;
+ out.y1 = pScrn1->frameY1;
+
+ /*
+ * Define the inner sliding window. Being outsize both frames but
+ * inside the outer clipping window will slide corresponding frame
+ */
+ in1 = out;
+ in2 = out;
+ switch(((SiSMergedDisplayModePtr)pSiS->CurrentLayout.mode->Private)->CRT2Position) {
+ case sisLeftOf:
+ in1.x0 = f1.x0;
+ in2.x1 = f2.x1;
+ break;
+ case sisRightOf:
+ in1.x1 = f1.x1;
+ in2.x0 = f2.x0;
+ break;
+ case sisBelow:
+ in1.y1 = f1.y1;
+ in2.y0 = f2.y0;
+ break;
+ case sisAbove:
+ in1.y0 = f1.y0;
+ in2.y1 = f2.y1;
+ break;
+ case sisClone:
+ break;
+ }
+
+ deltay = 0;
+ deltax = 0;
+
+ if(InRegion(x, y, out)) { /* inside outer region */
+
+ if(InRegion(x, y, in1) && !InRegion(x, y, f1)) {
+ REBOUND(f1.x0, f1.x1, x);
+ REBOUND(f1.y0, f1.y1, y);
+ deltax = 1;
+ }
+ if(InRegion(x, y, in2) && !InRegion(x, y, f2)) {
+ REBOUND(f2.x0, f2.x1, x);
+ REBOUND(f2.y0, f2.y1, y);
+ deltax = 1;
+ }
+
+ } else { /* outside outer region */
+
+ if(out.x0 > x) {
+ deltax = x - out.x0;
+ }
+ if(out.x1 < x) {
+ deltax = x - out.x1;
+ }
+ if(deltax) {
+ pScrn1->frameX0 += deltax;
+ pScrn1->frameX1 += deltax;
+ f1.x0 += deltax;
+ f1.x1 += deltax;
+ f2.x0 += deltax;
+ f2.x1 += deltax;
+ }
+
+ if(out.y0 > y) {
+ deltay = y - out.y0;
+ }
+ if(out.y1 < y) {
+ deltay = y - out.y1;
+ }
+ if(deltay) {
+ pScrn1->frameY0 += deltay;
+ pScrn1->frameY1 += deltay;
+ f1.y0 += deltay;
+ f1.y1 += deltay;
+ f2.y0 += deltay;
+ f2.y1 += deltay;
+ }
+
+ switch(((SiSMergedDisplayModePtr)pSiS->CurrentLayout.mode->Private)->CRT2Position) {
+ case sisLeftOf:
+ if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); }
+ if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); }
+ break;
+ case sisRightOf:
+ if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); }
+ if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); }
+ break;
+ case sisBelow:
+ if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); }
+ if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); }
+ break;
+ case sisAbove:
+ if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); }
+ if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); }
+ break;
+ case sisClone:
+ break;
+ }
+
+ }
+
+ if(deltax || deltay) {
+ pSiS->CRT1frameX0 = f1.x0;
+ pSiS->CRT1frameY0 = f1.y0;
+ pScrn2->frameX0 = f2.x0;
+ pScrn2->frameY0 = f2.y0;
+
+ pSiS->CRT1frameX1 = pSiS->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
+ pSiS->CRT1frameY1 = pSiS->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
+ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
+ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
+ pScrn1->frameX1 = pScrn1->frameX0 + pSiS->CurrentLayout.mode->HDisplay - 1;
+ pScrn1->frameY1 = pScrn1->frameY0 + pSiS->CurrentLayout.mode->VDisplay - 1;
+
+ SISAdjustFrameHW_CRT1(pScrn1, pSiS->CRT1frameX0, pSiS->CRT1frameY0);
+ SISAdjustFrameHW_CRT2(pScrn1, pScrn2->frameX0, pScrn2->frameY0);
+ }
+}
+
+static void
+SISAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+ SISPtr pSiS = SISPTR(pScrn1);
+ ScrnInfoPtr pScrn2 = pSiS->CRT2pScrn;
+ int VTotal = pSiS->CurrentLayout.mode->VDisplay;
+ int HTotal = pSiS->CurrentLayout.mode->HDisplay;
+ int VMax = VTotal;
+ int HMax = HTotal;
+
+ BOUND(x, 0, pScrn1->virtualX - HTotal);
+ BOUND(y, 0, pScrn1->virtualY - VTotal);
+
+ switch(SDMPTR(pScrn1)->CRT2Position) {
+ case sisLeftOf:
+ pScrn2->frameX0 = x;
+ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ pSiS->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay;
+ BOUND(pSiS->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ break;
+ case sisRightOf:
+ pSiS->CRT1frameX0 = x;
+ BOUND(pSiS->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay;
+ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ break;
+ case sisAbove:
+ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+ pScrn2->frameY0 = y;
+ BOUND(pSiS->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+ pSiS->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay;
+ break;
+ case sisBelow:
+ BOUND(pSiS->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+ pSiS->CRT1frameY0 = y;
+ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+ pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay;
+ break;
+ case sisClone:
+ BOUND(pSiS->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+ BOUND(pSiS->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ break;
+ }
+
+ BOUND(pSiS->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
+ BOUND(pSiS->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
+ BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
+ BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
+
+ pScrn1->frameX0 = x;
+ pScrn1->frameY0 = y;
+
+ pSiS->CRT1frameX1 = pSiS->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
+ pSiS->CRT1frameY1 = pSiS->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
+ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
+ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
+ pScrn1->frameX1 = pScrn1->frameX0 + pSiS->CurrentLayout.mode->HDisplay - 1;
+ pScrn1->frameY1 = pScrn1->frameY0 + pSiS->CurrentLayout.mode->VDisplay - 1;
+
+ SISAdjustFrameHW_CRT1(pScrn1, pSiS->CRT1frameX0, pSiS->CRT1frameY0);
+ SISAdjustFrameHW_CRT2(pScrn1, pScrn2->frameX0, pScrn2->frameY0);
}
#endif
/*
* This function is used to initialize the Start Address - the first
* displayed location in the video memory.
+ *
+ * Usually mandatory
*/
-/* Usually mandatory */
void
SISAdjustFrame(int scrnIndex, int x, int y, int flags)
{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- SISPtr pSiS;
- vgaHWPtr hwp;
- int base;
- unsigned char temp;
-
- hwp = VGAHWPTR(pScrn);
- pSiS = SISPTR(pScrn);
-
- base = y * pSiS->CurrentLayout.displayWidth + x;
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned long base;
+ unsigned char temp, cr11backup;
+
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ SISAdjustFrameMerged(scrnIndex, x, y, flags);
+ return;
+ }
+#endif
if(pSiS->UseVESA) {
-
- /* TW: Let BIOS adjust frame if using VESA */
VBESetDisplayStart(pSiS->pVbe, x, y, TRUE);
+ return;
+ }
+ if(pScrn->bitsPerPixel < 8) {
+ base = (y * pSiS->CurrentLayout.displayWidth + x + 3) >> 3;
} else {
+ base = y * pSiS->CurrentLayout.displayWidth + x;
+
+ /* calculate base bpp dep. */
+ switch(pSiS->CurrentLayout.bitsPerPixel) {
+ case 16:
+ base >>= 1;
+ break;
+ case 24:
+ base = ((base * 3)) >> 2;
+ base -= base % 6;
+ break;
+ case 32:
+ break;
+ default: /* 8bpp */
+ base >>= 2;
+ break;
+ }
+ }
#ifdef UNLOCK_ALWAYS
- sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
- if(pScrn->bitsPerPixel < 8) {
- base = (y * pSiS->CurrentLayout.displayWidth + x + 3) >> 3;
- } else {
- base = y * pSiS->CurrentLayout.displayWidth + x;
-
- /* calculate base bpp dep. */
- switch(pSiS->CurrentLayout.bitsPerPixel) {
- case 16:
- base >>= 1;
- break;
- case 24:
- base = ((base * 3)) >> 2;
- base -= base % 6;
- break;
- case 32:
- break;
- default: /* 8bpp */
- base >>= 2;
- break;
- }
- }
-
-#ifdef SISDUALHEAD
- if (pSiS->DualHeadMode) {
- /* TW: We assume that DualHeadMode only can be true for
- * dual head capable chipsets (and thus save the check
- * for chipset here)
- */
- if (!pSiS->SecondHead) {
- /* TW: Head 1 (master) is always CRT2 */
- SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
- outSISIDXREG(SISPART1, 0x06, GETVAR8(base));
- outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8));
- outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16));
- if (pSiS->VGAEngine == SIS_315_VGA) {
- setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
- }
- SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
- } else {
- /* TW: Head 2 (slave) is always CRT1 */
- base += (pSiS->dhmOffset/4);
- outSISIDXREG(SISCR, 0x0D, base & 0xFF);
- outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
- outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
- if (pSiS->VGAEngine == SIS_315_VGA) {
- setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
- }
- }
- } else {
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->SecondHead) {
+ /* Head 1 (master) is always CRT2 */
+ SISSetStartAddressCRT2(pSiS, base);
+ } else {
+ /* TW: Head 2 (slave) is always CRT1 */
+ base += (pSiS->dhmOffset/4);
+ SISSetStartAddressCRT1(pSiS, base);
+ }
+ } else {
#endif
- switch (pSiS->VGAEngine) {
- case SIS_300_VGA:
- outSISIDXREG(SISCR, 0x0D, base & 0xFF);
- outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
- outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
- if (pSiS->VBFlags & CRT2_ENABLE) {
- SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
- outSISIDXREG(SISPART1, 0x06, GETVAR8(base));
- outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8));
- outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16));
- SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
- }
- break;
- case SIS_315_VGA:
- outSISIDXREG(SISCR, 0x0D, base & 0xFF);
- outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
- outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
- setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
- if (pSiS->VBFlags & CRT2_ENABLE) {
- SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
- outSISIDXREG(SISPART1, 0x06, GETVAR8(base));
- outSISIDXREG(SISPART1, 0x05, GETBITS(base, 15:8));
- outSISIDXREG(SISPART1, 0x04, GETBITS(base, 23:16));
- setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
- SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30);
- }
- break;
- default:
- outSISIDXREG(SISCR, 0x0D, base & 0xFF);
- outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
- inSISIDXREG(SISSR, 0x27, temp);
- temp &= 0xF0;
- temp |= (base & 0x0F0000) >> 16;
- outSISIDXREG(SISSR, 0x27, temp);
- }
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA:
+ case SIS_315_VGA:
+ SISSetStartAddressCRT1(pSiS, base);
+ if(pSiS->VBFlags & CRT2_ENABLE) {
+ SISSetStartAddressCRT2(pSiS, base);
+ }
+ break;
+ default:
+ /* Unlock CRTC registers */
+ inSISIDXREG(SISCR, 0x11, cr11backup);
+ andSISIDXREG(SISCR, 0x11, 0x7F);
+ outSISIDXREG(SISCR, 0x0D, base & 0xFF);
+ outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
+ inSISIDXREG(SISSR, 0x27, temp);
+ temp &= 0xF0;
+ temp |= (base & 0x0F0000) >> 16;
+ outSISIDXREG(SISSR, 0x27, temp);
+ /* Eventually lock CRTC registers */
+ setSISIDXREG(SISCR, 0x11, 0x7F, (cr11backup & 0x80));
+ }
#ifdef SISDUALHEAD
- }
+ }
#endif
- } /* if not VESA */
}
-
/*
* This is called when VT switching back to the X server. Its job is
* to reinitialise the video mode.
@@ -5130,19 +7677,26 @@ SISEnterVT(int scrnIndex, int flags)
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
if(!SISModeInit(pScrn, pScrn->currentMode)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "SiSEnterVT: SISModeInit() failed\n");
- return FALSE;
+ SISErrorLog(pScrn, "SiSEnterVT: SISModeInit() failed\n");
+ return FALSE;
}
SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
#ifdef XF86DRI
- /* TW: this is to be done AFTER switching the mode */
- if(pSiS->directRenderingEnabled)
- DRIUnlock(screenInfo.screens[scrnIndex]);
+ /* this is to be done AFTER switching the mode */
+ if(pSiS->directRenderingEnabled) {
+ DRIUnlock(screenInfo.screens[scrnIndex]);
+ }
#endif
+#ifdef SISDUALHEAD
+ if((!pSiS->DualHeadMode) || (!pSiS->SecondHead))
+#endif
+ if(pSiS->ResetXv) {
+ (pSiS->ResetXv)(pScrn);
+ }
+
return TRUE;
}
@@ -5160,10 +7714,10 @@ SISLeaveVT(int scrnIndex, int flags)
#ifdef XF86DRI
ScreenPtr pScreen;
- /* TW: to be done before mode change */
+ /* to be done before mode change */
if(pSiS->directRenderingEnabled) {
- pScreen = screenInfo.screens[scrnIndex];
- DRILock(pScreen, 0);
+ pScreen = screenInfo.screens[scrnIndex];
+ DRILock(pScreen, 0);
}
#endif
@@ -5175,12 +7729,12 @@ SISLeaveVT(int scrnIndex, int flags)
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
if(!pSiS->SecondHead) {
- pSiS->ForceCursorOff = TRUE;
- pSiS->CursorInfoPtr->HideCursor(pScrn);
- SISWaitVBRetrace(pScrn);
- pSiS->ForceCursorOff = FALSE;
+ pSiS->ForceCursorOff = TRUE;
+ pSiS->CursorInfoPtr->HideCursor(pScrn);
+ SISWaitVBRetrace(pScrn);
+ pSiS->ForceCursorOff = FALSE;
}
- } else {
+ } else {
#endif
pSiS->CursorInfoPtr->HideCursor(pScrn);
SISWaitVBRetrace(pScrn);
@@ -5193,20 +7747,29 @@ SISLeaveVT(int scrnIndex, int flags)
if(pSiS->UseVESA) {
- /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2,
- * VBESaveRestore() does not restore CRT1. So we set any mode now,
- * because VBESetVBEMode correctly restores CRT1. Afterwards, we
- * can call VBESaveRestore to restore original mode.
- */
- if ( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)) )
- VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL);
+ /* This is a q&d work-around for a BIOS bug. In case we disabled CRT2,
+ * VBESaveRestore() does not restore CRT1. So we set any mode now,
+ * because VBESetVBEMode correctly restores CRT1. Afterwards, we
+ * can call VBESaveRestore to restore original mode.
+ */
+ if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)))
+ VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL);
- SISVESARestore(pScrn);
+ SISVESARestore(pScrn);
} else {
-
+
SISRestore(pScrn);
-
+
+ }
+
+ /* We use this (otherwise unused) bit to indicate that we are running
+ * to keep sisfb to change the displaymode (this would result in
+ * lethal display corruption upon quitting X or changing to a VT
+ * until a reboot)
+ */
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+ orSISIDXREG(SISCR,0x34,0x80);
}
vgaHWLock(hwp);
@@ -5230,15 +7793,15 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen)
#ifdef XF86DRI
if(pSiS->directRenderingEnabled) {
- SISDRICloseScreen(pScreen);
- pSiS->directRenderingEnabled = FALSE;
+ SISDRICloseScreen(pScreen);
+ pSiS->directRenderingEnabled = FALSE;
}
#endif
if(pScrn->vtSema) {
if(pSiS->CursorInfoPtr) {
-#ifdef SISDUALHEAD
+#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
if(!pSiS->SecondHead) {
pSiS->ForceCursorOff = TRUE;
@@ -5246,26 +7809,26 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen)
SISWaitVBRetrace(pScrn);
pSiS->ForceCursorOff = FALSE;
}
- } else {
+ } else {
#endif
pSiS->CursorInfoPtr->HideCursor(pScrn);
SISWaitVBRetrace(pScrn);
-#ifdef SISDUALHEAD
- }
-#endif
+#ifdef SISDUALHEAD
+ }
+#endif
}
SISBridgeRestore(pScrn);
if(pSiS->UseVESA) {
- /* TW: This is a q&d work-around for a BIOS bug. In case we disabled CRT2,
- * VBESaveRestore() does not restore CRT1. So we set any mode now,
- * because VBESetVBEMode correctly restores CRT1. Afterwards, we
- * can call VBESaveRestore to restore original mode.
+ /* This is a q&d work-around for a BIOS bug. In case we disabled CRT2,
+ * VBESaveRestore() does not restore CRT1. So we set any mode now,
+ * because VBESetVBEMode correctly restores CRT1. Afterwards, we
+ * can call VBESaveRestore to restore original mode.
*/
- if( (pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)))
- VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL);
+ if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (!(pSiS->VBFlags & DISPTYPE_DISP2)))
+ VBESetVBEMode(pSiS->pVbe, (pSiS->SISVESAModeList->n) | 0xc000, NULL);
SISVESARestore(pScrn);
@@ -5278,44 +7841,53 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen)
vgaHWLock(hwp);
}
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+ andSISIDXREG(SISCR,0x34,0x7f);
+ }
+
SISUnmapMem(pScrn);
vgaHWUnmapMem(pScrn);
-
+
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
- pSiSEnt = pSiS->entityPrivate;
- pSiSEnt->refCount--;
+ pSiSEnt = pSiS->entityPrivate;
+ pSiSEnt->refCount--;
}
-#endif
+#endif
if(pSiS->pInt) {
- xf86FreeInt10(pSiS->pInt);
- pSiS->pInt = NULL;
+ xf86FreeInt10(pSiS->pInt);
+ pSiS->pInt = NULL;
+ }
+
+ if(pSiS->AccelLinearScratch) {
+ xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
+ pSiS->AccelLinearScratch = NULL;
}
if(pSiS->AccelInfoPtr) {
- XAADestroyInfoRec(pSiS->AccelInfoPtr);
- pSiS->AccelInfoPtr = NULL;
+ XAADestroyInfoRec(pSiS->AccelInfoPtr);
+ pSiS->AccelInfoPtr = NULL;
}
if(pSiS->CursorInfoPtr) {
- xf86DestroyCursorInfoRec(pSiS->CursorInfoPtr);
- pSiS->CursorInfoPtr = NULL;
+ xf86DestroyCursorInfoRec(pSiS->CursorInfoPtr);
+ pSiS->CursorInfoPtr = NULL;
}
if(pSiS->ShadowPtr) {
- xfree(pSiS->ShadowPtr);
- pSiS->ShadowPtr = NULL;
+ xfree(pSiS->ShadowPtr);
+ pSiS->ShadowPtr = NULL;
}
if(pSiS->DGAModes) {
- xfree(pSiS->DGAModes);
- pSiS->DGAModes = NULL;
+ xfree(pSiS->DGAModes);
+ pSiS->DGAModes = NULL;
}
if(pSiS->adaptor) {
- xfree(pSiS->adaptor);
- pSiS->adaptor = NULL;
+ xfree(pSiS->adaptor);
+ pSiS->adaptor = NULL;
}
pScrn->vtSema = FALSE;
@@ -5324,7 +7896,8 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen)
pScreen->BlockHandler = pSiS->BlockHandler;
pScreen->CloseScreen = pSiS->CloseScreen;
- return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+
+ return(*pScreen->CloseScreen)(scrnIndex, pScreen);
}
@@ -5334,116 +7907,150 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen)
static void
SISFreeScreen(int scrnIndex, int flags)
{
- if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
- vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ if(xf86LoaderCheckSymbol("vgaHWFreeHWRec")) {
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ }
+
SISFreeRec(xf86Screens[scrnIndex]);
}
/* Checks if a mode is suitable for the selected chipset. */
-/* Optional */
-static int
+static ModeStatus
SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
SISPtr pSiS = SISPTR(pScrn);
if(pSiS->UseVESA) {
- if(SiSCalcVESAModeIndex(pScrn, mode))
- return(MODE_OK);
- else
- return(MODE_BAD);
+ if(SiSCalcVESAModeIndex(pScrn, mode))
+ return(MODE_OK);
+ else
+ return(MODE_BAD);
}
+
if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
#ifdef SISDUALHEAD
- if((pSiS->DualHeadMode) && (pSiS->SecondHead)) {
- /* DHM: Only check modes for CRT1 */
- if(SiS_CalcModeIndex(pScrn, mode) < 0x14)
- return(MODE_BAD);
- } else
-#endif
- if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags) < 0x14)
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead) {
+ if(SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14)
+ return(MODE_BAD);
+ } else {
+ if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14)
return(MODE_BAD);
+ }
+ } else
+#endif
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ if(!mode->Private) {
+ if(!pSiS->CheckForCRT2) {
+ if(SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14)
+ return(MODE_BAD);
+ } else {
+ if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes2) < 0x14)
+ return(MODE_BAD);
+ }
+ } else {
+ if(SiS_CalcModeIndex(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT1,
+ pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14)
+ return(MODE_BAD);
+
+ if(SiS_CheckCalcModeIndex(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT2,
+ pSiS->VBFlags, pSiS->HaveCustomModes2) < 0x14)
+ return(MODE_BAD);
+ }
+ } else
+#endif
+ {
+ if(pSiS->VBFlags & CRT1_LCDA) {
+ if(SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14)
+ return(MODE_BAD);
+ }
+ if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14)
+ return(MODE_BAD);
+ }
}
-
+
return(MODE_OK);
}
-/* Do screen blanking */
-
-/* Mandatory */
+/* Do screen blanking
+ *
+ * Mandatory
+ */
static Bool
SISSaveScreen(ScreenPtr pScreen, int mode)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- if ((pScrn != NULL) && pScrn->vtSema) {
+ if((pScrn != NULL) && pScrn->vtSema) {
SISPtr pSiS = SISPTR(pScrn);
- /* enable access to extended sequencer registers */
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
- if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (CRT2_LCD | CRT1_LCDA)) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- if(!xf86IsUnblank(mode)) {
- pSiS->Blank = TRUE;
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- } else {
- pSiS->Blank = FALSE;
- SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
- }
- } else {
- /* if not blanked obtain state of LCD blank flags set by BIOS */
- if(!pSiS->Blank) {
- inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
- }
+ if(pSiS->VGAEngine == SIS_300_VGA) {
- if(!xf86IsUnblank(mode)) {
- pSiS->Blank = TRUE;
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
- } else {
- pSiS->Blank = FALSE;
- /* don't just unblanking; use LCD state set by BIOS */
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ pSiS->Blank = FALSE;
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) {
+ if(!pSiS->Blank) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ pSiS->Blank = FALSE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
}
- }
- } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
- if(!pSiS->Blank) {
- inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
- }
+ if(!pSiS->Blank) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else {
+ pSiS->Blank = FALSE;
+ SiS_Chrontel701xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ pSiS->Blank = FALSE;
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ } else if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ if(!xf86IsUnblank(mode)) {
+ pSiS->Blank = TRUE;
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ pSiS->Blank = FALSE;
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ }
- if(pSiS->VBFlags & VB_CHRONTEL) {
- if(!xf86IsUnblank(mode)) {
- pSiS->Blank = TRUE;
- SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
- } else {
- pSiS->Blank = FALSE;
- SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
- }
- } else if(pSiS->VBFlags & VB_LVDS) {
- if(!xf86IsUnblank(mode)) {
- pSiS->Blank = TRUE;
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
- } else {
- pSiS->Blank = FALSE;
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
- }
- } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
- if(!xf86IsUnblank(mode)) {
- pSiS->Blank = TRUE;
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- } else {
- pSiS->Blank = FALSE;
- SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
- }
}
}
@@ -5454,99 +8061,101 @@ SISSaveScreen(ScreenPtr pScreen, int mode)
}
#ifdef SISDUALHEAD
-/* TW: SaveScreen for dual head mode */
+/* SaveScreen for dual head mode */
static Bool
SISSaveScreenDH(ScreenPtr pScreen, int mode)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ Bool checkit = FALSE;
- if ((pScrn != NULL) && pScrn->vtSema) {
+ if((pScrn != NULL) && pScrn->vtSema) {
- SISPtr pSiS = SISPTR(pScrn);
- if (pSiS->SecondHead) {
+ SISPtr pSiS = SISPTR(pScrn);
- /* Slave head is always CRT1 */
- return vgaHWSaveScreen(pScreen, mode);
+ if((pSiS->SecondHead) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C))) {
- } else {
+ /* Slave head is always CRT1 */
+ if(pSiS->VBFlags & CRT1_LCDA) pSiS->Blank = xf86IsUnblank(mode) ? FALSE : TRUE;
+
+ return vgaHWSaveScreen(pScreen, mode);
- /* Master head is always CRT2 */
+ } else {
- /* We can only blank LCD, not other CRT2 devices */
- if(!(pSiS->VBFlags & CRT2_LCD)) return TRUE;
+ /* Master head is always CRT2 */
+ /* But we land here if CRT1 is LCDA, too */
- /* enable access to extended sequencer registers */
+ /* We can only blank LCD, not other CRT2 devices */
+ if(!(pSiS->VBFlags & (CRT2_LCD|CRT1_LCDA))) return TRUE;
+
+ /* enable access to extended sequencer registers */
#ifdef UNLOCK_ALWAYS
- sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
- if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VGAEngine == SIS_300_VGA) {
- if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) {
- if(!xf86IsUnblank(mode)) {
- pSiS->BlankCRT2 = TRUE;
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- } else {
- pSiS->BlankCRT2 = FALSE;
- SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
- }
+ if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ checkit = TRUE;
+ if(!xf86IsUnblank(mode)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
} else {
- /* if not blanked obtain state of LCD blank flags set by BIOS */
- if(!pSiS->BlankCRT2) {
- inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
- }
-
- if (!xf86IsUnblank(mode)) {
- pSiS->BlankCRT2 = TRUE;
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
- } else {
- pSiS->BlankCRT2 = FALSE;
- /* don't just unblank; use LCD state set by BIOS */
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
- }
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ } else if(pSiS->VBFlags & (VB_LVDS|VB_30xBDH)) {
+ if(!pSiS->BlankCRT2) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ checkit = TRUE;
+ if(!xf86IsUnblank(mode)) {
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
}
+ }
- } else if(pSiS->VGAEngine == SIS_315_VGA) {
+ } else if(pSiS->VGAEngine == SIS_315_VGA) {
- if(!pSiS->BlankCRT2) {
- inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
- }
+ if(!pSiS->BlankCRT2) {
+ inSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
- if(pSiS->VBFlags & VB_CHRONTEL) {
- if(!xf86IsUnblank(mode)) {
- pSiS->BlankCRT2 = TRUE;
- SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
- } else {
- pSiS->BlankCRT2 = FALSE;
- SiS_Chrontel701xBLOn(pSiS->SiS_Pr);
- }
- } else if(pSiS->VBFlags & VB_LVDS) {
- if(!xf86IsUnblank(mode)) {
- pSiS->BlankCRT2 = TRUE;
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
- } else {
- pSiS->BlankCRT2 = FALSE;
- outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
- }
- } else if(pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) {
- if(!xf86IsUnblank(mode)) {
- pSiS->BlankCRT2 = TRUE;
- SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
- } else {
- pSiS->BlankCRT2 = FALSE;
- SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
- }
+ if(pSiS->VBFlags & VB_CHRONTEL) {
+ checkit = TRUE;
+ if(!xf86IsUnblank(mode)) {
+ SiS_Chrontel701xBLOff(pSiS->SiS_Pr);
+ } else {
+ SiS_Chrontel701xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
}
+ } else if(pSiS->VBFlags & VB_LVDS) {
+ checkit = TRUE;
+ if(!xf86IsUnblank(mode)) {
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon | 0x08);
+ } else {
+ outSISIDXREG(SISSR, 0x11, pSiS->LCDon);
+ }
+ } else if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ checkit = TRUE;
+ if(!xf86IsUnblank(mode)) {
+ SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ } else {
+ SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext);
+ }
+ }
- }
- }
+ }
+
+ if(checkit) {
+ if(!pSiS->SecondHead) pSiS->BlankCRT2 = xf86IsUnblank(mode) ? FALSE : TRUE;
+ else if(pSiS->VBFlags & CRT1_LCDA) pSiS->Blank = xf86IsUnblank(mode) ? FALSE : TRUE;
+ }
+
+ }
}
return TRUE;
}
#endif
#ifdef DEBUG
-/* locally used for debug */
static void
SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
@@ -5569,11 +8178,9 @@ SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
#endif
-/* local used for debug */
static void
SISModifyModeInfo(DisplayModePtr mode)
{
-#if 1
if(mode->CrtcHBlankStart == mode->CrtcHDisplay)
mode->CrtcHBlankStart++;
if(mode->CrtcHBlankEnd == mode->CrtcHTotal)
@@ -5582,10 +8189,9 @@ SISModifyModeInfo(DisplayModePtr mode)
mode->CrtcVBlankStart++;
if(mode->CrtcVBlankEnd == mode->CrtcVTotal)
mode->CrtcVBlankEnd--;
-#endif
}
-/* TW: Enable the TurboQueue (For 300 and 310/325 series only) */
+/* Enable the Turboqueue/Commandqueue (For 300 and 315/330 series only) */
void
SiSEnableTurboQueue(ScrnInfoPtr pScrn)
{
@@ -5595,7 +8201,7 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn)
switch (pSiS->VGAEngine) {
case SIS_300_VGA:
- if ((!pSiS->NoAccel) && (pSiS->TurboQueue)) {
+ if((!pSiS->NoAccel) && (pSiS->TurboQueue)) {
/* TQ size is always 512k */
temp = (pScrn->videoRam/64) - 8;
SR26 = temp & 0xFF;
@@ -5606,27 +8212,19 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn)
outSISIDXREG(SISSR, 0x27, SR27);
}
break;
+
case SIS_315_VGA:
- if (!pSiS->NoAccel) {
- /* TW: On 310/325 series, there are three queue modes available
- * which are chosen by setting bits 7:5 in SR26:
+ if(!pSiS->NoAccel) {
+ /* On 315/330 series, there are three queue modes available
+ * which are chosen by setting bits 7:5 in SR26:
* 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
* track of the queue, the FIFO, command parsing and so
* on. This is the one comparable to the 300 series.
* 2. VRAM queue mode (bit 6, 0x40). In this case, one will
- * have to do queue management himself. Register 0x85c4 will
- * hold the location of the next free queue slot, 0x85c8
- * is the "queue read pointer" whose way of working is
- * unknown to me. Anyway, this mode would require a
- * translation of the MMIO commands to some kind of
- * accelerator assembly and writing these commands
- * to the memory location pointed to by 0x85c4.
- * We will not use this, as nobody knows how this
- * "assembly" works, and as it would require a complete
- * re-write of the accelerator code.
+ * have to do queue management himself.
* 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
* queue in AGP memory space.
- * We go MMIO here.
+ * We go VRAM or MMIO here.
* SR26 bit 4 is called "Bypass H/W queue".
* SR26 bit 1 is called "Enable Command Queue Auto Correction"
* SR26 bit 0 resets the queue
@@ -5637,31 +8235,71 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn)
* 11 (0x0C) 4M
* The queue location is to be written to 0x85C0.
*/
-#if 0
- if (pSiS->TurboQueue) {
-#endif
- /* TW: We only use MMIO Cmd Queue, not VRAM or AGP */
- /* TW: Set Command Queue Threshold to max value 11111b */
- outSISIDXREG(SISSR, 0x27, 0x1F);
- /* TW: Syncronous reset for Command Queue */
- outSISIDXREG(SISSR, 0x26, 0x01);
- /* TW: Do some magic (cp readport to writeport) */
- temp = MMIO_IN32(pSiS->IOBase, 0x85C8);
- MMIO_OUT32(pSiS->IOBase, 0x85C4, temp);
- /* TW: Enable MMIO Command Queue mode (0x20),
- * Enable_command_queue_auto_correction (0x02)
- * (no idea, but sounds good, so use it)
- * 512k (0x00) (does this apply to MMIO mode?) */
- outSISIDXREG(SISSR, 0x26, 0x22);
- /* TW: Calc Command Queue position (Q is always 512k)*/
- temp = (pScrn->videoRam - 512) * 1024;
- /* TW: Set Q position */
- MMIO_OUT32(pSiS->IOBase, 0x85C0, temp);
-#if 0
- } else {
- /* TW: Is there a non-TurboQueue mode within MMIO mode? */
+#ifdef SISVRAMQ
+ /* We use VRAM Cmd Queue, not MMIO or AGP */
+ unsigned char tempCR55;
+
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+ pSiS->cmdQ_SharedWritePort = &(pSiSEnt->cmdQ_SharedWritePort_2D);
+ } else
+#endif
+ pSiS->cmdQ_SharedWritePort = &(pSiS->cmdQ_SharedWritePort_2D);
+
+ /* Set Command Queue Threshold to max value 11111b (?) */
+ outSISIDXREG(SISSR, 0x27, 0x1F);
+ /* No idea what this does */
+ inSISIDXREG(SISCR, 0x55, tempCR55) ;
+ andSISIDXREG(SISCR, 0x55, 0x33) ;
+ /* Syncronous reset for Command Queue */
+ outSISIDXREG(SISSR, 0x26, 0x01);
+ MMIO_OUT32(pSiS->IOBase, 0x85c4, 0);
+ /* Enable VRAM Command Queue mode */
+ switch(pSiS->cmdQueueSize) {
+ case 1*1024*1024: SR26 = (0x40 | 0x04 | 0x01); break;
+ case 2*1024*1024: SR26 = (0x40 | 0x08 | 0x01); break;
+ case 4*1024*1024: SR26 = (0x40 | 0x0C | 0x01); break;
+ default:
+ pSiS->cmdQueueSize = 512 * 1024;
+ case 512*1024: SR26 = (0x40 | 0x00 | 0x01);
+ }
+ outSISIDXREG(SISSR, 0x26, SR26);
+ SR26 &= 0xfe;
+ outSISIDXREG(SISSR, 0x26, SR26);
+ pSiS->cmdQ_SharedWritePort_2D = (unsigned long)(MMIO_IN32(pSiS->IOBase, 0x85c8));
+ *(pSiS->cmdQ_SharedWritePort) = pSiS->cmdQ_SharedWritePort_2D;
+ MMIO_OUT32(pSiS->IOBase, 0x85c4, pSiS->cmdQ_SharedWritePort_2D);
+ MMIO_OUT32(pSiS->IOBase, 0x85C0, pSiS->cmdQueueOffset);
+ temp = (unsigned long)pSiS->FbBase;
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+ temp = (unsigned long)pSiSEnt->FbBase;
}
#endif
+ temp += pSiS->cmdQueueOffset;
+ pSiS->cmdQueueBase = (unsigned long *)temp;
+ outSISIDXREG(SISCR, 0x55, tempCR55);
+#else
+ /* For MMIO */
+ /* Set Command Queue Threshold to max value 11111b */
+ outSISIDXREG(SISSR, 0x27, 0x1F);
+ /* Syncronous reset for Command Queue */
+ outSISIDXREG(SISSR, 0x26, 0x01);
+ /* Do some magic (cp readport to writeport) */
+ temp = MMIO_IN32(pSiS->IOBase, 0x85C8);
+ MMIO_OUT32(pSiS->IOBase, 0x85C4, temp);
+ /* Enable MMIO Command Queue mode (0x20),
+ * Enable_command_queue_auto_correction (0x02)
+ * (no idea, but sounds good, so use it)
+ * 512k (0x00) (does this apply to MMIO mode?) */
+ outSISIDXREG(SISSR, 0x26, 0x22);
+ /* Calc Command Queue position (Q is always 512k)*/
+ temp = (pScrn->videoRam - 512) * 1024;
+ /* Set Q position */
+ MMIO_OUT32(pSiS->IOBase, 0x85C0, temp);
+#endif
}
break;
default:
@@ -5669,194 +8307,422 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn)
}
}
-/* TW: Things to do before a ModeSwitch. We set up the
- * video bridge configuration and the TurboQueue.
+/* Things to do before a ModeSwitch. We set up the
+ * video bridge configuration and the TurboQueue.
*/
-void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode)
{
SISPtr pSiS = SISPTR(pScrn);
- unsigned char usScratchCR30, usScratchCR31;
- unsigned char usScratchCR32, usScratchCR33;
- unsigned char usScratchCR17, usScratchCR38 = 0;
- int vbflag, temp = 0;
+ unsigned char CR30, CR31;
+ unsigned char CR32, CR33;
+ unsigned char CR17, CR38 = 0;
+ unsigned char CR35 = 0, CR79 = 0;
+ unsigned long vbflag;
+ int temp = 0, i;
int crt1rateindex = 0;
+ DisplayModePtr mymode;
+#ifdef SISMERGED
+ DisplayModePtr mymode2 = NULL;
+#endif
-#ifdef UNLOCK_ALWAYS
- sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); /* Unlock Registers */
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ mymode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1;
+ mymode2 = ((SiSMergedDisplayModePtr)mode->Private)->CRT2;
+ } else
#endif
+ mymode = mode;
vbflag = pSiS->VBFlags;
pSiS->IsCustom = FALSE;
-
- if(pSiS->HaveCustomModes) {
- if(!(mode->type & M_T_DEFAULT)) {
- pSiS->IsCustom = TRUE;
+#ifdef SISMERGED
+ pSiS->IsCustomCRT2 = FALSE;
+
+ if(pSiS->MergedFB) {
+ /* CRT2 */
+ if(vbflag & CRT2_LCD) {
+ if(pSiS->SiS_Pr->CP_HaveCustomData) {
+ for(i=0; i<7; i++) {
+ if(pSiS->SiS_Pr->CP_DataValid[i]) {
+ if((mymode2->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) &&
+ (mymode2->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) {
+ if(mymode2->type & M_T_BUILTIN) {
+ pSiS->IsCustomCRT2 = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(vbflag & (CRT2_VGA|CRT2_LCD)) {
+ if(pSiS->AddedPlasmaModes) {
+ if(mymode2->type & M_T_BUILTIN) {
+ pSiS->IsCustomCRT2 = TRUE;
+ }
+ }
+ if(pSiS->HaveCustomModes2) {
+ if(!(mymode2->type & M_T_DEFAULT)) {
+ pSiS->IsCustomCRT2 = TRUE;
+ }
+ }
+ }
+ /* CRT1 */
+ if(pSiS->HaveCustomModes) {
+ if(!(mymode->type & M_T_DEFAULT)) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+ } else
+#endif
+#ifdef SISDUALHEAD
+ if(pSiS->DualHeadMode) {
+ if(!pSiS->SecondHead) {
+ /* CRT2 */
+ if(vbflag & CRT2_LCD) {
+ if(pSiS->SiS_Pr->CP_HaveCustomData) {
+ for(i=0; i<7; i++) {
+ if(pSiS->SiS_Pr->CP_DataValid[i]) {
+ if((mymode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) &&
+ (mymode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) {
+ if(mymode->type & M_T_BUILTIN) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(vbflag & (CRT2_VGA|CRT2_LCD)) {
+ if(pSiS->AddedPlasmaModes) {
+ if(mymode->type & M_T_BUILTIN) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+ if(pSiS->HaveCustomModes) {
+ if(!(mymode->type & M_T_DEFAULT)) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+ }
+ } else {
+ /* CRT1 */
+ if(pSiS->HaveCustomModes) {
+ if(!(mymode->type & M_T_DEFAULT)) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+ }
+ } else
+#endif
+ {
+ if(vbflag & CRT2_LCD) {
+ if(pSiS->SiS_Pr->CP_HaveCustomData) {
+ for(i=0; i<7; i++) {
+ if(pSiS->SiS_Pr->CP_DataValid[i]) {
+ if((mymode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) &&
+ (mymode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) {
+ if(mymode->type & M_T_BUILTIN) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(vbflag & (CRT2_LCD|CRT2_VGA)) {
+ if(pSiS->AddedPlasmaModes) {
+ if(mymode->type & M_T_BUILTIN) {
+ pSiS->IsCustom = TRUE;
+ }
+ }
+ }
+ if((pSiS->HaveCustomModes) && (!(vbflag & CRT2_TV))) {
+ if(!(mymode->type & M_T_DEFAULT)) {
+ pSiS->IsCustom = TRUE;
+ }
}
}
- /* TW: The CR3x registers are for communicating with our BIOS emulation
- * code (native code in init.c/init301.c) or the BIOS (via VESA)
- */
- inSISIDXREG(SISCR, 0x30, usScratchCR30); /* Bridge config */
- inSISIDXREG(SISCR, 0x31, usScratchCR31); /* Bridge config */
- usScratchCR32 = pSiS->newCR32; /* Bridge connection info (use our new value) */
- inSISIDXREG(SISCR, 0x33, usScratchCR33); /* CRT1 refresh rate index */
- if(pSiS->Chipset != PCI_CHIP_SIS300) {
- switch(pSiS->VGAEngine) {
- case SIS_300_VGA: temp = 0x35; break;
- case SIS_315_VGA: temp = 0x38; break;
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); /* Unlock Registers */
+#endif
+
+ if(pSiS->Chipset == PCI_CHIP_SIS660) {
+
+ inSISIDXREG(SISCR, 0x30, CR30);
+ inSISIDXREG(SISCR, 0x31, CR31);
+ CR32 = pSiS->newCR32;
+ inSISIDXREG(SISCR, 0x33, CR33);
+ inSISIDXREG(SISCR, 0x35, CR35);
+ inSISIDXREG(SISCR, 0x38, CR38);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4,
+ "Before: CR30=0x%02x,CR31=0x%02x,CR32=0x%02x,CR33=0x%02x,CR35=0x%02x,CR38=0x%02x\n",
+ CR30, CR31, CR32, CR33, CR35, CR38);
+ CR38 &= ~0x03;
+
+ } else {
+
+ inSISIDXREG(SISCR, 0x30, CR30);
+ inSISIDXREG(SISCR, 0x31, CR31);
+ CR32 = pSiS->newCR32;
+ inSISIDXREG(SISCR, 0x33, CR33);
+ if(pSiS->Chipset != PCI_CHIP_SIS300) {
+ switch(pSiS->VGAEngine) {
+ case SIS_300_VGA: temp = 0x35; break;
+ case SIS_315_VGA: temp = 0x38; break;
+ }
+ if(temp) inSISIDXREG(SISCR, temp, CR38);
+ }
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ inSISIDXREG(SISCR, 0x79, CR79);
+ CR38 &= ~0x03; /* Clear LCDA/DualEdge bits */
}
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4,
+ "Before: CR30=0x%02x, CR31=0x%02x, CR32=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
+ CR30, CR31, CR32, CR33, temp, CR38);
}
- if(temp) inSISIDXREG(SISCR, temp, usScratchCR38); /* PAL-M, PAL-N selection */
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "VBFlags=0x%x\n", pSiS->VBFlags);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "VBFlags=0x%lx\n", pSiS->VBFlags);
- xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 3,
- "Before: CR30=0x%02x, CR31=0x%02x, CR32=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
- usScratchCR30, usScratchCR31, usScratchCR32, usScratchCR33, temp, usScratchCR38);
+ CR30 = 0x00;
+ CR31 &= ~0x60; /* Clear VB_Drivermode & VB_OutputDisable */
+ CR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */
+ CR35 = 0x00;
- usScratchCR30 = 0;
- usScratchCR31 &= ~0x60; /* TW: Clear VB_Drivermode & VB_OutputDisable */
-#if 0 /* TW: For future use */
- if( (pSiS->VBFlags & VB_LVDS) ||
- (pSiS->VBFlags & VB_301) ||
- ( (pSiS->VBFlags & (VB_301B | VB_302B |VB_30xLV | VB_30xLVX)) &&
- (!(pSiS->VBLCDFlags & VB_LCD_1400x1050)) ) ) {
-#endif
- usScratchCR31 |= 0x04; /* TW: Set VB_NotSimuMode (not for 30xB/1400x1050?) */
-#if 0
+ if(pSiS->Chipset != PCI_CHIP_SIS660) {
+ if(!pSiS->AllowHotkey) {
+ CR31 |= 0x80; /* Disable hotkey-switch */
+ }
+ CR79 &= ~0x10; /* Enable Backlight control on 315 series */
}
+
+ SiS_SetEnableDstn(pSiS->SiS_Pr, FALSE);
+ SiS_SetEnableFstn(pSiS->SiS_Pr, FALSE);
+
+ if((vbflag & CRT1_LCDA) && (viewmode == SIS_MODE_CRT1)) {
+
+ CR38 |= 0x02;
+
+ } else {
+
+ switch(vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) {
+
+ case CRT2_TV:
+
+ CR38 &= ~0xC0;
+
+ if(vbflag & TV_CHSCART) {
+ CR30 |= 0x10;
+ CR38 |= 0x04;
+ CR31 |= 0x01;
+ } else if(vbflag & TV_CHHDTV) {
+ CR38 |= 0x08;
+ CR31 &= ~0x01;
+ } else if(vbflag & TV_HIVISION)
+ CR30 |= 0x80;
+ else if(vbflag & TV_SCART)
+ CR30 |= 0x10;
+ else {
+ if(vbflag & TV_SVIDEO) CR30 |= 0x08;
+ if(vbflag & TV_AVIDEO) CR30 |= 0x04;
+ if(!(CR30 & 0x0c)) CR30 |= 0x08; /* default: SVIDEO */
+ }
+
+ if(!(vbflag & (TV_CHSCART | TV_CHHDTV))) {
+ if(vbflag & TV_PAL) {
+ CR31 |= 0x01;
+ CR35 |= 0x01;
+ if( (vbflag & VB_SISBRIDGE) ||
+ ((vbflag & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_701x)) ) {
+ if(vbflag & TV_PALM) {
+ CR38 |= 0x40;
+ CR35 |= 0x04;
+ } else if(vbflag & TV_PALN) {
+ CR38 |= 0x80;
+ CR35 |= 0x08;
+ }
+ }
+ } else {
+ CR31 &= ~0x01;
+ CR35 &= ~0x01;
+ if(vbflag & TV_NTSCJ) {
+ CR38 |= 0x40; /* TW, not BIOS */
+ CR35 |= 0x02;
+ }
+ }
+ }
+
+ CR31 &= ~0x04; /* Clear NotSimuMode */
+ pSiS->SiS_Pr->SiS_CHOverScan = pSiS->UseCHOverScan;
+ if((pSiS->OptTVSOver == 1) && (pSiS->ChrontelType == CHRONTEL_700x)) {
+ pSiS->SiS_Pr->SiS_CHSOverScan = TRUE;
+ } else {
+ pSiS->SiS_Pr->SiS_CHSOverScan = FALSE;
+ }
+#ifdef SIS_CP
+ SIS_CP_DRIVER_CONFIG
#endif
+ break;
- switch(vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) {
- case CRT2_TV:
- if(vbflag & TV_CHSCART) {
- usScratchCR38 |= 0x04;
- usScratchCR31 |= 0x01;
- } else if(vbflag & TV_CHHDTV) {
- usScratchCR38 |= 0x08;
- usScratchCR31 &= ~0x01;
- } else if(vbflag & TV_HIVISION)
- usScratchCR30 |= 0x80;
- else if(vbflag & TV_SVIDEO)
- usScratchCR30 |= 0x08;
- else if(vbflag & TV_AVIDEO)
- usScratchCR30 |= 0x04;
- else if(vbflag & TV_SCART)
- usScratchCR30 |= 0x10;
- else
- usScratchCR30 |= 0x08; /* default: SVIDEO */
-
- if(!(vbflag & (TV_CHSCART | TV_CHHDTV))) {
- if(vbflag & TV_PAL) {
- usScratchCR31 |= 0x01;
- usScratchCR38 &= ~0xC0;
- if( (vbflag & VB_SISBRIDGE) ||
- ((vbflag & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_701x)) ) {
- if(vbflag & TV_PALM) usScratchCR38 |= 0x40;
- else if(vbflag & TV_PALN) usScratchCR38 |= 0x80;
- }
- } else
- usScratchCR31 &= ~0x01;
- }
+ case CRT2_LCD:
+ CR30 |= 0x20;
+ SiS_SetEnableDstn(pSiS->SiS_Pr, pSiS->DSTN);
+ SiS_SetEnableFstn(pSiS->SiS_Pr, pSiS->FSTN);
+ break;
- usScratchCR30 |= 0x01; /* Set SimuScanMode */
+ case CRT2_VGA:
+ CR30 |= 0x40;
+ break;
- usScratchCR31 &= ~0x04; /* Clear NotSimuMode */
- pSiS->SiS_Pr->SiS_CHOverScan = pSiS->UseCHOverScan;
- if(pSiS->OptTVSOver == 1) {
- pSiS->SiS_Pr->SiS_CHSOverScan = TRUE;
- } else {
- pSiS->SiS_Pr->SiS_CHSOverScan = FALSE;
- }
- break;
- case CRT2_LCD:
- usScratchCR30 |= 0x21; /* LCD + SimuScanMode */
- break;
- case CRT2_VGA:
- usScratchCR30 |= 0x41; /* VGA2 + SimuScanMode */
- break;
- default:
- usScratchCR30 |= 0x00;
- usScratchCR31 |= 0x20; /* VB_OUTPUT_DISABLE */
- if(pSiS->UseVESA) {
- crt1rateindex = SISSearchCRT1Rate(pScrn, mode);
- }
+ default:
+ CR30 |= 0x00;
+ CR31 |= 0x20; /* VB_OUTPUT_DISABLE */
+ if(pSiS->UseVESA) {
+ crt1rateindex = SISSearchCRT1Rate(pScrn, mymode);
+ }
+ }
+
+ }
+
+ if(vbflag & CRT1_LCDA) {
+ switch(viewmode) {
+ case SIS_MODE_CRT1:
+ CR38 |= 0x01;
+ break;
+ case SIS_MODE_CRT2:
+ if(vbflag & (CRT2_TV|CRT2_VGA)) {
+ CR30 |= 0x02;
+ CR38 |= 0x01;
+ } else {
+ CR38 |= 0x03;
+ }
+ break;
+ case SIS_MODE_SIMU:
+ default:
+ if(vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) {
+ CR30 |= 0x01;
+ }
+ break;
+ }
+ } else {
+ if(vbflag & (CRT2_TV|CRT2_LCD|CRT2_VGA)) {
+ CR30 |= 0x01;
+ }
}
- /* TW: for VESA: no DRIVERMODE, otherwise
+
+ /* for VESA: no DRIVERMODE, otherwise
* -) CRT2 will not be initialized correctly when using mode
* where LCD has to scale, and
* -) CRT1 will have too low rate
*/
- if (pSiS->UseVESA) {
- usScratchCR31 &= 0x40; /* TW: Clear Drivermode */
+ if(pSiS->UseVESA) {
+ CR31 &= ~0x40; /* Clear Drivermode */
+ CR31 |= 0x06; /* Set SlaveMode, Enable SimuMode in Slavemode */
#ifdef TWDEBUG
- usScratchCR31 |= 0x40; /* DEBUG (for non-slave mode VESA) */
- crt1rateindex = SISSearchCRT1Rate(pScrn, mode);
+ CR31 |= 0x40; /* DEBUG (for non-slave mode VESA) */
+ crt1rateindex = SISSearchCRT1Rate(pScrn, mymode);
#endif
} else {
- usScratchCR31 |= 0x40; /* TW: Set Drivermode */
+ CR31 |= 0x40; /* Set Drivermode */
+ CR31 &= ~0x06; /* Disable SlaveMode, disable SimuMode in SlaveMode */
if(!pSiS->IsCustom) {
- crt1rateindex = SISSearchCRT1Rate(pScrn, mode);
+ crt1rateindex = SISSearchCRT1Rate(pScrn, mymode);
} else {
- crt1rateindex = usScratchCR33;
+ crt1rateindex = CR33;
}
}
- outSISIDXREG(SISCR, 0x30, usScratchCR30);
- outSISIDXREG(SISCR, 0x31, usScratchCR31);
- if(temp) {
- usScratchCR38 &= ~0x03; /* Clear LCDA/DualEdge bits */
- outSISIDXREG(SISCR, temp, usScratchCR38);
- }
-
- pSiS->SiS_Pr->SiS_UseOEM = pSiS->OptUseOEM;
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode) {
if(pSiS->SecondHead) {
/* CRT1 */
- usScratchCR33 &= 0xf0;
- usScratchCR33 |= (crt1rateindex & 0x0f);
+ CR33 &= 0xf0;
+ if(!(vbflag & CRT1_LCDA)) {
+ CR33 |= (crt1rateindex & 0x0f);
+ }
} else {
/* CRT2 */
- usScratchCR33 &= 0x0f;
- if(vbflag & CRT2_VGA) usScratchCR33 |= ((crt1rateindex << 4) & 0xf0);
+ CR33 &= 0x0f;
+ if(vbflag & CRT2_VGA) {
+ CR33 |= ((crt1rateindex << 4) & 0xf0);
+ }
}
- } else {
+ } else
#endif
+#ifdef SISMERGED
+ if(pSiS->MergedFB) {
+ CR33 = 0;
+ if(!(vbflag & CRT1_LCDA)) {
+ CR33 |= (crt1rateindex & 0x0f);
+ }
if(vbflag & CRT2_VGA) {
- usScratchCR33 = (crt1rateindex & 0x0f) | ((crt1rateindex & 0x0f) << 4);
- } else {
- usScratchCR33 = crt1rateindex & 0x0f;
+ if(!pSiS->IsCustomCRT2) {
+ CR33 |= (SISSearchCRT1Rate(pScrn, mymode2) << 4);
+ }
+ }
+ } else
+#endif
+ {
+ CR33 = 0;
+ if(!(vbflag & CRT1_LCDA)) {
+ CR33 |= (crt1rateindex & 0x0f);
+ }
+ if(vbflag & CRT2_VGA) {
+ CR33 |= ((crt1rateindex & 0x0f) << 4);
}
if((!(pSiS->UseVESA)) && (vbflag & CRT2_ENABLE)) {
-#ifndef TWDEBUG
- if(pSiS->CRT1off) usScratchCR33 &= 0xf0;
-#endif
+ if(pSiS->CRT1off) CR33 &= 0xf0;
}
-#ifdef SISDUALHEAD
}
-#endif
- outSISIDXREG(SISCR, 0x33, usScratchCR33);
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "After: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x\n",
- usScratchCR30, usScratchCR31, usScratchCR33);
+ if(pSiS->Chipset == PCI_CHIP_SIS660) {
+
+ CR31 &= 0xfe; /* Clear PAL flag (now in CR35) */
+ CR38 &= 0x03; /* Use only LCDA bits */
+ outSISIDXREG(SISCR, 0x30, CR30);
+ outSISIDXREG(SISCR, 0x31, CR31);
+ outSISIDXREG(SISCR, 0x33, CR33);
+ outSISIDXREG(SISCR, 0x35, CR35);
+ setSISIDXREG(SISCR, 0x38, 0xfc, CR38);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR35=0x%02x,CR38=%02x\n",
+ CR30, CR31, CR33, CR35, CR38);
+
+ } else {
+
+ outSISIDXREG(SISCR, 0x30, CR30);
+ outSISIDXREG(SISCR, 0x31, CR31);
+ outSISIDXREG(SISCR, 0x33, CR33);
+ if(temp) {
+ outSISIDXREG(SISCR, temp, CR38);
+ }
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ outSISIDXREG(SISCR, 0x79, CR79);
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n",
+ CR30, CR31, CR33, temp, CR38);
+ }
+
+ pSiS->SiS_Pr->SiS_UseOEM = pSiS->OptUseOEM;
/* Enable TurboQueue */
- SiSEnableTurboQueue(pScrn);
+#ifdef SISVRAMQ
+ if(pSiS->VGAEngine != SIS_315_VGA)
+#endif
+ SiSEnableTurboQueue(pScrn);
if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE)) {
/* Switch on CRT1 for modes that require the bridge in SlaveMode */
- inSISIDXREG(SISCR, 0x17, usScratchCR17);
- if(!(usScratchCR17 & 0x80)) {
- orSISIDXREG(SISCR, 0x17, 0x80);
- outSISIDXREG(SISSR, 0x00, 0x01);
- usleep(10000);
- outSISIDXREG(SISSR, 0x00, 0x03);
+ andSISIDXREG(SISSR,0x1f,0x3f);
+ inSISIDXREG(SISCR, 0x17, CR17);
+ if(!(CR17 & 0x80)) {
+ orSISIDXREG(SISCR, 0x17, 0x80);
+ outSISIDXREG(SISSR, 0x00, 0x01);
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03);
}
}
-
}
/* Functions for adjusting various TV settings */
@@ -6041,7 +8907,10 @@ void SiS_SetCHTVlumaflickerfilter(ScrnInfoPtr pScrn, int val)
case CHRONTEL_700x:
val /= 6;
if((val >= 0) && (val <= 2)) {
- SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 10) | 0x01),0xF3);
+ unsigned short reg = 0;
+ reg = SiS_GetCH70xx(pSiS->SiS_Pr, 0x01);
+ reg = (reg & 0xf0) | ((reg & 0x0c) >> 2) | (val << 2);
+ SiS_SetCH70xx(pSiS->SiS_Pr, ((reg << 8) | 0x01));
}
break;
case CHRONTEL_701x:
@@ -6073,7 +8942,7 @@ int SiS_GetCHTVlumaflickerfilter(ScrnInfoPtr pScrn)
#endif
switch(pSiS->ChrontelType) {
case CHRONTEL_700x:
- return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 6);
+ return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x03) * 6);
case CHRONTEL_701x:
return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 4);
default:
@@ -6169,7 +9038,10 @@ void SiS_SetCHTVchromaflickerfilter(ScrnInfoPtr pScrn, int val)
case CHRONTEL_700x:
val /= 6;
if((val >= 0) && (val <= 2)) {
- SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 12) | 0x01),0xCF);
+ unsigned short reg = 0;
+ reg = SiS_GetCH70xx(pSiS->SiS_Pr, 0x01);
+ reg = (reg & 0xc0) | ((reg & 0x0c) >> 2) | ((reg & 0x03) << 2) | (val << 4);
+ SiS_SetCH70xx(pSiS->SiS_Pr, ((reg << 8) | 0x01));
}
break;
case CHRONTEL_701x:
@@ -6221,14 +9093,14 @@ void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val)
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->chtvcvbscolor = pSiS->chtvcvbscolor;
#endif
-
+
if(!(pSiS->VBFlags & CRT2_TV)) return;
if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
-
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
-
+
switch(pSiS->ChrontelType) {
case CHRONTEL_700x:
if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x4003,0x00);
@@ -6238,7 +9110,7 @@ void SiS_SetCHTVcvbscolor(ScrnInfoPtr pScrn, int val)
if(!val) SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x0002,~0x20);
else SiS_SetCH70xxANDOR(pSiS->SiS_Pr, 0x2002,0x00);
break;
- }
+ }
}
int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn)
@@ -6249,8 +9121,8 @@ int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn)
#endif
if(!(pSiS->VBFlags & VB_CHRONTEL && pSiS->VBFlags & CRT2_TV)) {
-#ifdef SISDUALHEAD
- if(pSiSEnt && pSiS->DualHeadMode)
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
return (int)pSiSEnt->chtvcvbscolor;
else
#endif
@@ -6265,9 +9137,9 @@ int SiS_GetCHTVcvbscolor(ScrnInfoPtr pScrn)
case CHRONTEL_701x:
return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x02) & 0x20) >> 5) ^ 0x01);
default:
- return -2;
+ return -2;
}
- }
+ }
}
void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val)
@@ -6281,10 +9153,10 @@ void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val)
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->chtvtextenhance = val;
#endif
-
+
if(!(pSiS->VBFlags & CRT2_TV)) return;
if(!(pSiS->VBFlags & VB_CHRONTEL)) return;
-
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
@@ -6293,7 +9165,10 @@ void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val)
case CHRONTEL_700x:
val /= 6;
if((val >= 0) && (val <= 2)) {
- SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x01),0xFC);
+ unsigned short reg = 0;
+ reg = SiS_GetCH70xx(pSiS->SiS_Pr, 0x01);
+ reg = (reg & 0xf0) | ((reg & 0x03) << 2) | val;
+ SiS_SetCH70xx(pSiS->SiS_Pr, ((reg << 8) | 0x01));
}
break;
case CHRONTEL_701x:
@@ -6302,7 +9177,7 @@ void SiS_SetCHTVtextenhance(ScrnInfoPtr pScrn, int val)
SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x03),0xF8);
}
break;
- }
+ }
}
int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn)
@@ -6325,11 +9200,11 @@ int SiS_GetCHTVtextenhance(ScrnInfoPtr pScrn)
#endif
switch(pSiS->ChrontelType) {
case CHRONTEL_700x:
- return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x03) * 6);
+ return(int)(((SiS_GetCH70xx(pSiS->SiS_Pr, 0x01) & 0x0c) >> 2) * 6);
case CHRONTEL_701x:
return(int)((SiS_GetCH70xx(pSiS->SiS_Pr, 0x03) & 0x07) * 2);
default:
- return -2;
+ return -2;
}
}
}
@@ -6362,8 +9237,9 @@ void SiS_SetCHTVcontrast(ScrnInfoPtr pScrn, int val)
case CHRONTEL_701x:
SiS_SetCH70xxANDOR(pSiS->SiS_Pr, ((val << 8) | 0x08),0xF8);
break;
- }
- }
+ }
+ SiS_DDC2Delay(pSiS->SiS_Pr, 1000);
+ }
}
int SiS_GetCHTVcontrast(ScrnInfoPtr pScrn)
@@ -6463,8 +9339,8 @@ void SiS_SetSISTVantiflicker(ScrnInfoPtr pScrn, int val)
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
- val /= 2;
- if((val >= 0) && (val <= 7)) {
+ /* Valid values: 0=off, 1=low, 2=med, 3=high, 4=adaptive */
+ if((val >= 0) && (val <= 4)) {
setSISIDXREG(SISPART2,0x0A,0x8F, (val << 4));
}
}
@@ -6482,14 +9358,14 @@ int SiS_GetSISTVantiflicker(ScrnInfoPtr pScrn)
return (int)pSiSEnt->sistvantiflicker;
else
#endif
- return (int)pSiS->sistvantiflicker;
+ return (int)pSiS->sistvantiflicker;
} else {
unsigned char temp;
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
inSISIDXREG(SISPART2, 0x0a, temp);
- return(int)(((temp & 0x70) >> 4) * 2);
+ return(int)((temp & 0x70) >> 4);
}
}
@@ -6507,7 +9383,8 @@ void SiS_SetSISTVsaturation(ScrnInfoPtr pScrn, int val)
if(!(pSiS->VBFlags & CRT2_TV)) return;
if(!(pSiS->VBFlags & VB_SISBRIDGE)) return;
-
+ if(pSiS->VBFlags & VB_301) return;
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
@@ -6524,33 +9401,305 @@ int SiS_GetSISTVsaturation(ScrnInfoPtr pScrn)
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS->entityPrivate;
#endif
-
- if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) {
-#ifdef SISDUALHEAD
- if(pSiSEnt && pSiS->DualHeadMode)
+
+ if(!(pSiS->VBFlags & VB_SISBRIDGE &&
+ (!(pSiS->VBFlags & VB_301)) &&
+ pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
return (int)pSiSEnt->sistvsaturation;
else
-#endif
+#endif
return (int)pSiS->sistvsaturation;
} else {
unsigned char temp;
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
-#endif
+#endif
inSISIDXREG(SISPART4, 0x21, temp);
return(int)((temp & 0x07) * 2);
}
}
+void SiS_SetSISTVcolcalib(ScrnInfoPtr pScrn, int val, Bool coarse)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+ int ccoarse, cfine, cbase = pSiS->sistvccbase;
+ unsigned char temp;
+
+#ifdef SISDUALHEAD
+ if(pSiSEnt) cbase = pSiSEnt->sistvccbase;
+#endif
+
+ if(coarse) {
+ pSiS->sistvcolcalibc = ccoarse = val;
+ cfine = pSiS->sistvcolcalibf;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) {
+ pSiSEnt->sistvcolcalibc = val;
+ cfine = pSiSEnt->sistvcolcalibf;
+ }
+#endif
+ } else {
+ pSiS->sistvcolcalibf = cfine = val;
+ ccoarse = pSiS->sistvcolcalibc;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) {
+ pSiSEnt->sistvcolcalibf = val;
+ ccoarse = pSiSEnt->sistvcolcalibc;
+ }
+#endif
+ }
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_SISBRIDGE)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if((cfine >= -128) && (cfine <= 127) && (ccoarse >= -120) && (ccoarse <= 120)) {
+ long finalcc = cbase + (((ccoarse * 256) + cfine) * 256);
+
+ inSISIDXREG(SISPART4,0x1f,temp);
+ if(!(temp & 0x01)) {
+#if 0
+ if(pSiS->VBFlags & TV_NTSC) finalcc += 0x21ed8620;
+ else if(pSiS->VBFlags & TV_PALM) finalcc += ?;
+ else if(pSiS->VBFlags & TV_PALM) finalcc += ?;
+ else finalcc += 0x2a05d300;
+#endif
+ }
+ setSISIDXREG(SISPART2,0x31,0x80,((finalcc >> 24) & 0x7f));
+ outSISIDXREG(SISPART2,0x32,((finalcc >> 16) & 0xff));
+ outSISIDXREG(SISPART2,0x33,((finalcc >> 8) & 0xff));
+ outSISIDXREG(SISPART2,0x34,(finalcc & 0xff));
+ }
+}
+
+int SiS_GetSISTVcolcalib(ScrnInfoPtr pScrn, Bool coarse)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+ if(pSiSEnt && pSiS->DualHeadMode)
+ if(coarse)
+ return (int)pSiSEnt->sistvcolcalibc;
+ else
+ return (int)pSiSEnt->sistvcolcalibf;
+ else
+#endif
+ if(coarse)
+ return (int)pSiS->sistvcolcalibc;
+ else
+ return (int)pSiS->sistvcolcalibf;
+}
+
+void SiS_SetSISTVcfilter(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ pSiS->sistvcfilter = val ? 1 : 0;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->sistvcfilter = pSiS->sistvcfilter;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_SISBRIDGE)) return;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ setSISIDXREG(SISPART2,0x30,~0x10,((pSiS->sistvcfilter << 4) & 0x10));
+}
+
+int SiS_GetSISTVcfilter(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+ if(!(pSiS->VBFlags & VB_SISBRIDGE && pSiS->VBFlags & CRT2_TV)) {
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->sistvcfilter;
+ else
+#endif
+ return (int)pSiS->sistvcfilter;
+ } else {
+ unsigned char temp;
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+ inSISIDXREG(SISPART2, 0x30, temp);
+ return(int)((temp & 0x10) ? 1 : 0);
+ }
+}
+
+void SiS_SetSISTVyfilter(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+ unsigned char p35,p36,p37,p38,p48,p49,p4a,p30;
+ int i,j;
+
+ pSiS->sistvyfilter = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->sistvyfilter = pSiS->sistvyfilter;
+#endif
+
+ if(!(pSiS->VBFlags & CRT2_TV)) return;
+ if(!(pSiS->VBFlags & VB_SISBRIDGE)) return;
+
+ p35 = pSiS->p2_35; p36 = pSiS->p2_36;
+ p37 = pSiS->p2_37; p38 = pSiS->p2_38;
+ p48 = pSiS->p2_48; p49 = pSiS->p2_49;
+ p4a = pSiS->p2_4a; p30 = pSiS->p2_30;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) {
+ p35 = pSiSEnt->p2_35; p36 = pSiSEnt->p2_36;
+ p37 = pSiSEnt->p2_37; p38 = pSiSEnt->p2_38;
+ p48 = pSiSEnt->p2_48; p49 = pSiSEnt->p2_49;
+ p4a = pSiSEnt->p2_4a; p30 = pSiSEnt->p2_30;
+ }
+#endif
+ p30 &= 0x20;
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ switch(pSiS->sistvyfilter) {
+ case 0:
+ andSISIDXREG(SISPART2,0x30,0xdf);
+ break;
+ case 1:
+ outSISIDXREG(SISPART2,0x35,p35);
+ outSISIDXREG(SISPART2,0x36,p36);
+ outSISIDXREG(SISPART2,0x37,p37);
+ outSISIDXREG(SISPART2,0x38,p38);
+ if(!(pSiS->VBFlags & VB_301)) {
+ outSISIDXREG(SISPART2,0x48,p48);
+ outSISIDXREG(SISPART2,0x49,p49);
+ outSISIDXREG(SISPART2,0x4a,p4a);
+ }
+ setSISIDXREG(SISPART2,0x30,0xdf,p30);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ if(!(pSiS->VBFlags & (TV_PALM | TV_PALN | TV_NTSCJ))) {
+ int yindex301 = -1, yindex301B = -1;
+ unsigned char p3d4_34;
+
+ inSISIDXREG(SISCR,0x34,p3d4_34);
+
+ switch((p3d4_34 & 0x7f)) {
+ case 0x59: /* 320x200 */
+ case 0x41:
+ case 0x4f:
+ case 0x50: /* 320x240 */
+ case 0x56:
+ case 0x53:
+ yindex301 = (pSiS->VBFlags & TV_NTSC) ? 0 : 4;
+ break;
+ case 0x2f: /* 640x400 */
+ case 0x5d:
+ case 0x5e:
+ case 0x2e: /* 640x480 */
+ case 0x44:
+ case 0x62:
+ yindex301 = (pSiS->VBFlags & TV_NTSC) ? 1 : 5;
+ yindex301B = (pSiS->VBFlags & TV_NTSC) ? 0 : 4;
+ break;
+ case 0x31: /* 720x480 */
+ case 0x33:
+ case 0x35:
+ case 0x32: /* 720x576 */
+ case 0x34:
+ case 0x36:
+ case 0x5f: /* 768x576 */
+ case 0x60:
+ case 0x61:
+ yindex301 = (pSiS->VBFlags & TV_NTSC) ? 2 : 6;
+ yindex301B = (pSiS->VBFlags & TV_NTSC) ? 1 : 5;
+ break;
+ case 0x51: /* 400x300 */
+ case 0x57:
+ case 0x54:
+ case 0x30: /* 800x600 */
+ case 0x47:
+ case 0x63:
+ yindex301 = (pSiS->VBFlags & TV_NTSC) ? 3 : 7;
+ yindex301B = (pSiS->VBFlags & TV_NTSC) ? 2 : 6;
+ break;
+ case 0x52: /* 512x384 */
+ case 0x58:
+ case 0x5c:
+ case 0x38: /* 1024x768 */
+ case 0x4a:
+ case 0x64:
+ yindex301B = (pSiS->VBFlags & TV_NTSC) ? 3 : 7;
+ break;
+ }
+ if(pSiS->VBFlags & VB_301) {
+ if(yindex301 >= 0) {
+ for(i=0, j=0x35; i<=3; i++, j++) {
+ outSISIDXREG(SISPART2,j,(SiSTVFilter301[yindex301].filter[pSiS->sistvyfilter-2][i]));
+ }
+ }
+ } else {
+ if(yindex301B >= 0) {
+ for(i=0, j=0x35; i<=3; i++, j++) {
+ outSISIDXREG(SISPART2,j,(SiSTVFilter301B[yindex301B].filter[pSiS->sistvyfilter-2][i]));
+ }
+ for(i=4, j=0x48; i<=6; i++, j++) {
+ outSISIDXREG(SISPART2,j,(SiSTVFilter301B[yindex301B].filter[pSiS->sistvyfilter-2][i]));
+ }
+ }
+ }
+ orSISIDXREG(SISPART2,0x30,0x20);
+ }
+ }
+}
+
+int SiS_GetSISTVyfilter(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->sistvyfilter;
+ else
+#endif
+ return (int)pSiS->sistvyfilter;
+}
+
void SiS_SetSIS6326TVantiflicker(ScrnInfoPtr pScrn, int val)
{
SISPtr pSiS = SISPTR(pScrn);
unsigned char tmp;
-
- pSiS->sis6326antiflicker = val;
+
+ pSiS->sistvantiflicker = val;
if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return;
-
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
@@ -6572,7 +9721,7 @@ int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn)
unsigned char tmp;
if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) {
- return (int)pSiS->sis6326antiflicker;
+ return (int)pSiS->sistvantiflicker;
}
#ifdef UNLOCK_ALWAYS
@@ -6581,7 +9730,7 @@ int SiS_GetSIS6326TVantiflicker(ScrnInfoPtr pScrn)
tmp = SiS6326GetTVReg(pScrn,0x00);
if(!(tmp & 0x04)) {
- return (int)pSiS->sis6326antiflicker;
+ return (int)pSiS->sistvantiflicker;
} else {
return (int)((tmp >> 5) & 0x07);
}
@@ -6689,7 +9838,7 @@ void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val)
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS->entityPrivate;
#endif
-
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
@@ -6700,11 +9849,11 @@ void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val)
#endif
if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
-
+
if(pSiS->VBFlags & CRT2_TV) {
-
+
if(pSiS->VBFlags & VB_CHRONTEL) {
-
+
int x = pSiS->tvx;
#ifdef SISDUALHEAD
if(pSiSEnt && pSiS->DualHeadMode) x = pSiSEnt->tvx;
@@ -6719,114 +9868,91 @@ void SiS_SetTVxposoffset(ScrnInfoPtr pScrn, int val)
}
break;
case CHRONTEL_701x:
- /* TO DO */
+ /* Not supported by hardware */
break;
}
-
+
} else if(pSiS->VBFlags & VB_SISBRIDGE) {
-
+
if((val >= -32) && (val <= 32)) {
- unsigned char p2_1f,p2_2b,p2_2c,p2_2d,p2_43;
- const unsigned char p2_left_ntsc[8][4] = {
- { 0x48, 0x63, 0x49, 0xf4 },
- { 0x45, 0x60, 0x46, 0xf1 },
- { 0x43, 0x6e, 0x44, 0xff },
- { 0x40, 0x6b, 0x41, 0xfc },
- { 0x3e, 0x69, 0x3f, 0xfa },
- { 0x3c, 0x67, 0x3d, 0xf8 },
- { 0x39, 0x64, 0x3a, 0xf5 },
- { 0x37, 0x62, 0x38, 0xf3 }
- };
- const unsigned char p2_right_ntsc[8][4] = {
- { 0x4b, 0x66, 0x4c, 0xf7 },
- { 0x4c, 0x67, 0x4d, 0xf8 },
- { 0x4e, 0x69, 0x4f, 0xfa },
- { 0x4f, 0x6a, 0x50, 0xfb },
- { 0x51, 0x6c, 0x52, 0xfd },
- { 0x53, 0x6e, 0x54, 0xff },
- { 0x55, 0x60, 0x56, 0xf1 },
- { 0x56, 0x61, 0x57, 0xf2 }
- };
- const unsigned char p2_left_pal[8][4] = {
- { 0x5b, 0x66, 0x5c, 0x87 },
- { 0x59, 0x64, 0x5a, 0x85 },
- { 0x56, 0x61, 0x57, 0x82 },
- { 0x53, 0x6e, 0x54, 0x8f },
- { 0x50, 0x6b, 0x51, 0x8c },
- { 0x4d, 0x68, 0x4e, 0x89 },
- { 0x4a, 0x65, 0x4b, 0x86 },
- { 0x49, 0x64, 0x4a, 0x85 }
- };
- const unsigned char p2_right_pal[8][4] = {
- { 0x5f, 0x6a, 0x60, 0x8b },
- { 0x61, 0x6c, 0x62, 0x8d },
- { 0x63, 0x6e, 0x64, 0x8f },
- { 0x65, 0x60, 0x66, 0x81 },
- { 0x66, 0x61, 0x67, 0x82 },
- { 0x68, 0x63, 0x69, 0x84 },
- { 0x69, 0x64, 0x6a, 0x85 },
- { 0x6b, 0x66, 0x6c, 0x87 }
- };
- val /= 4;
- p2_2d = pSiS->p2_2d;
-#ifdef SISDUALHEAD
- if(pSiSEnt && pSiS->DualHeadMode) p2_2d = pSiSEnt->p2_2d;
-#endif
- p2_2d &= 0xf0;
- if(val < 0) {
- val = -val;
- if(val == 8) val = 7;
- if(pSiS->VBFlags & TV_PAL) {
- p2_1f = p2_left_pal[val][0];
- p2_2b = p2_left_pal[val][1];
- p2_2c = p2_left_pal[val][2];
- p2_2d |= (p2_left_pal[val][3] & 0x0f);
- } else {
- p2_1f = p2_left_ntsc[val][0];
- p2_2b = p2_left_ntsc[val][1];
- p2_2c = p2_left_ntsc[val][2];
- p2_2d |= (p2_left_ntsc[val][3] & 0x0f);
- }
+
+ unsigned char p2_1f,p2_20,p2_2b,p2_43,p3d4_34;
+ unsigned short temp;
+ int myadd2, mysub;
+
+ p2_1f = pSiS->p2_1f;
+ p2_20 = pSiS->p2_20;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ p2_1f = pSiSEnt->p2_1f;
+ p2_20 = pSiSEnt->p2_20;
+ }
+#endif
+ inSISIDXREG(SISCR,0x34,p3d4_34);
+ p3d4_34 &= 0x7f;
+
+ temp = p2_1f | ((p2_20 & 0xf0) << 4);
+ temp += (val * 2);
+
+ p2_1f = temp & 0xff;
+ p2_20 = (temp & 0xf00) >> 4;
+
+ if((pSiS->VBFlags & (TV_NTSC | TV_PALM)) &&
+ ((p3d4_34 == 0x64) || (p3d4_34 == 0x4a) || (p3d4_34 == 0x38))) {
+ temp += 1514;
+ myadd2 = 4;
+ mysub = 4;
} else {
- if(val == 8) val = 7;
- if(pSiS->VBFlags & TV_PAL) {
- p2_1f = p2_right_pal[val][0];
- p2_2b = p2_right_pal[val][1];
- p2_2c = p2_right_pal[val][2];
- p2_2d |= (p2_right_pal[val][3] & 0x0f);
- } else {
- p2_1f = p2_right_ntsc[val][0];
- p2_2b = p2_right_ntsc[val][1];
- p2_2c = p2_right_ntsc[val][2];
- p2_2d |= (p2_right_ntsc[val][3] & 0x0f);
- }
+ temp += 1363;
+ myadd2 = 3;
+ if(pSiS->VBFlags & VB_301) myadd2 += 3;
+ mysub = 5;
+ }
+
+ p2_2b = ((temp & 0xf00) >> 4) | ((p2_1f - mysub) & 0x0f);
+ p2_43 = p2_1f + myadd2;
+
+#if 0
+ p2_1f += (val * 2);
+ if((pSiS->VBFlags & (TV_NTSC | TV_PALM)) &&
+ ((p3d4_34 == 0x64) || (p3d4_34 == 0x4a) || (p3d4_34 == 0x38))) {
+ p2_2b = ((p2_1f - 4) & 0x0f) | 0x70;
+ p2_2c = p2_1f - 22;
+ p2_2d = ((p2_2c - 4) & 0x0f) | 0xe0;
+ p2_43 = p2_1f + 4;
+ } else {
+ p2_2b = ((p2_1f - 5) & 0x0f) | 0x60;
+ p2_2c = p2_1f + 1;
+ p2_2d = ((p2_2c - 5) & 0x0f) | (pSiS->VBFlags & TV_PAL ? 0x80 : 0xf0);
+ p2_43 = p2_1f + 3;
+ if(pSiS->VBFlags & VB_301) p2_43 += 3;
}
- p2_43 = p2_1f + 3;
+#endif
+
SISWaitRetraceCRT2(pScrn);
outSISIDXREG(SISPART2,0x1f,p2_1f);
+ setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
outSISIDXREG(SISPART2,0x2b,p2_2b);
- outSISIDXREG(SISPART2,0x2c,p2_2c);
- outSISIDXREG(SISPART2,0x2d,p2_2d);
outSISIDXREG(SISPART2,0x43,p2_43);
}
}
}
-
+
} else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
-
+
if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) {
-
+
unsigned char tmp;
unsigned short temp1, temp2, temp3;
-
+
tmp = SiS6326GetTVReg(pScrn,0x00);
if(tmp & 0x04) {
-
+
temp1 = pSiS->tvx1;
temp2 = pSiS->tvx2;
temp3 = pSiS->tvx3;
if((val >= -16) && (val <= 16)) {
- if(val > 0) {
+ if(val > 0) {
temp1 += (val * 4);
temp2 += (val * 4);
while((temp1 > 0x0fff) || (temp2 > 0x0fff)) {
@@ -6866,11 +9992,11 @@ int SiS_GetTVxposoffset(ScrnInfoPtr pScrn)
SISPtr pSiS = SISPTR(pScrn);
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS->entityPrivate;
-
- if(pSiSEnt && pSiS->DualHeadMode)
+
+ if(pSiSEnt && pSiS->DualHeadMode)
return (int)pSiSEnt->tvxpos;
else
-#endif
+#endif
return (int)pSiS->tvxpos;
}
@@ -6891,11 +10017,11 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val)
#endif
if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
-
+
if(pSiS->VBFlags & CRT2_TV) {
-
+
if(pSiS->VBFlags & VB_CHRONTEL) {
-
+
int y = pSiS->tvy;
#ifdef SISDUALHEAD
if(pSiSEnt && pSiS->DualHeadMode) y = pSiSEnt->tvy;
@@ -6910,12 +10036,12 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val)
}
break;
case CHRONTEL_701x:
- /* TO DO */
+ /* Not supported by hardware */
break;
}
-
+
} else if(pSiS->VBFlags & VB_SISBRIDGE) {
-
+
if((val >= -32) && (val <= 32)) {
char p2_01, p2_02;
val /= 4;
@@ -6931,7 +10057,7 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val)
p2_02 += (val * 2);
while((p2_01 <= 0) || (p2_02 <= 0)) {
p2_01 += 2;
- p2_02 += 2;
+ p2_02 += 2;
}
SISWaitRetraceCRT2(pScrn);
outSISIDXREG(SISPART2,0x01,p2_01);
@@ -6939,18 +10065,18 @@ void SiS_SetTVyposoffset(ScrnInfoPtr pScrn, int val)
}
}
- }
+ }
} else if(pSiS->Chipset == PCI_CHIP_SIS6326) {
-
+
if(pSiS->SiS6326Flags & SIS6326_TVDETECTED) {
-
+
unsigned char tmp;
int temp1, limit;
-
+
tmp = SiS6326GetTVReg(pScrn,0x00);
if(tmp & 0x04) {
-
+
if((val >= -16) && (val <= 16)) {
temp1 = (unsigned short)pSiS->tvy1;
limit = (pSiS->SiS6326Flags & SIS6326_TVPAL) ? 625 : 525;
@@ -6991,19 +10117,314 @@ int SiS_GetTVyposoffset(ScrnInfoPtr pScrn)
SISPtr pSiS = SISPTR(pScrn);
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS->entityPrivate;
-
- if(pSiSEnt && pSiS->DualHeadMode)
+
+ if(pSiSEnt && pSiS->DualHeadMode)
return (int)pSiSEnt->tvypos;
- else
-#endif
+ else
+#endif
return (int)pSiS->tvypos;
}
-/* TW: Disable CRT1 for saving bandwidth. This doesn't work with VESA;
- * VESA uses the bridge in SlaveMode and switching CRT1 off while the
- * bridge is in SlaveMode not that clever...
+void SiS_SetTVxscale(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ pSiS->tvxscale = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->tvxscale = val;
+#endif
+
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+
+ if((pSiS->VBFlags & CRT2_TV) && (pSiS->VBFlags & VB_SISBRIDGE)) {
+
+ if((val >= -16) && (val <= 16)) {
+
+ unsigned char p2_44,p2_45,p2_46;
+ int scalingfactor;
+
+ p2_44 = pSiS->p2_44;
+ p2_45 = pSiS->p2_45 & 0x3f;
+ p2_46 = pSiS->p2_46 & 0x07;
+#ifdef SISDUALHEAD
+ if(pSiSEnt && pSiS->DualHeadMode) {
+ p2_44 = pSiSEnt->p2_44;
+ p2_45 = pSiSEnt->p2_45 & 0x3f;
+ p2_46 = pSiSEnt->p2_46 & 0x07;
+ }
+#endif
+ scalingfactor = (p2_46 << 13) | ((p2_45 & 0x1f) << 8) | p2_44;
+
+ if(val < 0) {
+ p2_45 &= 0xdf;
+ scalingfactor += ((-val) * 64);
+ if(scalingfactor > 0xffff) scalingfactor = 0xffff;
+ } else if(val > 0) {
+ p2_45 &= 0xdf;
+ scalingfactor -= (val * 64);
+ if(scalingfactor < 1) scalingfactor = 1;
+ }
+
+ p2_44 = scalingfactor & 0xff;
+ p2_45 &= 0xe0;
+ p2_45 |= ((scalingfactor >> 8) & 0x1f);
+ p2_46 = ((scalingfactor >> 13) & 0x07);
+
+ SISWaitRetraceCRT2(pScrn);
+ outSISIDXREG(SISPART2,0x44,p2_44);
+ setSISIDXREG(SISPART2,0x45,0xC0,p2_45);
+ if(!(pSiS->VBFlags & VB_301)) {
+ setSISIDXREG(SISPART2,0x46,0xF8,p2_46);
+ }
+ }
+
+ }
+
+ }
+}
+
+int SiS_GetTVxscale(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->tvxscale;
+ else
+#endif
+ return (int)pSiS->tvxscale;
+}
+
+void SiS_SetTVyscale(ScrnInfoPtr pScrn, int val)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+#endif
+
+#ifdef UNLOCK_ALWAYS
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
+#endif
+
+ if(val < -4) val = -4;
+ if(val > 3) val = 3;
+
+ pSiS->tvyscale = val;
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->tvyscale = val;
+#endif
+
+ if(pSiS->VBFlags & (TV_HIVISION | TV_HIVISION_LV)) return;
+
+ if(pSiS->VGAEngine == SIS_315_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+
+ if((pSiS->VBFlags & CRT2_TV) && (pSiS->VBFlags & VB_SISBRIDGE)) {
+
+ int srindex = -1;
+ int newvde, i=0, j, temp;
+ int vlimit = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 259 : 309;
+ unsigned char p3d4_34;
+
+ inSISIDXREG(SISCR,0x34,p3d4_34);
+
+ switch((p3d4_34 & 0x7f)) {
+#if 0
+ case 0x50: /* 320x240 - hdclk mode */
+ case 0x56:
+ case 0x53:
+#endif
+ case 0x2e: /* 640x480 */
+ case 0x44:
+ case 0x62:
+ srindex = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 0 : 21;
+ break;
+ case 0x31: /* 720x480 */
+ case 0x33:
+ case 0x35:
+ case 0x32: /* 720x576 */
+ case 0x34:
+ case 0x36:
+ case 0x5f: /* 768x576 */
+ case 0x60:
+ case 0x61:
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ srindex = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 7 : 28;
+ }
+ break;
+#if 0
+ case 0x51: /* 400x300 - hdclk mode */
+ case 0x57:
+ case 0x54:
+#endif
+ case 0x30: /* 800x600 */
+ case 0x47:
+ case 0x63:
+ srindex = (pSiS->VBFlags & (TV_NTSC | TV_PALM)) ? 14 : 35;
+ }
+
+ if(srindex >= 0) {
+ Bool found = FALSE;
+ if(pSiS->tvyscale != 0) {
+ for(j=0; j<=1; j++) {
+ for(i=0; i<=6; i++) {
+ if(SiSTVVScale[srindex+i].sindex == pSiS->tvyscale) {
+ found = TRUE;
+ break;
+ }
+ }
+ if(found) break;
+ if(pSiS->tvyscale > 0) pSiS->tvyscale--;
+ else pSiS->tvyscale++;
+ }
+ }
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->tvyscale = pSiS->tvyscale;
+#endif
+ if(pSiS->tvyscale == 0) {
+ unsigned char p2_0a = pSiS->p2_0a;
+ unsigned char p2_2f = pSiS->p2_2f;
+ unsigned char p2_30 = pSiS->p2_30;
+ unsigned char p2_46 = pSiS->p2_46;
+ unsigned char p2_47 = pSiS->p2_47;
+ unsigned char p1scaling[9], p4scaling[9];
+
+ for(i=0; i<9; i++) {
+ p1scaling[i] = pSiS->scalingp1[i];
+ }
+ for(i=0; i<9; i++) {
+ p4scaling[i] = pSiS->scalingp4[i];
+ }
+#ifdef SISDUALHEAD
+ if(pSiSEnt) {
+ p2_0a = pSiSEnt->p2_0a;
+ p2_2f = pSiSEnt->p2_2f;
+ p2_30 = pSiSEnt->p2_30;
+ p2_46 = pSiSEnt->p2_46;
+ p2_47 = pSiSEnt->p2_47;
+ for(i=0; i<9; i++) {
+ p1scaling[i] = pSiSEnt->scalingp1[i];
+ }
+ for(i=0; i<9; i++) {
+ p4scaling[i] = pSiSEnt->scalingp4[i];
+ }
+ }
+#endif
+ SISWaitRetraceCRT2(pScrn);
+ for(i=0; i<9; i++) {
+ outSISIDXREG(SISPART1,SiSScalingP1Regs[i],p1scaling[i]);
+ }
+ for(i=0; i<9; i++) {
+ outSISIDXREG(SISPART4,SiSScalingP4Regs[i],p4scaling[i]);
+ }
+
+ setSISIDXREG(SISPART2,0x0a,0x7f,(p2_0a & 0x80));
+ outSISIDXREG(SISPART2,0x2f,p2_2f);
+ setSISIDXREG(SISPART2,0x30,0x3f,(p2_30 & 0xc0));
+ if(!(pSiS->VBFlags & VB_301)) {
+ setSISIDXREG(SISPART2,0x46,0x9f,(p2_46 & 0x60));
+ outSISIDXREG(SISPART2,0x47,p2_47);
+ }
+
+ } else {
+
+ int so = (pSiS->VGAEngine == SIS_300_VGA) ? 12 : 0;
+ int realvde;
+ unsigned long calctemp;
+
+ srindex += i;
+ newvde = SiSTVVScale[srindex].ScaleVDE;
+ realvde = SiSTVVScale[srindex].RealVDE;
+
+ do {
+ inSISIDXREG(SISPART2,0x01,temp);
+ temp = vlimit - (temp & 0x7f);
+ if((temp - (((newvde >> 1) - 2) + 9)) > 0) break;
+ SiS_SetTVyposoffset(pScrn, pSiS->tvypos - 1);
+ } while(1);
+
+ SISWaitRetraceCRT2(pScrn);
+ if(!(pSiS->VBFlags & VB_301)) {
+ temp = (newvde >> 1) - 3;
+ setSISIDXREG(SISPART2,0x46,0x9f,((temp & 0x0300) >> 3));
+ outSISIDXREG(SISPART2,0x47,(temp & 0xff));
+ }
+ outSISIDXREG(SISPART1,0x08,(SiSTVVScale[srindex].reg[so+0] & 0xff));
+ setSISIDXREG(SISPART1,0x09,0x0f,((SiSTVVScale[srindex].reg[so+0] >> 4) & 0xf0));
+ outSISIDXREG(SISPART1,0x0b,(SiSTVVScale[srindex].reg[so+1] & 0xff));
+ setSISIDXREG(SISPART1,0x0c,0xf0,((SiSTVVScale[srindex].reg[so+1] >> 8) & 0x0f));
+ outSISIDXREG(SISPART1,0x0d,(SiSTVVScale[srindex].reg[so+2] & 0xff));
+ outSISIDXREG(SISPART1,0x0e,(SiSTVVScale[srindex].reg[so+3] & 0xff));
+ setSISIDXREG(SISPART1,0x12,0xf8,((SiSTVVScale[srindex].reg[so+3] >> 8 ) & 0x07));
+ outSISIDXREG(SISPART1,0x10,(SiSTVVScale[srindex].reg[so+4] & 0xff));
+ setSISIDXREG(SISPART1,0x11,0x8f,((SiSTVVScale[srindex].reg[so+4] >> 4) & 0x70));
+ setSISIDXREG(SISPART1,0x11,0xf0,(SiSTVVScale[srindex].reg[so+5] & 0x0f));
+
+ setSISIDXREG(SISPART2,0x0a,0x7f,((SiSTVVScale[srindex].reg[so+6] << 7) & 0x80));
+ outSISIDXREG(SISPART2,0x2f,((newvde / 2) - 2));
+ setSISIDXREG(SISPART2,0x30,0x3f,((((newvde / 2) - 2) >> 2) & 0xc0));
+
+ outSISIDXREG(SISPART4,0x13,(SiSTVVScale[srindex].reg[so+7] & 0xff));
+ outSISIDXREG(SISPART4,0x14,(SiSTVVScale[srindex].reg[so+8] & 0xff));
+ setSISIDXREG(SISPART4,0x15,0x7f,((SiSTVVScale[srindex].reg[so+8] >> 1) & 0x80));
+
+ outSISIDXREG(SISPART4,0x16,(SiSTVVScale[srindex].reg[so+9] & 0xff));
+ setSISIDXREG(SISPART4,0x15,0x87,((SiSTVVScale[srindex].reg[so+9] >> 5) & 0x78));
+
+ outSISIDXREG(SISPART4,0x17,(SiSTVVScale[srindex].reg[so+10] & 0xff));
+ setSISIDXREG(SISPART4,0x15,0xf8,((SiSTVVScale[srindex].reg[so+10] >> 8) & 0x07));
+
+ outSISIDXREG(SISPART4,0x18,(SiSTVVScale[srindex].reg[so+11] & 0xff));
+ setSISIDXREG(SISPART4,0x19,0xf0,((SiSTVVScale[srindex].reg[so+11] >> 8) & 0x0f));
+
+ temp = 0x40;
+ if(realvde <= newvde) temp = 0;
+ else realvde -= newvde;
+
+ calctemp = (realvde * 256 * 1024) / newvde;
+ if((realvde * 256 * 1024) % newvde) calctemp++;
+ outSISIDXREG(SISPART4,0x1b,(calctemp & 0xff));
+ outSISIDXREG(SISPART4,0x1a,((calctemp >> 8) & 0xff));
+ setSISIDXREG(SISPART4,0x19,0x8f,(((calctemp >> 12) & 0x30) | temp));
+ }
+ }
+
+ }
+
+ }
+}
+
+int SiS_GetTVyscale(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+#ifdef SISDUALHEAD
+ SISEntPtr pSiSEnt = pSiS->entityPrivate;
+
+ if(pSiSEnt && pSiS->DualHeadMode)
+ return (int)pSiSEnt->tvyscale;
+ else
+#endif
+ return (int)pSiS->tvyscale;
+}
+
+/* PostSetMode:
+ * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA;
+ * VESA uses the bridge in SlaveMode and switching CRT1 off while
+ * the bridge is in SlaveMode not that clever...
+ * -) Check if overlay can be used (depending on dotclock)
+ * -) Check if Panel Scaler is active on LVDS for overlay re-scaling
+ * -) Save TV registers for further processing
+ * -) Apply TV settings
*/
-void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+static void
+SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
{
SISPtr pSiS = SISPTR(pScrn);
#ifdef SISDUALHEAD
@@ -7012,12 +10433,15 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
unsigned char usScratchCR17;
Bool flag = FALSE;
Bool doit = TRUE;
- int temp;
+ int myclock, temp;
+ unsigned char sr2b, sr2c, tmpreg;
+ float num, denum, postscalar, divider;
#ifdef TWDEBUG
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"CRT1off is %d\n", pSiS->CRT1off);
#endif
+ pSiS->CRT1isoff = pSiS->CRT1off;
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
@@ -7026,55 +10450,164 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE)) {
if(pSiS->VBFlags != pSiS->VBFlags_backup) {
- pSiS->VBFlags = pSiS->VBFlags_backup;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ pSiS->VBFlags = pSiS->VBFlags_backup;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"VBFlags restored to %0lx\n", pSiS->VBFlags);
}
- /* TW: -) We can't switch off CRT1 if bridge is in SlaveMode.
- * -) If we change to a SlaveMode-Mode (like 512x384), we
- * need to adapt VBFlags for eg. Xv.
+ /* -) We can't switch off CRT1 if bridge is in SlaveMode.
+ * -) If we change to a SlaveMode-Mode (like 512x384), we
+ * need to adapt VBFlags for eg. Xv.
*/
#ifdef SISDUALHEAD
if(!pSiS->DualHeadMode) {
#endif
- if(SiSBridgeIsInSlaveMode(pScrn)) {
- doit = FALSE;
- temp = pSiS->VBFlags;
- pSiS->VBFlags &= (~VB_DISPMODE_SINGLE);
- pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_DISP1);
- if(temp != pSiS->VBFlags) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "VBFlags changed to 0x%0lx\n", pSiS->VBFlags);
- }
+ if(SiSBridgeIsInSlaveMode(pScrn)) {
+ doit = FALSE;
+ temp = pSiS->VBFlags;
+ pSiS->VBFlags &= (~VB_DISPMODE_SINGLE);
+ pSiS->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_DISP1);
+ if(temp != pSiS->VBFlags) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "VBFlags changed to 0x%0lx\n", pSiS->VBFlags);
+ }
}
#ifdef SISDUALHEAD
}
#endif
- if(doit) {
- inSISIDXREG(SISCR, 0x17, usScratchCR17);
- if(pSiS->CRT1off) {
- if(usScratchCR17 & 0x80) flag = TRUE;
- usScratchCR17 &= ~0x80;
- } else {
- if(!(usScratchCR17 & 0x80)) flag = TRUE;
- usScratchCR17 |= 0x80;
- }
- outSISIDXREG(SISCR, 0x17, usScratchCR17);
- /* TW: Reset only if status changed */
- if(flag) {
- outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
- usleep(10000);
- outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+
+ if((pSiS->CRT1off) && (doit)) {
+ orSISIDXREG(SISCR,0x63,0x40);
+ orSISIDXREG(SISSR,0x1f,0xc0);
+ } else {
+ andSISIDXREG(SISCR,0x63,0xBF);
+ andSISIDXREG(SISSR,0x1f,0x3f);
+ }
+
+ } else {
+
+ if(doit) {
+ inSISIDXREG(SISCR, 0x17, usScratchCR17);
+ if(pSiS->CRT1off) {
+ if(usScratchCR17 & 0x80) {
+ flag = TRUE;
+ usScratchCR17 &= ~0x80;
+ }
+ orSISIDXREG(SISSR,0x1f,0xc0);
+ } else {
+ if(!(usScratchCR17 & 0x80)) {
+ flag = TRUE;
+ usScratchCR17 |= 0x80;
+ }
+ andSISIDXREG(SISSR,0x1f,0x3f);
+ }
+ /* Reset only if status changed */
+ if(flag) {
+ outSISIDXREG(SISCR, 0x17, usScratchCR17);
+ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */
+ }
}
}
+
}
- /* TW: Apply TV settings given by options
+ /* Determine if the video overlay can be used */
+ if(!pSiS->NoXvideo) {
+ inSISIDXREG(SISSR,0x2b,sr2b);
+ inSISIDXREG(SISSR,0x2c,sr2c);
+ divider = (sr2b & 0x80) ? 2.0 : 1.0;
+ postscalar = (sr2c & 0x80) ?
+ ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0 ) :
+ ( ((sr2c >> 5) & 0x03) + 1.0 );
+ num = (sr2b & 0x7f) + 1.0;
+ denum = (sr2c & 0x1f) + 1.0;
+ myclock = (int)((14318 * (divider / postscalar) * (num / denum)) / 1000);
+
+ pSiS->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT1OVERLAYGAMMA);
+ switch(pSiS->sishw_ext.jChipType) {
+ case SIS_300:
+ case SIS_540:
+ case SIS_630:
+ case SIS_730:
+ if(myclock < 150) {
+ pSiS->MiscFlags |= MISC_CRT1OVERLAY;
+ }
+ break;
+ case SIS_550:
+ case SIS_650:
+ case SIS_740:
+ if(myclock < 175) {
+ pSiS->MiscFlags |= MISC_CRT1OVERLAY;
+ if(myclock < 166) {
+ pSiS->MiscFlags |= MISC_CRT1OVERLAYGAMMA;
+ }
+ }
+ break;
+ case SIS_315H:
+ case SIS_315:
+ case SIS_315PRO:
+ case SIS_330:
+ case SIS_661:
+ case SIS_741:
+ case SIS_660:
+ case SIS_760:
+ if(myclock < 180) {
+ pSiS->MiscFlags |= MISC_CRT1OVERLAY;
+ if(myclock < 166) {
+ pSiS->MiscFlags |= MISC_CRT1OVERLAYGAMMA;
+ }
+ }
+ break;
+ }
+ if(!(pSiS->MiscFlags & MISC_CRT1OVERLAY)) {
+#ifdef SISDUALHEAD
+ if((!pSiS->DualHeadMode) || (pSiS->SecondHead))
+#endif
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3,
+ "Current dotclock (%dMhz) too high for video overlay on CRT1\n",
+ myclock);
+ }
+ }
+
+ /* Determine if the Panel Link scaler is active */
+ pSiS->MiscFlags &= ~MISC_PANELLINKSCALER;
+ if(pSiS->VBFlags & (CRT2_LCD | CRT1_LCDA)) {
+ if(pSiS->VGAEngine == SIS_300_VGA) {
+ if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH)) {
+ inSISIDXREG(SISPART1,0x1e,tmpreg);
+ tmpreg &= 0x3f;
+ if(tmpreg) pSiS->MiscFlags |= MISC_PANELLINKSCALER;
+ }
+ } else {
+ if(pSiS->VBFlags & (VB_LVDS | VB_30xBDH | CRT1_LCDA)) {
+ inSISIDXREG(SISPART1,0x35,tmpreg);
+ tmpreg &= 0x04;
+ if(!tmpreg) pSiS->MiscFlags |= MISC_PANELLINKSCALER;
+ }
+ }
+ }
+
+#ifdef SISVRAMQ
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ /* Re-Enable command queue */
+ SiSEnableTurboQueue(pScrn);
+ }
+#endif
+
+ /* Reset XV gamma correction */
+ if(pSiS->ResetXvGamma) {
+ (pSiS->ResetXvGamma)(pScrn);
+ }
+
+ /* Apply TV settings given by options
Do this even in DualHeadMode:
- if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1
- if this is called by SetModeCRT2, CRT2 mode has changed (duh!)
- -> In both cases, the settings must be re-applied.
+ -> Hence, in both cases, the settings must be re-applied.
*/
if(pSiS->VBFlags & CRT2_TV) {
int val;
@@ -7089,7 +10622,7 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
int mychtvcontrast = pSiS->chtvcontrast;
int mytvxpos = pSiS->tvxpos;
int mytvypos = pSiS->tvypos;
-#ifdef SISDUALHEAD
+#ifdef SISDUALHEAD
if(pSiSEnt && pSiS->DualHeadMode) {
mychtvlumabandwidthcvbs = pSiSEnt->chtvlumabandwidthcvbs;
mychtvlumabandwidthsvideo = pSiSEnt->chtvlumabandwidthsvideo;
@@ -7139,10 +10672,10 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
pSiSEnt->tvx = pSiS->tvx;
pSiSEnt->tvy = pSiS->tvy;
}
-#endif
+#endif
break;
case CHRONTEL_701x:
- /* TO DO */
+ /* Not supported by hardware */
break;
}
if((val = mytvxpos) != 0) {
@@ -7158,7 +10691,7 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
if(pSiSEnt && pSiS->DualHeadMode) {
mysistvedgeenhance = pSiSEnt->sistvedgeenhance;
}
-#endif
+#endif
if((val = mysistvedgeenhance) != -1) {
SiS_SetSISTVedgeenhance(pScrn, val);
}
@@ -7166,53 +10699,135 @@ void SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
if(pSiS->VBFlags & VB_SISBRIDGE) {
int mysistvantiflicker = pSiS->sistvantiflicker;
int mysistvsaturation = pSiS->sistvsaturation;
+ int mysistvcolcalibf = pSiS->sistvcolcalibf;
+ int mysistvcolcalibc = pSiS->sistvcolcalibc;
+ int mysistvcfilter = pSiS->sistvcfilter;
+ int mysistvyfilter = pSiS->sistvyfilter;
int mytvxpos = pSiS->tvxpos;
int mytvypos = pSiS->tvypos;
+ int mytvxscale = pSiS->tvxscale;
+ int mytvyscale = pSiS->tvyscale;
+ int i;
+ unsigned long cbase;
+ unsigned char ctemp;
#ifdef SISDUALHEAD
if(pSiSEnt && pSiS->DualHeadMode) {
mysistvantiflicker = pSiSEnt->sistvantiflicker;
mysistvsaturation = pSiSEnt->sistvsaturation;
+ mysistvcolcalibf = pSiSEnt->sistvcolcalibf;
+ mysistvcolcalibc = pSiSEnt->sistvcolcalibc;
+ mysistvcfilter = pSiSEnt->sistvcfilter;
+ mysistvyfilter = pSiSEnt->sistvyfilter;
mytvxpos = pSiSEnt->tvxpos;
mytvypos = pSiSEnt->tvypos;
+ mytvxscale = pSiSEnt->tvxscale;
+ mytvyscale = pSiSEnt->tvyscale;
}
-#endif
- /* Backup default TV position registers */
- inSISIDXREG(SISPART2,0x2d,pSiS->p2_2d);
+#endif
+ /* Backup default TV position, scale and colcalib registers */
+ inSISIDXREG(SISPART2,0x1f,pSiS->p2_1f);
+ inSISIDXREG(SISPART2,0x20,pSiS->p2_20);
inSISIDXREG(SISPART2,0x01,pSiS->p2_01);
inSISIDXREG(SISPART2,0x02,pSiS->p2_02);
+ inSISIDXREG(SISPART2,0x44,pSiS->p2_44);
+ inSISIDXREG(SISPART2,0x45,pSiS->p2_45);
+ if(!(pSiS->VBFlags & VB_301)) {
+ inSISIDXREG(SISPART2,0x46,pSiS->p2_46);
+ } else {
+ pSiS->p2_46 = 0;
+ }
+ inSISIDXREG(SISPART2,0x0a,pSiS->p2_0a);
+ inSISIDXREG(SISPART2,0x31,cbase);
+ cbase = (cbase & 0x7f) << 8;
+ inSISIDXREG(SISPART2,0x32,ctemp);
+ cbase = (cbase | ctemp) << 8;
+ inSISIDXREG(SISPART2,0x33,ctemp);
+ cbase = (cbase | ctemp) << 8;
+ inSISIDXREG(SISPART2,0x34,ctemp);
+ pSiS->sistvccbase = (cbase | ctemp);
+ inSISIDXREG(SISPART2,0x35,pSiS->p2_35);
+ inSISIDXREG(SISPART2,0x36,pSiS->p2_36);
+ inSISIDXREG(SISPART2,0x37,pSiS->p2_37);
+ inSISIDXREG(SISPART2,0x38,pSiS->p2_38);
+ if(!(pSiS->VBFlags & VB_301)) {
+ inSISIDXREG(SISPART2,0x47,pSiS->p2_47);
+ inSISIDXREG(SISPART2,0x48,pSiS->p2_48);
+ inSISIDXREG(SISPART2,0x49,pSiS->p2_49);
+ inSISIDXREG(SISPART2,0x4a,pSiS->p2_4a);
+ }
+ inSISIDXREG(SISPART2,0x2f,pSiS->p2_2f);
+ inSISIDXREG(SISPART2,0x30,pSiS->p2_30);
+ for(i=0; i<9; i++) {
+ inSISIDXREG(SISPART1,SiSScalingP1Regs[i],pSiS->scalingp1[i]);
+ }
+ for(i=0; i<9; i++) {
+ inSISIDXREG(SISPART4,SiSScalingP4Regs[i],pSiS->scalingp4[i]);
+ }
#ifdef SISDUALHEAD
if(pSiSEnt && pSiS->DualHeadMode) {
- pSiSEnt->p2_2d = pSiS->p2_2d;
- pSiSEnt->p2_01 = pSiS->p2_01;
- pSiSEnt->p2_02 = pSiS->p2_02;
+ pSiSEnt->p2_1f = pSiS->p2_1f; pSiSEnt->p2_20 = pSiS->p2_20;
+ pSiSEnt->p2_01 = pSiS->p2_01; pSiSEnt->p2_02 = pSiS->p2_02;
+ pSiSEnt->p2_44 = pSiS->p2_44; pSiSEnt->p2_45 = pSiS->p2_45;
+ pSiSEnt->p2_46 = pSiS->p2_46; pSiSEnt->p2_0a = pSiS->p2_0a;
+ pSiSEnt->sistvccbase = pSiS->sistvccbase;
+ pSiSEnt->p2_35 = pSiS->p2_35; pSiSEnt->p2_36 = pSiS->p2_36;
+ pSiSEnt->p2_37 = pSiS->p2_37; pSiSEnt->p2_38 = pSiS->p2_38;
+ pSiSEnt->p2_48 = pSiS->p2_48; pSiSEnt->p2_49 = pSiS->p2_49;
+ pSiSEnt->p2_4a = pSiS->p2_4a; pSiSEnt->p2_2f = pSiS->p2_2f;
+ pSiSEnt->p2_30 = pSiS->p2_30; pSiSEnt->p2_47 = pSiS->p2_47;
+ for(i=0; i<9; i++) {
+ pSiSEnt->scalingp1[i] = pSiS->scalingp1[i];
+ }
+ for(i=0; i<9; i++) {
+ pSiSEnt->scalingp4[i] = pSiS->scalingp4[i];
+ }
}
-#endif
+#endif
if((val = mysistvantiflicker) != -1) {
SiS_SetSISTVantiflicker(pScrn, val);
}
if((val = mysistvsaturation) != -1) {
SiS_SetSISTVsaturation(pScrn, val);
}
+ if((val = mysistvcfilter) != -1) {
+ SiS_SetSISTVcfilter(pScrn, val);
+ }
+ if((val = mysistvyfilter) != 1) {
+ SiS_SetSISTVyfilter(pScrn, val);
+ }
+ if((val = mysistvcolcalibc) != 0) {
+ SiS_SetSISTVcolcalib(pScrn, val, TRUE);
+ }
+ if((val = mysistvcolcalibf) != 0) {
+ SiS_SetSISTVcolcalib(pScrn, val, FALSE);
+ }
if((val = mytvxpos) != 0) {
SiS_SetTVxposoffset(pScrn, val);
}
if((val = mytvypos) != 0) {
- SiS_SetTVyposoffset(pScrn, val);
- }
+ SiS_SetTVyposoffset(pScrn, val);
+ }
+ if((val = mytvxscale) != 0) {
+ SiS_SetTVxscale(pScrn, val);
+ }
+ if((val = mytvyscale) != 0) {
+ SiS_SetTVyscale(pScrn, val);
+ }
}
}
}
/* Post-set SiS6326 TV registers */
-void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+static void
+SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
{
SISPtr pSiS = SISPTR(pScrn);
unsigned char tmp;
int val;
if(!(pSiS->SiS6326Flags & SIS6326_TVDETECTED)) return;
-
+
#ifdef UNLOCK_ALWAYS
sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
@@ -7227,7 +10842,7 @@ void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
pSiS->tvy1 = SiS6326GetTVReg(pScrn,0x11);
pSiS->tvy1 |= ((SiS6326GetTVReg(pScrn,0x13) & 0x30) << 4);
- /* TW: Handle TVPosOffset options (BEFORE switching on TV) */
+ /* Handle TVPosOffset options (BEFORE switching on TV) */
if((val = pSiS->tvxpos) != 0) {
SiS_SetTVxposoffset(pScrn, val);
}
@@ -7235,8 +10850,8 @@ void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
SiS_SetTVyposoffset(pScrn, val);
}
- /* TW: Switch on TV output. This is rather complicated, but
- * if we don't do it, TV output will flicker terribly.
+ /* Switch on TV output. This is rather complicated, but
+ * if we don't do it, TV output will flicker terribly.
*/
if(pSiS->SiS6326Flags & SIS6326_TVON) {
orSISIDXREG(SISSR, 0x01, 0x20);
@@ -7265,8 +10880,8 @@ void SiS6326PostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg)
tmp = SiS6326GetTVReg(pScrn,0x00);
if(!(tmp & 0x04)) return;
- /* TW: Apply TV settings given by options */
- if((val = pSiS->sis6326antiflicker) != -1) {
+ /* Apply TV settings given by options */
+ if((val = pSiS->sistvantiflicker) != -1) {
SiS_SetSIS6326TVantiflicker(pScrn, val);
}
if((val = pSiS->sis6326enableyfilter) != -1) {
@@ -7296,7 +10911,7 @@ SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn)
}
}
-/* TW: Build a list of the VESA modes the BIOS reports as valid */
+/* Build a list of the VESA modes the BIOS reports as valid */
static void
SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
{
@@ -7309,7 +10924,7 @@ SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
int id = vbe->VideoModePtr[i++];
int bpp;
- if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
+ if((mode = VBEGetModeInfo(pVbe, id)) == NULL)
continue;
bpp = mode->BitsPerPixel;
@@ -7322,7 +10937,7 @@ SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
m->next = pSiS->SISVESAModeList;
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
+ "BIOS supports VESA mode 0x%x: x:%i y:%i bpp:%i\n",
m->n, m->width, m->height, m->bpp);
pSiS->SISVESAModeList = m;
@@ -7331,7 +10946,7 @@ SiSBuildVesaModeList(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe)
}
}
-/* TW: Calc VESA mode from given resolution/depth */
+/* Calc VESA mode from given resolution/depth */
static UShort
SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
@@ -7353,6 +10968,16 @@ SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
mode->HDisplay, mode->VDisplay, pScrn->bitsPerPixel);
switch(mode->HDisplay) {
+ case 320:
+ if(mode->VDisplay == 200)
+ ModeIndex = VESAModeIndex_320x200[i];
+ else if(mode->VDisplay == 240)
+ ModeIndex = VESAModeIndex_320x240[i];
+ break;
+ case 400:
+ if(mode->VDisplay == 300)
+ ModeIndex = VESAModeIndex_400x300[i];
+ break;
case 512:
if(mode->VDisplay == 384)
ModeIndex = VESAModeIndex_512x384[i];
@@ -7360,6 +10985,8 @@ SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
case 640:
if(mode->VDisplay == 480)
ModeIndex = VESAModeIndex_640x480[i];
+ else if(mode->VDisplay == 400)
+ ModeIndex = VESAModeIndex_640x400[i];
break;
case 800:
if(mode->VDisplay == 600)
@@ -7390,7 +11017,97 @@ SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode)
return(ModeIndex);
}
-/* TW: Calculate the vertical refresh rate from a mode */
+USHORT
+SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN havecustommodes)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;
+
+ if(!(VBFlags & CRT1_LCDA)) {
+ if((havecustommodes) && (!(mode->type & M_T_DEFAULT))) {
+ return 0xfe;
+ }
+ } else {
+ if((mode->HDisplay > pSiS->LCDwidth) ||
+ (mode->VDisplay > pSiS->LCDheight)) {
+ return 0;
+ }
+ }
+
+ return(SiS_GetModeID(pSiS->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay, i, pSiS->FSTN));
+}
+
+USHORT
+SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN havecustommodes)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1;
+ UShort ModeIndex = 0;
+ int j;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Inside CheckCalcModeIndex (VBFlags %x, mode %dx%d)\n",
+ VBFlags,mode->HDisplay, mode->VDisplay);
+#endif
+
+ if(VBFlags & CRT2_LCD) { /* CRT2 is LCD */
+
+ if(pSiS->SiS_Pr->CP_HaveCustomData) {
+ for(j=0; j<7; j++) {
+ if((pSiS->SiS_Pr->CP_DataValid[j]) &&
+ (mode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[j]) &&
+ (mode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[j]) &&
+ (mode->type & M_T_BUILTIN))
+ return 0xfe;
+ }
+ }
+
+ if((pSiS->AddedPlasmaModes) && (mode->type & M_T_BUILTIN))
+ return 0xfe;
+
+ if((havecustommodes) &&
+ (!(mode->type & M_T_DEFAULT)) &&
+ (!(mode->Flags & V_INTERLACE)))
+ return 0xfe;
+
+ if( ((mode->HDisplay <= pSiS->LCDwidth) &&
+ (mode->VDisplay <= pSiS->LCDheight)) ||
+ ((pSiS->SiS_Pr->SiS_CustomT == CUT_PANEL848) &&
+ (((mode->HDisplay == 1360) && (mode->HDisplay == 768)) ||
+ ((mode->HDisplay == 1024) && (mode->HDisplay == 768)) ||
+ ((mode->HDisplay == 800) && (mode->HDisplay == 600)))) ) {
+
+ ModeIndex = SiS_GetModeID_LCD(pSiS->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay, i,
+ pSiS->FSTN, pSiS->SiS_Pr->SiS_CustomT, pSiS->LCDwidth, pSiS->LCDheight);
+
+ }
+
+ } else if(VBFlags & CRT2_TV) { /* CRT2 is TV */
+
+ ModeIndex = SiS_GetModeID_TV(pSiS->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay, i);
+
+ } else if(VBFlags & CRT2_VGA) { /* CRT2 is VGA2 */
+
+ if((pSiS->AddedPlasmaModes) && (mode->type & M_T_BUILTIN))
+ return 0xfe;
+
+ if((havecustommodes) &&
+ (!(mode->type & M_T_DEFAULT)) &&
+ (!(mode->Flags & V_INTERLACE)))
+ return 0xfe;
+
+ ModeIndex = SiS_GetModeID_VGA2(pSiS->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay, i);
+
+ } else { /* CRT1 only, no CRT2 */
+
+ ModeIndex = SiS_CalcModeIndex(pScrn, mode, VBFlags, havecustommodes);
+
+ }
+
+ return(ModeIndex);
+}
+
+/* Calculate the vertical refresh rate from a mode */
int
SiSCalcVRate(DisplayModePtr mode)
{
@@ -7423,10 +11140,10 @@ SiSCalcVRate(DisplayModePtr mode)
return((int)(refresh));
}
-/* TW: Calculate CR33 (rate index) for CRT1.
- * Calculation is done using currentmode, therefore it is
- * recommended to set VertRefresh and HorizSync to correct
- * values in config file.
+/* Calculate CR33 (rate index) for CRT1.
+ * Calculation is done using currentmode, therefore it is
+ * recommended to set VertRefresh and HorizSync to correct
+ * values in config file.
*/
unsigned char
SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
@@ -7441,8 +11158,8 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
irefresh = SiSCalcVRate(mode);
if(!irefresh) {
- if(xres == 800 || xres == 1024 || xres == 1280) return 0x02;
- else return 0x01;
+ if(xres == 800 || xres == 1024 || xres == 1280) return 0x02;
+ else return 0x01;
}
/* SiS730 has troubles on CRT2 if CRT1 is at 32bpp */
@@ -7462,8 +11179,8 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
-#endif
+ xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
+#endif
/* We need the REAL refresh rate here */
if(mode->Flags & V_INTERLACE)
@@ -7471,8 +11188,8 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
/* Do not multiply by 2 when DBLSCAN! */
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
#endif
index = 0;
@@ -7491,6 +11208,9 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
index = sisx_vrate[i - 1].idx;
}
break;
+ } else if((irefresh - sisx_vrate[i].refresh) <= 2) {
+ index = sisx_vrate[i].idx;
+ break;
}
}
}
@@ -7499,7 +11219,7 @@ SISSearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
if(index > 0)
return index;
else {
- /* TW: Default Rate index */
+ /* Default Rate index */
if(xres == 800 || xres == 1024 || xres == 1280) return 0x02;
else return 0x01;
}
@@ -7515,10 +11235,13 @@ SISWaitRetraceCRT1(ScrnInfoPtr pScrn)
inSISIDXREG(SISCR,0x17,temp);
if(!(temp & 0x80)) return;
- watchdog = 65536;
- while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
+ inSISIDXREG(SISSR,0x1f,temp);
+ if(temp & 0xc0) return;
+
watchdog = 65536;
while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
+ watchdog = 65536;
+ while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
}
void
@@ -7528,12 +11251,17 @@ SISWaitRetraceCRT2(ScrnInfoPtr pScrn)
int watchdog;
unsigned char temp, reg;
+ if(SiSBridgeIsInSlaveMode(pScrn)) {
+ SISWaitRetraceCRT1(pScrn);
+ return;
+ }
+
switch(pSiS->VGAEngine) {
case SIS_300_VGA:
- reg = 0x28;
+ reg = 0x25;
break;
case SIS_315_VGA:
- reg = 0x33;
+ reg = 0x30;
break;
default:
return;
@@ -7542,12 +11270,12 @@ SISWaitRetraceCRT2(ScrnInfoPtr pScrn)
watchdog = 65536;
do {
inSISIDXREG(SISPART1, reg, temp);
- if(temp & 0x80) break;
+ if(!(temp & 0x02)) break;
} while(--watchdog);
watchdog = 65536;
do {
inSISIDXREG(SISPART1, reg, temp);
- if(!(temp & 0x80)) break;
+ if(temp & 0x02) break;
} while(--watchdog);
}
@@ -7556,25 +11284,60 @@ SISWaitVBRetrace(ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
+ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
#ifdef SISDUALHEAD
- if(pSiS->DualHeadMode) {
- if(pSiS->SecondHead)
- SISWaitRetraceCRT1(pScrn);
- else
- SISWaitRetraceCRT2(pScrn);
- } else {
+ if(pSiS->DualHeadMode) {
+ if(pSiS->SecondHead)
+ SISWaitRetraceCRT1(pScrn);
+ else
+ SISWaitRetraceCRT2(pScrn);
+ } else {
#endif
- if(pSiS->VBFlags & DISPTYPE_DISP1) {
- SISWaitRetraceCRT1(pScrn);
- }
- if(pSiS->VBFlags & DISPTYPE_DISP2) {
- if(!(SiSBridgeIsInSlaveMode(pScrn))) {
- SISWaitRetraceCRT2(pScrn);
- }
- }
+ if(pSiS->VBFlags & DISPTYPE_DISP1) {
+ SISWaitRetraceCRT1(pScrn);
+ }
+ if(pSiS->VBFlags & DISPTYPE_DISP2) {
+ if(!(SiSBridgeIsInSlaveMode(pScrn))) {
+ SISWaitRetraceCRT2(pScrn);
+ }
+ }
#ifdef SISDUALHEAD
- }
+ }
#endif
+ } else {
+ SISWaitRetraceCRT1(pScrn);
+ }
+}
+
+#define MODEID_OFF 0x449
+
+unsigned char
+SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
+{
+ return(SiS_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
+}
+
+unsigned char
+SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
+{
+ unsigned char ret;
+ unsigned char *base;
+
+ base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
+ if(!base) {
+ SISErrorLog(pScrn, "(Could not map BIOS scratch area)\n");
+ return 0;
+ }
+
+ ret = *(base + offset);
+
+ /* value != 0xff means: set register */
+ if(value != 0xff)
+ *(base + offset) = value;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
+
+ return ret;
}
void
@@ -7599,15 +11362,16 @@ sisSaveUnlockExtRegisterLock(SISPtr pSiS, unsigned char *reg1, unsigned char *re
unsigned char val1, val2;
int i;
#endif
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
- "Failed to unlock sr registers (%p, %x, 0x%02x; %d)\n",
- pSiS, pSiS->RelIO, val, mylockcalls);
+ SISErrorLog(pSiS->pScrn,
+ "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
+ (void *)pSiS, (unsigned long)pSiS->RelIO, val, mylockcalls);
#ifdef TWDEBUG
for(i = 0; i <= 0x3f; i++) {
inSISIDXREG(SISSR, i, val1);
inSISIDXREG(0x3c4, i, val2);
xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
- "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n", i, val1, val2, mylockcalls);
+ "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n",
+ i, val1, val2, mylockcalls);
}
#endif
if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
@@ -7626,9 +11390,9 @@ sisSaveUnlockExtRegisterLock(SISPtr pSiS, unsigned char *reg1, unsigned char *re
outSISIDXREG(SISCR, 0x80, 0x86);
inSISIDXREG(SISCR, 0x80, val);
if(val != 0xA1) {
- xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR,
- "Failed to unlock cr registers (%p, %x, 0x%02x)\n",
- pSiS, pSiS->RelIO, val);
+ SISErrorLog(pSiS->pScrn,
+ "Failed to unlock cr registers (%p, %lx, 0x%02x)\n",
+ (void *)pSiS, (unsigned long)pSiS->RelIO, val);
}
}
}