summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Winischhofer <thomas@winischhofer.net>2005-07-19 23:31:49 +0000
committerThomas Winischhofer <thomas@winischhofer.net>2005-07-19 23:31:49 +0000
commit5be938441d8c42bd57b68d6759e25b0e25659988 (patch)
treec982db625936be421c75dbfe556758802713ca82
parent1d4febacb8f831d540470622289149088799dd54 (diff)
SiS driver: Some fixes for multiple cards. Small fix for mode switching onXORG-6_8_99_16
newer machines. Prepare for Dave's PCI cleanup.
-rw-r--r--src/init.c70
-rw-r--r--src/init.h9
-rw-r--r--src/init301.c55
-rw-r--r--src/init301.h3
-rw-r--r--src/sis.h22
-rw-r--r--src/sis_dri.c12
-rw-r--r--src/sis_driver.c1091
-rw-r--r--src/sis_driver.h8
-rw-r--r--src/sis_utility.c12
9 files changed, 751 insertions, 531 deletions
diff --git a/src/init.c b/src/init.c
index ff208fb..2ab3868 100644
--- a/src/init.c
+++ b/src/init.c
@@ -1095,10 +1095,11 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr)
case SIS_630:
case SIS_730:
/* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
- * - RELOCATED VGA IO (0x20)
- * - MMIO ENABLE (0x1)
+ * - RELOCATED VGA IO ENABLED (0x20)
+ * - MMIO ENABLED (0x01)
+ * Leave other bits untouched.
*/
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
/* - Enable 2D (0x40)
* - Enable 3D (0x02)
* - Enable 3D Vertex command fetch (0x10) ?
@@ -1121,7 +1122,8 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr)
case SIS_761:
case SIS_340:
case XGI_40:
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ /* See above */
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
/* - Enable 3D G/L transformation engine (0x80)
* - Enable 2D (0x40)
* - Enable 3D vertex command fetch (0x10)
@@ -1132,7 +1134,8 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr)
break;
case XGI_20:
case SIS_550:
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+ /* See above */
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
/* No 3D engine ! */
/* - Enable 2D (0x40)
* - disable 3D
@@ -3126,7 +3129,7 @@ SiS_ResetVB(struct SiS_Private *SiS_Pr)
}
/*********************************************/
-/* HELPER: SET VIDEO REGISTERS */
+/* HELPER: SET VIDEO/CAPTURE REGISTERS */
/*********************************************/
static void
@@ -3151,6 +3154,55 @@ SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
}
/*********************************************/
+/* HELPER: SET AGP TIMING FOR SiS760 */
+/*********************************************/
+
+static void
+SiS_Handle760(struct SiS_Private *SiS_Pr)
+{
+#ifdef SIS315H
+ unsigned int somebase;
+ unsigned char temp1, temp2, temp3;
+
+ if( (SiS_Pr->ChipType != SIS_760) ||
+ ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) ||
+ (!(SiS_Pr->SiS_SysFlags & SF_760LFB)) ||
+ (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
+ return;
+
+#ifdef SIS_LINUX_KERNEL
+ somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
+#else
+ somebase = pciReadWord(0x00001000, 0x74);
+#endif
+ somebase &= 0xffff;
+
+ if(somebase == 0) return;
+
+ temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7;
+
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+ temp1 = 0x21;
+ temp2 = 0x03;
+ temp3 |= 0x08;
+ } else {
+ temp1 = 0x25;
+ temp2 = 0x0b;
+ }
+
+#ifdef SIS_LINUX_KERNEL
+ sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
+ sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
+#else
+ pciWriteByte(0x00000000, 0x7e, temp1);
+ pciWriteByte(0x00000000, 0x8d, temp2);
+#endif
+
+ SiS_SetRegByte((somebase + 0x85), temp3);
+#endif
+}
+
+/*********************************************/
/* X.org/XFree86: SET SCREEN PITCH */
/*********************************************/
@@ -3386,6 +3438,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_CloseCRTC(SiS_Pr);
+ SiS_Handle760(SiS_Pr);
+
#ifdef SIS_LINUX_KERNEL
/* We never lock registers in XF86 */
if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
@@ -3602,6 +3656,8 @@ SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
/* SetPitch: Adapt to virtual size & position */
SiS_SetPitchCRT2(SiS_Pr, pScrn);
+ SiS_Handle760(SiS_Pr);
+
return TRUE;
}
@@ -3777,6 +3833,8 @@ SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
}
}
+ SiS_Handle760(SiS_Pr);
+
/* Backup/Set ModeNo in BIOS scratch area */
SiS_GetSetModeID(pScrn,ModeNo);
diff --git a/src/init.h b/src/init.h
index 85ee49e..4422812 100644
--- a/src/init.h
+++ b/src/init.h
@@ -78,6 +78,9 @@
#include <linux/types.h>
#include <asm/io.h>
#include <linux/fb.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include <video/fbcon.h>
+#endif
#include "sis.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/sisfb.h>
@@ -1631,6 +1634,12 @@ extern unsigned short SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode,
extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
extern void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg,
unsigned int val);
+extern unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
+#endif
+#ifdef SIS315H
+extern void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg,
+ unsigned char val);
+extern unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
#endif
#endif
diff --git a/src/init301.c b/src/init301.c
index 61a2683..b7c25cf 100644
--- a/src/init301.c
+++ b/src/init301.c
@@ -3867,12 +3867,14 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
/*********************************************/
#ifdef SIS315H
-static void
+static int
SiS_HandlePWD(struct SiS_Private *SiS_Pr)
{
+ int ret = 0;
#ifdef SET_PWD
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
+ unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
unsigned short temp;
if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
@@ -3884,10 +3886,19 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr)
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
temp = 0x00;
- if(ROMAddr[romptr + 2] & (0x06 << 1)) temp = 0x80;
+ if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
+ temp = 0x80;
+ ret = 1;
+ }
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
+#ifdef SIS_XORG_XF86
+#ifdef TWDEBUG
+ xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
+#endif
+#endif
}
#endif
+ return ret;
}
#endif
@@ -3948,6 +3959,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
#ifdef SIS315H /* 315 series */
+ int didpwd = 0;
BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
(SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
@@ -3963,13 +3975,17 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
}
#endif
- SiS_HandlePWD(SiS_Pr);
+ didpwd = SiS_HandlePWD(SiS_Pr);
if( (modenum <= 0x13) ||
(SiS_IsVAMode(SiS_Pr)) ||
(!(SiS_IsDualEdge(SiS_Pr))) ) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
- if(custom1) SiS_PanelDelay(SiS_Pr, 3);
+ if(!didpwd) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
+ if(custom1) SiS_PanelDelay(SiS_Pr, 3);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
+ }
}
if(!custom1) {
@@ -4046,8 +4062,11 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
if( (!(SiS_IsVAMode(SiS_Pr))) &&
(!(SiS_CRT2IsLCD(SiS_Pr))) &&
(!(SiS_IsDualEdge(SiS_Pr))) ) {
+
if(custom1) SiS_PanelDelay(SiS_Pr, 2);
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+ if(!didpwd) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+ }
if(custom1) SiS_PanelDelay(SiS_Pr, 4);
}
@@ -4374,6 +4393,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
#ifdef SET_EMI
unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
+ int didpwd = 0;
/* unsigned short emidelay=0; */
#endif
@@ -4406,12 +4426,19 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
}
- SiS_HandlePWD(SiS_Pr);
+ didpwd = SiS_HandlePWD(SiS_Pr);
if(SiS_IsVAorLCD(SiS_Pr)) {
- if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
- SiS_PanelDelayLoop(SiS_Pr, 3, 2);
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ if(!didpwd) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+ SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ SiS_PanelDelayLoop(SiS_Pr, 3, 2);
+ if(SiS_Pr->SiS_VBType & VB_SISEMI) {
+ SiS_GenericDelay(SiS_Pr, 17664);
+ }
+ }
+ } else {
SiS_PanelDelayLoop(SiS_Pr, 3, 2);
if(SiS_Pr->SiS_VBType & VB_SISEMI) {
SiS_GenericDelay(SiS_Pr, 17664);
@@ -4613,6 +4640,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
if( (SiS_LCDAEnabled(SiS_Pr)) ||
(SiS_CRT2IsLCD(SiS_Pr)) ) {
if(r30 & 0x40) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);
SiS_PanelDelayLoop(SiS_Pr, 3, 5);
if(delaylong) {
SiS_PanelDelayLoop(SiS_Pr, 3, 5);
@@ -4624,6 +4652,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
SiS_GenericDelay(SiS_Pr, 1280);
}
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
}
}
#endif
@@ -4641,7 +4670,11 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
SiS_GenericDelay(SiS_Pr, 2048);
SiS_WaitVBRetrace(SiS_Pr);
}
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+ if(!didpwd) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+ } else {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
+ }
}
}
diff --git a/src/init301.h b/src/init301.h
index d729f4e..3dcfbf6 100644
--- a/src/init301.h
+++ b/src/init301.h
@@ -72,6 +72,9 @@
#include <linux/types.h>
#include <asm/io.h>
#include <linux/fb.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#include <video/fbcon.h>
+#endif
#include "sis.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/sisfb.h>
diff --git a/src/sis.h b/src/sis.h
index 3e127eb..181361c 100644
--- a/src/sis.h
+++ b/src/sis.h
@@ -37,7 +37,7 @@
#define SISDRIVERVERSIONYEAR 5
#define SISDRIVERVERSIONMONTH 7
-#define SISDRIVERVERSIONDAY 15
+#define SISDRIVERVERSIONDAY 20
#define SISDRIVERREVISION 1
#define SISDRIVERIVERSION ((SISDRIVERVERSIONYEAR << 16) | \
@@ -253,6 +253,20 @@
#endif
#endif
+#if 0 /* Perhaps for future use */
+#if 1
+#define SIS_PCI_BUS(a) (a)->bus
+#define SIS_PCI_DEVICE(a) (a)->device
+#define SIS_PCI_FUNC(a) (a)->func
+#define SIS_PCI_TAG(a) pciTag((a)->bus, (a)->device, (a)->func);
+#else
+#define SIS_PCI_BUS(a) (a)->pciid.bus
+#define SIS_PCI_DEVICE(a) (a)->pciid.device
+#define SIS_PCI_FUNC(a) (a)->pciid.func
+#define SIS_PCI_TAG(a) pciTag(&((a)->pciid));
+#endif
+#endif
+
#ifdef TWDEBUG
#define SISVERBLEVEL 3
#else
@@ -664,6 +678,9 @@ typedef unsigned char UChar;
#define SIS_CPUFL_SSE2 0x0080
#define SIS_CPUFL_FLAG 0x8000
+/* Convenience macro for sisfb version checks */
+#define SISFB_VERSION(a,b,c) ((a << 16) | (b << 8) | c)
+
/* For backup of register contents */
typedef struct {
UChar sisRegMiscOut;
@@ -867,6 +884,7 @@ typedef struct _region {
typedef struct {
ScrnInfoPtr pScrn;
pciVideoPtr PciInfo;
+ int PciBus, PciDevice, PciFunc;
PCITAG PciTag;
EntityInfoPtr pEnt;
int Chipset;
@@ -1102,6 +1120,7 @@ typedef struct {
UShort SiS_DDC2_Data;
UShort SiS_DDC2_Clk;
Bool Primary; /* Display adapter is primary */
+ Bool VGADecodingEnabled; /* a0000 memory adress decoding is enabled */
xf86Int10InfoPtr pInt; /* Our int10 */
int oldChipset; /* Type of old chipset */
int RealVideoRam; /* 6326 can only address 4MB, but TQ can be above */
@@ -1149,6 +1168,7 @@ typedef struct {
unsigned int sisfbHeapSize, sisfbVideoOffset;
Bool sisfbxSTN;
unsigned int sisfbDSTN, sisfbFSTN;
+ Bool sisfbcanpost, sisfbcardposted, sisfbprimary;
char sisfbdevname[16];
int EMI;
int PRGB;
diff --git a/src/sis_dri.c b/src/sis_dri.c
index 8f0a037..14ce6d9 100644
--- a/src/sis_dri.c
+++ b/src/sis_dri.c
@@ -320,9 +320,7 @@ SISDRIScreenInit(ScreenPtr pScreen)
#endif
pDRIInfo->busIdString = xalloc(64);
sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->busnum,
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->devnum,
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->funcnum);
+ pSIS->PciBus, pSIS->PciDevice, pSIS->PciFunc);
#ifdef SISHAVECREATEBUSID
}
#endif
@@ -630,16 +628,12 @@ SISDRIScreenInit(ScreenPtr pScreen)
/* Eventually grab and enable IRQ */
pSIS->irqEnabled = FALSE;
pSIS->irq = drmGetInterruptFromBusID(pSIS->drmSubFD,
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->busnum,
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->devnum,
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->funcnum);
+ pSIS->PciBus, pSIS->PciDevice, pSIS->PciFunc);
if(pSIS->irq < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"[drm] No valid IRQ number for device %d:%d:%d (code %d)\n",
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->busnum,
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->devnum,
- ((pciConfigPtr)pSIS->PciInfo->thisCard)->funcnum,
+ pSIS->PciBus, pSIS->PciDevice, pSIS->PciFunc,
pSIS->irq);
} else if((drmCtlInstHandler(pSIS->drmSubFD, pSIS->irq)) != 0) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff --git a/src/sis_driver.c b/src/sis_driver.c
index 6b15984..90a7d92 100644
--- a/src/sis_driver.c
+++ b/src/sis_driver.c
@@ -2852,6 +2852,19 @@ SiS_LoadInitVBE(ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
+ /* Don't load the VBE module for secondary
+ * cards which sisfb POSTed. We don't want
+ * int10 to overwrite our set up (such as
+ * disabled a0000 memory address decoding).
+ * We don't need the VBE anyway because
+ * the card will never be in text mode,
+ * and we can restore graphics modes just
+ * perfectly.
+ */
+ if( !pSiS->Primary &&
+ pSiS->sisfbcardposted)
+ return;
+
if(pSiS->pVbe) return;
if(xf86LoadSubModule(pScrn, "vbe")) {
@@ -2879,8 +2892,10 @@ SiS_MapVGAMem(ScrnInfoPtr pScrn)
/* Map 64k VGA window for saving/restoring CGA fonts */
pSiS->VGAMapSize = 0x10000;
pSiS->VGAMapPhys = 0; /* Default */
- if(!pSiS->Primary) {
- /* If secondary, set Phys to beginning of our video RAM */
+ if((!pSiS->Primary) || (!pSiS->VGADecodingEnabled)) {
+ /* If card is secondary or if a0000-address decoding
+ * is disabled, set Phys to beginning of our video RAM.
+ */
pSiS->VGAMapPhys = pSiS->PciInfo->memBase[0];
}
if(!SiSVGAMapMem(pScrn)) {
@@ -2892,6 +2907,220 @@ SiS_MapVGAMem(ScrnInfoPtr pScrn)
#endif
static void
+SiS_CheckKernelFB(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int fd, i;
+ CARD32 sisfbinfosize = 0, sisfbversion;
+ sisfb_info *mysisfbinfo;
+ char name[16];
+
+ pSiS->donttrustpdc = FALSE;
+ pSiS->sisfbpdc = 0xff;
+ pSiS->sisfbpdca = 0xff;
+ pSiS->sisfblcda = 0xff;
+ pSiS->sisfbscalelcd = -1;
+ pSiS->sisfbspecialtiming = CUT_NONE;
+ pSiS->sisfb_haveemi = FALSE;
+ pSiS->sisfbfound = FALSE;
+ pSiS->sisfb_tvposvalid = FALSE;
+ pSiS->sisfbdevname[0] = 0;
+ pSiS->sisfb_havelock = FALSE;
+ pSiS->sisfbHaveNewHeapDef = FALSE;
+ pSiS->sisfbHeapSize = 0;
+ pSiS->sisfbVideoOffset = 0;
+ pSiS->sisfbxSTN = FALSE;
+ pSiS->sisfbcanpost = FALSE; /* (Old) sisfb can't POST card */
+ pSiS->sisfbcardposted = TRUE; /* If (old) sisfb is running, card must have been POSTed */
+ pSiS->sisfbprimary = FALSE; /* (Old) sisfb doesn't know */
+
+ if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
+
+ i = 0;
+ do {
+
+ if(i <= 7) {
+ sprintf(name, "/dev/fb%1d", i);
+ } else {
+ sprintf(name, "/dev/fb/%1d", (i - 8));
+ }
+
+ if((fd = open(name, 'r')) != -1) {
+
+ Bool gotit = FALSE;
+
+ if(!ioctl(fd, SISFB_GET_INFO_SIZE, &sisfbinfosize)) {
+ if((mysisfbinfo = xalloc(sisfbinfosize))) {
+ if(!ioctl(fd, (SISFB_GET_INFO | (sisfbinfosize << 16)), mysisfbinfo)) {
+ gotit = TRUE;
+ } else {
+ xfree(mysisfbinfo);
+ mysisfbinfo = NULL;
+ }
+ }
+ } else {
+ if((mysisfbinfo = xalloc(sizeof(*mysisfbinfo) + 16))) {
+ if(!ioctl(fd, SISFB_GET_INFO_OLD, mysisfbinfo)) {
+ gotit = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Possibly old version of sisfb detected. Please update.\n");
+ } else {
+ xfree(mysisfbinfo);
+ mysisfbinfo = NULL;
+ }
+ }
+ }
+
+ if(gotit) {
+
+ if(mysisfbinfo->sisfb_id == SISFB_ID) {
+
+ sisfbversion = (mysisfbinfo->sisfb_version << 16) |
+ (mysisfbinfo->sisfb_revision << 8) |
+ (mysisfbinfo->sisfb_patchlevel);
+
+ if(sisfbversion >= SISFB_VERSION(1, 5, 8)) {
+ /* 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->PciBus) &&
+ (mysisfbinfo->sisfb_pcislot == pSiS->PciDevice) &&
+ (mysisfbinfo->sisfb_pcifunc == pSiS->PciFunc)) {
+ 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->PciBus,
+ pSiS->PciDevice,
+ pSiS->PciFunc);
+
+ /* 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");
+ }
+ /* Basically, we can't trust the pdc register if sisfb is loaded */
+ pSiS->donttrustpdc = TRUE;
+ pSiS->sisfbHeapStart = mysisfbinfo->heapstart;
+
+ if(sisfbversion >= SISFB_VERSION(1, 7, 20)) {
+ pSiS->sisfbHeapSize = mysisfbinfo->sisfb_heapsize;
+ pSiS->sisfbVideoOffset = mysisfbinfo->sisfb_videooffset;
+ pSiS->sisfbHaveNewHeapDef = TRUE;
+ pSiS->sisfbFSTN = mysisfbinfo->sisfb_curfstn;
+ pSiS->sisfbDSTN = mysisfbinfo->sisfb_curdstn;
+ pSiS->sisfbxSTN = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: memory heap at %dKB, size %dKB, viewport at %dKB\n",
+ (int)pSiS->sisfbHeapStart, (int)pSiS->sisfbHeapSize,
+ (int)pSiS->sisfbVideoOffset/1024);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: memory heap at %dKB\n", (int)pSiS->sisfbHeapStart);
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: using video mode 0x%02x\n", mysisfbinfo->fbvidmode);
+ pSiS->OldMode = mysisfbinfo->fbvidmode;
+ if(sisfbversion >= SISFB_VERSION(1, 5, 6)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb: using %s, reserved %dK\n",
+ (mysisfbinfo->sisfb_caps & 0x40) ? "SiS300 series Turboqueue" :
+ (mysisfbinfo->sisfb_caps & 0x20) ? "SiS315/330/340 series AGP command queue" :
+ (mysisfbinfo->sisfb_caps & 0x10) ? "SiS315/330/340 series VRAM command queue" :
+ (mysisfbinfo->sisfb_caps & 0x08) ? "SiS315/330/340 series MMIO mode" :
+ "no command queue",
+ (int)mysisfbinfo->sisfb_tqlen);
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 5, 10)) {
+ /* We can trust the pdc value if sisfb is of recent version */
+ if(pSiS->VGAEngine == SIS_300_VGA) pSiS->donttrustpdc = FALSE;
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 5, 11)) {
+ 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(!pSiS->sisfbpdc) pSiS->sisfbpdc = 0xff;
+ }
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 5, 14)) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ pSiS->sisfblcda = mysisfbinfo->sisfb_lcda;
+ }
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 6, 13)) {
+ pSiS->sisfbscalelcd = mysisfbinfo->sisfb_scalelcd;
+ pSiS->sisfbspecialtiming = mysisfbinfo->sisfb_specialtiming;
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 6, 16)) {
+ if(pSiS->VGAEngine == SIS_315_VGA) {
+ pSiS->donttrustpdc = FALSE;
+ pSiS->sisfbpdc = mysisfbinfo->sisfb_lcdpdc;
+ if(sisfbversion >= SISFB_VERSION(1, 6, 24)) {
+ pSiS->sisfb_haveemi = mysisfbinfo->sisfb_haveemi ? TRUE : FALSE;
+ pSiS->sisfb_haveemilcd = TRUE; /* will match most cases */
+ pSiS->sisfb_emi30 = mysisfbinfo->sisfb_emi30;
+ pSiS->sisfb_emi31 = mysisfbinfo->sisfb_emi31;
+ pSiS->sisfb_emi32 = mysisfbinfo->sisfb_emi32;
+ pSiS->sisfb_emi33 = mysisfbinfo->sisfb_emi33;
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 6, 25)) {
+ pSiS->sisfb_haveemilcd = mysisfbinfo->sisfb_haveemilcd ? TRUE : FALSE;
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 6, 31)) {
+ pSiS->sisfbpdca = mysisfbinfo->sisfb_lcdpdca;
+ } else {
+ if(pSiS->sisfbpdc) {
+ pSiS->sisfbpdca = (pSiS->sisfbpdc & 0xf0) >> 3;
+ pSiS->sisfbpdc = (pSiS->sisfbpdc & 0x0f) << 1;
+ } else {
+ pSiS->sisfbpdca = pSiS->sisfbpdc = 0xff;
+ }
+ }
+ }
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 7, 0)) {
+ pSiS->sisfb_havelock = TRUE;
+ if(sisfbversion >= SISFB_VERSION(1, 7, 1)) {
+ pSiS->sisfb_tvxpos = mysisfbinfo->sisfb_tvxpos;
+ pSiS->sisfb_tvypos = mysisfbinfo->sisfb_tvypos;
+ pSiS->sisfb_tvposvalid = TRUE;
+ }
+ }
+ if(sisfbversion >= SISFB_VERSION(1, 8, 7)) {
+ pSiS->sisfbcanpost = (mysisfbinfo->sisfb_can_post) ? TRUE : FALSE;
+ pSiS->sisfbcardposted = (mysisfbinfo->sisfb_card_posted) ? TRUE : FALSE;
+ pSiS->sisfbprimary = (mysisfbinfo->sisfb_was_boot_device) ? TRUE : FALSE;
+ /* Validity check */
+ if(!pSiS->sisfbcardposted) {
+ pSiS->sisfbprimary = FALSE;
+ }
+ }
+ }
+ }
+ xfree(mysisfbinfo);
+ mysisfbinfo = NULL;
+ }
+ close (fd);
+ }
+ i++;
+ } while((i <= 15) && (!pSiS->sisfbfound));
+
+ if(pSiS->sisfbfound) {
+ strncpy(pSiS->sisfbdevname, name, 15);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "sisfb not found\n");
+ }
+ }
+}
+
+static void
SiSPseudo(ScrnInfoPtr pScrn)
{
}
@@ -3028,6 +3257,8 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS = SISPTR(pScrn);
pSiS->pScrn = pScrn;
+ pSiS->pInt = NULL;
+
/* Save PCI Domain Base */
#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
pSiS->IODBase = 0;
@@ -3037,38 +3268,31 @@ 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) {
+ if(pSiS->pEnt->location.type != BUS_PCI) {
SISErrorLog(pScrn, "Entity's bus type is not PCI\n");
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_0;
}
#ifdef SISDUALHEAD
/* Allocate an entity private if necessary */
if(xf86IsEntityShared(pScrn->entityList[0])) {
- pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0],
- SISEntityIndex)->ptr;
+ pSiSEnt = xf86GetEntityPrivate(pScrn->entityList[0], SISEntityIndex)->ptr;
pSiS->entityPrivate = pSiSEnt;
/* 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;
+ SISErrorLog(pScrn, "First head encountered fatal error, aborting...\n");
+ goto my_error_0;
}
}
#endif
/* Find the PCI info for this screen */
pSiS->PciInfo = xf86GetPciInfoForEntity(pSiS->pEnt->index);
- pSiS->PciTag = pciTag(pSiS->PciInfo->bus, pSiS->PciInfo->device, pSiS->PciInfo->func);
-
- /* Determine whether this is primary or secondary display adapter */
- pSiS->Primary = xf86IsPrimaryPci(pSiS->PciInfo);
- if(!pSiS->Primary) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "This adapter is a secondary display adapter\n");
- }
+ pSiS->PciBus = ((pciConfigPtr)pSiS->PciInfo->thisCard)->busnum; /*SIS_PCI_BUS(pSiS->PciInfo);*/
+ pSiS->PciDevice = ((pciConfigPtr)pSiS->PciInfo->thisCard)->devnum; /*SIS_PCI_DEVICE(pSiS->PciInfo);*/
+ pSiS->PciFunc = ((pciConfigPtr)pSiS->PciInfo->thisCard)->funcnum; /*SIS_PCI_FUNC(pSiS->PciInfo);*/
+ pSiS->PciTag = ((pciConfigPtr)pSiS->PciInfo->thisCard)->tag; /*SIS_PCI_TAG(pSiS->PciInfo);*/
#ifdef SIS_NEED_MAP_IOP
/********************************************/
@@ -3085,13 +3309,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* IOPortBase, vga support for MIPS and ARM */
/* is unusable. */
/* (In this driver this is solvable because */
- /* we have our own vgaHW routines. TODO) */
+ /* we have our own vgaHW routines. However, */
+ /* we use /dev/port for now instead.) */
/********************************************/
pSiS->IOPAddress = pSiS->IODBase + pSiS->PciInfo->ioBase[2];
if(!SISMapIOPMem(pScrn)) {
SISErrorLog(pScrn, "Could not map I/O port area at 0x%x\n", pSiS->IOPAddress);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_0;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I/O port area mapped to %p, size 128\n", pSiS->IOPBase);
#if defined(__mips__) || defined(__arm32__)
@@ -3102,153 +3326,315 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ /* Set up i/o port access (for non-x86) */
#ifdef SISUSEDEVPORT
if((sisdevport = open("/dev/port", O_RDWR, 0)) == -1) {
SISErrorLog(pScrn, "Failed to open /dev/port for read/write\n");
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_0;
}
pSiS->sisdevportopen = TRUE;
#endif
-#ifdef SIS_PC_PLATFORM
- /* Map 64k VGA window for saving/restoring CGA fonts */
- SiS_MapVGAMem(pScrn);
-#endif
-
- pSiS->pInt = NULL;
-#if !defined(__alpha__)
- if(!pSiS->Primary) {
- /* Soft-boot the card through int10 */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Initializing display adapter through int10\n");
- if(xf86LoadSubModule(pScrn, "int10")) {
- xf86LoaderReqSymLists(int10Symbols, NULL);
- pSiS->pInt = xf86InitInt10(pSiS->pEnt->index);
- } else {
- SISErrorLog(pScrn, "Could not load int10 module\n");
- }
- }
-#endif
-
-#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
- {
- resRange vgamem[] = {
- {ResShrMemBlock,0xA0000,0xAFFFF},
- {ResShrMemBlock,0xB0000,0xB7FFF},
- {ResShrMemBlock,0xB8000,0xBFFFF},
- _END
- };
- xf86SetOperatingState(vgamem, pSiS->pEnt->index, ResUnusedOpr);
- }
-#else
- xf86SetOperatingState(resVgaMem, pSiS->pEnt->index, ResUnusedOpr);
-#endif
-
- /* Operations for which memory access is required */
- pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
- /* Operations for which I/O access is required */
- pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
-
- /* Load ramdac module */
- if(!xf86LoadSubModule(pScrn, "ramdac")) {
- SISErrorLog(pScrn, "Could not load ramdac module\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
- }
-
- xf86LoaderReqSymLists(ramdacSymbols, NULL);
-
- /* Set pScrn->monitor */
- pScrn->monitor = pScrn->confScreen->monitor;
-
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override. DANGEROUS!
+ */
{
- /*
- * Set the Chipset and ChipRev, allowing config file entries to
- * override. DANGEROUS!
- */
-
SymTabRec *myChipsets = SISChipsets;
- if(pSiS->PciInfo->vendor == PCI_VENDOR_XGI)
+ if(pSiS->PciInfo->vendor == PCI_VENDOR_XGI) {
myChipsets = XGIChipsets;
+ }
if(pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) {
+
pScrn->chipset = pSiS->pEnt->device->chipset;
pSiS->Chipset = xf86StringToToken(myChipsets, pScrn->chipset);
- from = X_CONFIG;
+
} else if(pSiS->pEnt->device->chipID >= 0) {
+
pSiS->Chipset = pSiS->pEnt->device->chipID;
pScrn->chipset = (char *)xf86TokenToString(myChipsets, pSiS->Chipset);
- from = X_CONFIG;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
- pSiS->Chipset);
+ pSiS->Chipset);
} else {
- from = X_PROBED;
+
pSiS->Chipset = pSiS->PciInfo->chipType;
pScrn->chipset = (char *)xf86TokenToString(myChipsets, pSiS->Chipset);
+
}
}
if(pSiS->pEnt->device->chipRev >= 0) {
+
pSiS->ChipRev = pSiS->pEnt->device->chipRev;
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
- pSiS->ChipRev);
+ pSiS->ChipRev);
} else {
+
pSiS->ChipRev = pSiS->PciInfo->chipRev;
+
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * SISProbe(), but check it just in case the user has overridden them.
+ */
+ if(pScrn->chipset == NULL) {
+ SISErrorLog(pScrn, "ChipID 0x%04X is not recognised\n", pSiS->Chipset);
+ goto my_error_0;
+ }
+ if(pSiS->Chipset < 0) {
+ SISErrorLog(pScrn, "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ goto my_error_0;
}
pSiS->SiS6326Flags = 0;
- if(pSiS->Chipset == PCI_CHIP_SIS6326) {
- /* Determine SiS6326 revision. According to SiS the differences are:
- * Chip name Chip type TV-Out MPEG II decoder
- * 6326 AGP Rev. G0/H0 no no
- * 6326 DVD Rev. D2 yes yes
- * 6326 Rev. Cx yes yes
- */
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+
+ /* Determine VGA engine generation */
+ switch(pSiS->Chipset) {
+ case PCI_CHIP_SIS300:
+ case PCI_CHIP_SIS540:
+ case PCI_CHIP_SIS630: /* 630 + 730 */
+ pSiS->VGAEngine = SIS_300_VGA;
+ break;
+ case PCI_CHIP_SIS315H:
+ case PCI_CHIP_SIS315:
+ case PCI_CHIP_SIS315PRO:
+ case PCI_CHIP_SIS550:
+ case PCI_CHIP_SIS650: /* 650 + 740 */
+ case PCI_CHIP_SIS330:
+ case PCI_CHIP_SIS660: /* 660, 661, 741, 760, 761, 670(?), 770 */
+ case PCI_CHIP_SIS340:
+ case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG40:
+ pSiS->VGAEngine = SIS_315_VGA;
+ break;
+ case PCI_CHIP_SIS530:
+ pSiS->VGAEngine = SIS_530_VGA;
+ break;
+ case PCI_CHIP_SIS6326:
+ /* Determine SiS6326 revision. According to SiS the differences are:
+ * Chip name Chip type TV-Out MPEG II decoder
+ * 6326 AGP Rev. G0/H0 no no
+ * 6326 DVD Rev. D2 yes yes
+ * 6326 Rev. Cx yes yes
+ */
+ 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/H0)" :
- (((pSiS->ChipRev & 0xf0) == 0x90) ? "(9x)" :
- (((pSiS->ChipRev & 0xf0) == 0xc0) ? "(Cx)" :
- "(unknown)"))))),
+ (((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)) {
- pSiS->SiS6326Flags |= SIS6326_HASTV;
- }
+ if((pSiS->ChipRev != 0x0a) && (pSiS->ChipRev != 0x0b)) {
+ pSiS->SiS6326Flags |= SIS6326_HASTV;
+ }
+ /* fall through */
+ default:
+ pSiS->VGAEngine = SIS_OLD_VGA;
}
- /*
- * This shouldn't happen because such problems should be caught in
- * SISProbe(), but check it just in case the user has overridden them.
+ /* We don't know about the current mode yet */
+ pSiS->OldMode = 0;
+
+ /* Determine whether this is the primary or a secondary
+ * display adapter. And right here the problem starts:
+ * On machines with integrated SiS chipsets, the system BIOS
+ * usually sets VGA_EN on all PCI-to-PCI bridges in the system
+ * (of which there usually are two: PCI and AGP). This and
+ * the fact that any PCI card POSTed by sisfb naturally has
+ * its PCI resources enabled, leads to X assuming that
+ * there are more than one "primary" cards in the system.
+ * In this case, X treats ALL cards as "secondary" -
+ * which by no means is desireable. If sisfb is running,
+ * we can determine which card really is "primary" (in
+ * terms of if it's the one that occupies the A0000 area
+ * etc.) in a better way (Linux 2.6.12 or later). See below.
*/
- if(pScrn->chipset == NULL) {
- SISErrorLog(pScrn, "ChipID 0x%04X is not recognised\n", pSiS->Chipset);
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+ if(!(pSiS->Primary = xf86IsPrimaryPci(pSiS->PciInfo))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ SISMYSERVERNAME " assumes this adapter to be secondary\n");
+ }
+
+ /* Now check if sisfb is running, and if so, retrieve
+ * all possible info from it. This also resets all
+ * sisfb_* entries in pSiS regardless of the chipset.
+ */
+ SiS_CheckKernelFB(pScrn);
+
+ /* Now for that primary/secondary mess: Linux kernel
+ * 2.6.12 and later knows what card is primary, and so
+ * does any recent version of sisfb. XFree86/X.org takes
+ * all adapters as "secondary" if more than one card's
+ * memory and i/o resources are enabled, and more than
+ * one PCI bridge in the system has VGA_EN set at server
+ * start. So, let's start thinking: What is this
+ * primary/secondary classification needed for anyway?
+ * (This list might be incomplete for the entire server
+ * infrastructure, but it's complete as regards the driver's
+ * purposes of primary/secondary classification.)
+ * 1) VGA/console font restoring: Here it's irrelevant
+ * whether more than one card's resources are enabled
+ * at server start or not. Relevant is whether the card
+ * occupies the A0000 area at this time. Assuming (?)
+ * that this does not change during machine up-time,
+ * it suffices to know which device was the boot video
+ * device (as determined by Linux 2.6.12 and later).
+ * Also, this is only relevant if the card is in text
+ * mode; if it's in graphics mode, fonts aren't saved
+ * or restored anyway.
+ * sisfb tells us if that card is considered the boot
+ * video device. The hardware registers tell us if
+ * the card's A0000 address decoding is enabled, and if
+ * the card currently is in text mode. These three bits
+ * of information are enough to decide on whether or not
+ * to save/restore fonts.
+ * 2) POSTing. Same here. Relevant is only whether or not
+ * the card has been POSTed once before. POSTing cards
+ * on every server start is pretty ugly, especially
+ * if a framebuffer driver is already handling it.
+ * SiS/XGI cards POSTed by sisfb can coexist well with other
+ * active adapters. So we trust sisfb's information more
+ * than X's (especially as we only use this information for
+ * console font restoring and eventual POSTing.)
+ * What we still need is a way to find out about all this if
+ * sisfb is not running....
+ */
+ if(!pSiS->Primary && pSiS->sisfbprimary) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "sisfb reports this adapter to be primary. Seems more reliable.\n");
+ pSiS->Primary = TRUE;
+ }
+
+ /* If the card is "secondary" and has not been
+ * POSTed by sisfb, POST it now through int10.
+ * For cards POSTed by sisfb, we definitely don't
+ * want that as it messes up our set up (eg. the
+ * disabled A0000 area).
+ * The int10 module decides on its own if the
+ * card is primary or secondary. Since it uses
+ * the generic technique described above, and since
+ * for "secondary" cards it needs a real PCI BIOS
+ * ROM, and since integrated chips don't have such
+ * a PCI BIOS ROM, int10 will naturally fail to
+ * find/read the BIOS on such machines. Great.
+ * Using the integrated graphics as "secondary"
+ * (which it will be as soon as X finds more than
+ * one card's mem and i/o resources enabled, and more
+ * than one PCI bridge's VGA_EN bit set during server
+ * start) will therefore prevent us from restoring
+ * the mode using the VBE. That means real fun if
+ * the integrated chip is set up to use the video
+ * bridge output for text mode (which is something
+ * the driver doesn't really support since it's done
+ * pretty much differently on every machine.)
+ */
+#if !defined(__alpha__)
+ if(!pSiS->Primary) {
+ if(!pSiS->sisfbcardposted) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initializing adapter through int10\n");
+ if(xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+ pSiS->pInt = xf86InitInt10(pSiS->pEnt->index);
+ } else {
+ SISErrorLog(pScrn, "Failed to load int10 module\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Adapter already initialized by sisfb\n");
+ }
+ }
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+
+ /* Get the address of our relocated IO registers.
+ * These are enabled by the hardware during cold boot, and
+ * by the BIOS. So we can pretty much rely on that these
+ * are enabled.
+ */
+ pSiS->RelIO = (SISIOADDRESS)(pSiS->PciInfo->ioBase[2] + pSiS->IODBase);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Relocated I/O registers at 0x%lX\n",
+ (ULong)pSiS->RelIO);
+
+ /* Unlock extended registers */
+ sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg);
+
+ /* Is a0000 memory address decoding enabled? */
+ pSiS->VGADecodingEnabled = TRUE;
+ switch(pSiS->VGAEngine) {
+ case SIS_OLD_VGA:
+ /* n/a */
+ break;
+ case SIS_530_VGA:
+ inSISIDXREG(SISSR, 0x3d, tempreg);
+ if(tempreg & 0x04) pSiS->VGADecodingEnabled = FALSE;
+ break;
+ case SIS_300_VGA:
+ case SIS_315_VGA:
+ inSISIDXREG(SISSR, 0x20, tempreg);
+ if(tempreg & 0x04) pSiS->VGADecodingEnabled = FALSE;
+ break;
}
- if(pSiS->Chipset < 0) {
- SISErrorLog(pScrn, "Chipset \"%s\" is not recognised\n", pScrn->chipset);
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+
+ if(!pSiS->VGADecodingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Standard VGA (0xA0000) memory address decoding is disabled\n");
+ }
+
+#ifdef SIS_PC_PLATFORM
+ /* Map 64k VGA window for saving/restoring CGA fonts.
+ * For secondary cards or if A0000 address decoding
+ * is disabled, this will map the beginning of the
+ * linear (PCI) video RAM instead.
+ */
+ SiS_MapVGAMem(pScrn);
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+
+ /* Set operating state */
+
+ /* 1. memory */
+ /* [ResUnusedOpr: Resource decoded by hw, but not used]
+ * [ResDisableOpr: Resource is not decoded by hw]
+ * So, if a0000 memory decoding is disabled, one could
+ * argue that we may say so, too. Hm. Quite likely that
+ * the VBE (via int10) will eventually enable it. So we
+ * cowardly say unused instead.
+ */
+ xf86SetOperatingState(resVgaMem, pSiS->pEnt->index, ResUnusedOpr);
+
+ /* 2. i/o */
+ /* Although we only use the relocated i/o ports, the hardware
+ * also decodes the standard VGA port range. This could in
+ * theory be disabled, but I don't dare to do this; in case of
+ * a server crash, the card would be entirely dead. Also, this
+ * would prevent int10 and the VBE from working at all. Generic
+ * access control through the PCI configuration registers does
+ * nicely anyway.
+ */
+ xf86SetOperatingState(resVgaIo, pSiS->pEnt->index, ResUnusedOpr);
+
+ /* Operations for which memory access is required */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* Operations for which I/O access is required */
+ pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* Load ramdac module */
+ if(!xf86LoadSubModule(pScrn, "ramdac")) {
+ SISErrorLog(pScrn, "Could not load ramdac module\n");
+ goto my_error_1;
}
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
/* Reset some entries */
pSiS->SiSFastVidCopy = SiSVidCopyGetDefault();
pSiS->SiSFastMemCopy = SiSVidCopyGetDefault();
@@ -3269,7 +3655,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Always do a ValidMode() inside Switchmode() */
pSiS->skipswitchcheck = FALSE;
- /* Determine chipset and VGA engine type */
+ /* Determine chipset and its capabilities in detail */
pSiS->ChipFlags = 0;
pSiS->SiS_SD_Flags = pSiS->SiS_SD2_Flags = 0;
pSiS->HWCursorMBufNum = pSiS->HWCursorCBufNum = 0;
@@ -3280,16 +3666,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
switch(pSiS->Chipset) {
case PCI_CHIP_SIS530:
pSiS->ChipType = SIS_530;
- pSiS->VGAEngine = SIS_530_VGA;
break;
case PCI_CHIP_SIS300:
pSiS->ChipType = SIS_300;
- pSiS->VGAEngine = SIS_300_VGA;
pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES;
break;
case PCI_CHIP_SIS540:
pSiS->ChipType = SIS_540;
- pSiS->VGAEngine = SIS_300_VGA;
pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES;
break;
case PCI_CHIP_SIS630: /* 630 + 730 */
@@ -3297,12 +3680,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(pciReadLong(0x00000000, 0x00) == 0x07301039) {
pSiS->ChipType = SIS_730;
}
- pSiS->VGAEngine = SIS_300_VGA;
pSiS->SiS_SD_Flags |= SiS_SD_IS300SERIES;
break;
case PCI_CHIP_SIS315H:
pSiS->ChipType = SIS_315H;
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->ChipFlags |= (SiSCF_315Core | SiSCF_MMIOPalette);
pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
@@ -3313,7 +3694,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->Chipset = PCI_CHIP_SIS315H;
pSiS->ChipType = SIS_315;
pSiS->ChipFlags |= (SiSCF_315Core | SiSCF_MMIOPalette);
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
pSiS->myCR63 = 0x63;
@@ -3323,7 +3703,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->Chipset = PCI_CHIP_SIS315H;
pSiS->ChipType = SIS_315PRO;
pSiS->ChipFlags |= (SiSCF_315Core | SiSCF_MMIOPalette);
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
pSiS->myCR63 = 0x63;
@@ -3331,7 +3710,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_SIS550:
pSiS->ChipType = SIS_550;
pSiS->ChipFlags |= (SiSCF_Integrated | SiSCF_MMIOPalette);
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
pSiS->myCR63 = 0x63;
@@ -3341,7 +3719,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(pciReadLong(0x00000000, 0x00) == 0x07401039) {
pSiS->ChipType = SIS_740;
}
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->ChipFlags |= (SiSCF_Integrated | SiSCF_Real256ECore | SiSCF_MMIOPalette);
pSiS->SiS_SD_Flags |= SiS_SD_IS315SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
@@ -3349,7 +3726,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
break;
case PCI_CHIP_SIS330:
pSiS->ChipType = SIS_330;
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->ChipFlags |= (SiSCF_XabreCore | SiSCF_MMIOPalette);
pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
@@ -3397,9 +3773,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
* 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?)
- * !!! BUT WE DO NOT HAVE RelIO AT THIS POINT YET !!!
*/
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->ChipFlags |= (SiSCF_Integrated | SiSCF_MMIOPalette);
pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
@@ -3409,7 +3783,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
break;
case PCI_CHIP_SIS340:
pSiS->ChipType = SIS_340;
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->ChipFlags |= (SiSCF_XabreCore | SiSCF_MMIOPalette);
pSiS->SiS_SD_Flags |= SiS_SD_IS340SERIES;
pSiS->SiS_SD2_Flags |= SiS_SD2_SUPPORTXVHUESAT;
@@ -3418,7 +3791,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
break;
case PCI_CHIP_XGIXG20:
pSiS->ChipType = XGI_20;
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->ChipFlags |= (SiSCF_XabreCore | SiSCF_MMIOPalette | SiSCF_IsXGI);
pSiS->SiS_SD2_Flags |= (SiS_SD2_NOOVERLAY | SiS_SD2_ISXGI);
pSiS->myCR63 = 0x53;
@@ -3426,7 +3798,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
break;
case PCI_CHIP_XGIXG40:
pSiS->ChipType = XGI_40;
- pSiS->VGAEngine = SIS_315_VGA;
pSiS->ChipFlags |= (SiSCF_XabreCore | SiSCF_MMIOPalette | SiSCF_IsXGI);
pSiS->SiS_SD2_Flags |= (SiS_SD2_SUPPORTXVHUESAT | SiS_SD2_ISXGI);
pSiS->myCR63 = 0x53;
@@ -3435,222 +3806,11 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
break;
default:
pSiS->ChipType = SIS_OLD;
- pSiS->VGAEngine = SIS_OLD_VGA;
break;
}
- /* Now check if sisfb is loaded. Since sisfb only supports
- * the 300 and 315/330 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).
- * Under a 2.4 kernel, that only works if sisfb is completely
- * running, ie with a video mode because the fbdev will not be
- * installed otherwise. Under 2.6 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 = 0xff;
- pSiS->sisfbpdca = 0xff;
- pSiS->sisfblcda = 0xff;
- pSiS->sisfbscalelcd = -1;
- pSiS->sisfbspecialtiming = CUT_NONE;
- pSiS->sisfb_haveemi = FALSE;
- pSiS->OldMode = 0;
- pSiS->sisfbfound = FALSE;
- pSiS->sisfb_tvposvalid = FALSE;
- pSiS->sisfbdevname[0] = 0;
- pSiS->sisfb_havelock = FALSE;
- pSiS->sisfbHaveNewHeapDef = FALSE;
- pSiS->sisfbHeapSize = 0;
- pSiS->sisfbVideoOffset = 0;
- pSiS->sisfbxSTN = FALSE;
-
- if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) {
-
- int fd, i;
- CARD32 sisfbinfosize = 0, sisfbversion;
- sisfb_info *mysisfbinfo;
- char name[16];
-
- i=0;
- do {
-
- if(i <= 7) {
- sprintf(name, "/dev/fb%1d", i);
- } else {
- sprintf(name, "/dev/fb/%1d", i-8);
- }
-
- if((fd = open(name, 'r')) != -1) {
-
- Bool gotit = FALSE;
-
- if(!ioctl(fd, SISFB_GET_INFO_SIZE, &sisfbinfosize)) {
- if((mysisfbinfo = xalloc(sisfbinfosize))) {
- if(!ioctl(fd, (SISFB_GET_INFO | (sisfbinfosize << 16)), mysisfbinfo)) {
- gotit = TRUE;
- } else {
- xfree(mysisfbinfo);
- mysisfbinfo = NULL;
- }
- }
- } else {
- if((mysisfbinfo = xalloc(sizeof(*mysisfbinfo)+16))) {
- if(!ioctl(fd, SISFB_GET_INFO_OLD, mysisfbinfo)) {
- gotit = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Possibly old version of sisfb detected. Please update.\n");
- } else {
- xfree(mysisfbinfo);
- mysisfbinfo = NULL;
- }
- }
- }
-
- if(gotit) {
-
- if(mysisfbinfo->sisfb_id == SISFB_ID) {
-
- 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) ) {
- 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");
- }
- /* Basically, we can't trust the pdc register if sisfb is loaded */
- pSiS->donttrustpdc = TRUE;
- pSiS->sisfbHeapStart = mysisfbinfo->heapstart;
-
- if(sisfbversion >= 0x010714) {
- pSiS->sisfbHeapSize = mysisfbinfo->sisfb_heapsize;
- pSiS->sisfbVideoOffset = mysisfbinfo->sisfb_videooffset;
- pSiS->sisfbHaveNewHeapDef = TRUE;
- pSiS->sisfbFSTN = mysisfbinfo->sisfb_curfstn;
- pSiS->sisfbDSTN = mysisfbinfo->sisfb_curdstn;
- pSiS->sisfbxSTN = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "sisfb: memory heap at %dKB, size %dKB, viewport at %dKB\n",
- (int)pSiS->sisfbHeapStart, (int)pSiS->sisfbHeapSize,
- (int)pSiS->sisfbVideoOffset/1024);
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "sisfb: memory heap at %dKB\n", (int)pSiS->sisfbHeapStart);
- }
- 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: using %s, reserved %dK\n",
- (mysisfbinfo->sisfb_caps & 0x40) ? "SiS300 series Turboqueue" :
- (mysisfbinfo->sisfb_caps & 0x20) ? "SiS315/330/340 series AGP command queue" :
- (mysisfbinfo->sisfb_caps & 0x10) ? "SiS315/330/340 series VRAM command queue" :
- (mysisfbinfo->sisfb_caps & 0x08) ? "SiS315/330/340 series MMIO mode" :
- "no command queue",
- (mysisfbinfo->sisfb_caps & 0x78) ? (int)mysisfbinfo->sisfb_tqlen : 0);
- }
- 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(!pSiS->sisfbpdc) pSiS->sisfbpdc = 0xff;
- }
- }
- 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;
- if(sisfbversion >= 0x010618) {
- pSiS->sisfb_haveemi = mysisfbinfo->sisfb_haveemi ? TRUE : FALSE;
- pSiS->sisfb_haveemilcd = TRUE; /* will match most cases */
- pSiS->sisfb_emi30 = mysisfbinfo->sisfb_emi30;
- pSiS->sisfb_emi31 = mysisfbinfo->sisfb_emi31;
- pSiS->sisfb_emi32 = mysisfbinfo->sisfb_emi32;
- pSiS->sisfb_emi33 = mysisfbinfo->sisfb_emi33;
- }
- if(sisfbversion >= 0x010619) {
- pSiS->sisfb_haveemilcd = mysisfbinfo->sisfb_haveemilcd ? TRUE : FALSE;
- }
- if(sisfbversion >= 0x01061f) {
- pSiS->sisfbpdca = mysisfbinfo->sisfb_lcdpdca;
- } else {
- if(pSiS->sisfbpdc) {
- pSiS->sisfbpdca = (pSiS->sisfbpdc & 0xf0) >> 3;
- pSiS->sisfbpdc = (pSiS->sisfbpdc & 0x0f) << 1;
- } else {
- pSiS->sisfbpdca = pSiS->sisfbpdc = 0xff;
- }
- }
- }
- }
- if(sisfbversion >= 0x010700) {
- pSiS->sisfb_havelock = TRUE;
- if(sisfbversion >= 0x010701) {
- pSiS->sisfb_tvxpos = mysisfbinfo->sisfb_tvxpos;
- pSiS->sisfb_tvypos = mysisfbinfo->sisfb_tvypos;
- pSiS->sisfb_tvposvalid = TRUE;
- }
- }
- }
- }
- xfree(mysisfbinfo);
- mysisfbinfo = NULL;
- }
- close (fd);
- }
- i++;
- } while((i <= 15) && (!pSiS->sisfbfound));
-
- if(pSiS->sisfbfound) {
- strncpy(pSiS->sisfbdevname, name, 15);
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "sisfb not found\n");
- }
- }
-
/*
- * The first thing we should figure out is the depth, bpp, etc.
+ * Now back to real business: Figure out the depth, bpp, etc.
* Set SupportConvert... flags since we use the fb layer which
* supports this conversion. (24to32 seems not implemented though)
* Additionally, determine the size of the HWCursor memory area.
@@ -3745,12 +3905,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(!pSiS->SiS_Pr) {
if(!(pSiS->SiS_Pr = xnfcalloc(sizeof(struct SiS_Private), 1))) {
SISErrorLog(pScrn, "Could not allocate memory for SiS_Pr structure\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->SiS_Pr = pSiS->SiS_Pr;
@@ -3783,15 +3938,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->SiS_Pr->DDCPortMixup = FALSE;
}
- /* Get our relocated IO registers */
- pSiS->RelIO = (SISIOADDRESS)(pSiS->PciInfo->ioBase[2] + pSiS->IODBase);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Relocated I/O registers at 0x%lX\n",
- (ULong)pSiS->RelIO);
- pSiS->SiS_Pr->IOAddress = (SISIOADDRESS)(pSiS->RelIO + 0x30);
-
- /* Initialize SiS Port Reg definitions for externally used
- * init.c/init301.c functions.
+ /* Copy IO address to SiS_Pr and init the structure for
+ * routines inside init.c/init301.c
*/
+ pSiS->SiS_Pr->IOAddress = (SISIOADDRESS)(pSiS->RelIO + 0x30);
SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO + 0x30);
/* The following identifies the old chipsets. This is only
@@ -3807,15 +3957,11 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
case PCI_CHIP_SG86C202:
pSiS->oldChipset = OC_SIS86202; break;
case PCI_CHIP_SG86C205:
- {
- UChar temp;
- sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg);
- inSISIDXREG(SISSR, 0x10, temp);
- if(temp & 0x80) pSiS->oldChipset = OC_SIS6205B;
- else pSiS->oldChipset = (pSiS->ChipRev == 0x11) ?
- OC_SIS6205C : OC_SIS6205A;
- break;
- }
+ inSISIDXREG(SISSR, 0x10, tempreg);
+ if(tempreg & 0x80) pSiS->oldChipset = OC_SIS6205B;
+ else pSiS->oldChipset = (pSiS->ChipRev == 0x11) ?
+ OC_SIS6205C : OC_SIS6205A;
+ break;
case PCI_CHIP_SIS82C204:
pSiS->oldChipset = OC_SIS82204; break;
case 0x6225:
@@ -3840,12 +3986,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
SISErrorLog(pScrn, "xf86SetDepthBpp() error\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
/* Check that the returned depth is one we support */
@@ -3869,9 +4010,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
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;
+ goto my_error_1;
}
xf86PrintDepthBpp(pScrn);
@@ -3881,9 +4020,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
((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;
+ goto my_error_1;
}
/* Get the depth24 pixmap format */
@@ -3901,12 +4038,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(!xf86SetWeight(pScrn, zeros, zeros)) {
SISErrorLog(pScrn, "xf86SetWeight() error\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
} else {
Bool ret = FALSE;
switch(pScrn->depth) {
@@ -3931,12 +4063,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
"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
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
}
}
@@ -3948,24 +4075,14 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(!xf86SetDefaultVisual(pScrn, -1)) {
SISErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
} else {
/* We don't support DirectColor at > 8bpp */
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;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
}
@@ -3974,16 +4091,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if((pSiS->DualHeadMode) && (pScrn->bitsPerPixel <= 8)) {
SISErrorLog(pScrn, "Color depth %d not supported in Dual Head mode.\n",
pScrn->bitsPerPixel);
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
#endif
- /* Unlock registers */
- sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg);
-
/* Read BIOS for 300 and 315/330/340 series customization */
pSiS->SiS_Pr->VirtualRomBase = NULL;
pSiS->BIOS = NULL;
@@ -3991,8 +4102,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->ROM661New = FALSE;
pSiS->HaveXGIBIOS = FALSE;
- /* Don't use BIOS image for XGI - different layout. */
-
if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) {
#ifdef SISDUALHEAD
if(pSiSEnt) {
@@ -4039,7 +4148,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
}
if(!found) {
- for(segstart=BIOS_BASE; segstart<0x000f0000; segstart+=0x00001000) {
+ for(segstart = BIOS_BASE; segstart < 0x000f0000; segstart += 0x00001000) {
#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0)
if(xf86ReadBIOS(segstart, 0, pSiS->BIOS, BIOS_SIZE) != BIOS_SIZE) continue;
@@ -4307,6 +4416,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->FbAddress = pSiS->PciInfo->memBase[0] & 0xFFFFFFF0;
from = X_PROBED;
}
+
#ifdef SISDUALHEAD
if(pSiS->DualHeadMode)
xf86DrvMsg(pScrn->scrnIndex, from, "Global linear framebuffer at 0x%lX\n",
@@ -4335,12 +4445,12 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
/* Register the PCI-assigned resources */
if(xf86RegisterResources(pSiS->pEnt->index, NULL, ResExclusive)) {
- SISErrorLog(pScrn, "xf86RegisterResources() found resource conflicts\n");
+ SISErrorLog(pScrn, "PCI resource conflicts detected\n");
#ifdef SISDUALHEAD
if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
SISFreeRec(pScrn);
return FALSE;
}
@@ -5472,12 +5582,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
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;
+ goto my_error_1;
}
#endif
#ifdef SISMERGED
@@ -5524,12 +5629,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
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;
+ goto my_error_1;
}
#endif
#ifdef SISMERGED
@@ -6371,13 +6471,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(i == -1) {
SISErrorLog(pScrn, "xf86ValidateModes() error\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
/* Check the virtual screen against the available memory */
@@ -6388,14 +6482,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
SISErrorLog(pScrn,
"Virtual screen too big for memory; %ldK needed, %ldK available\n",
memreq/1024, pSiS->maxxfbmem/1024);
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- pSiS->pInt = NULL;
- sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
}
@@ -6448,13 +6535,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(i == 0 || pScrn->modes == NULL) {
SISErrorLog(pScrn, "No valid modes found - check VertRefresh/HorizSync\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
@@ -6744,24 +6825,12 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
case 32:
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;
+ goto my_error_1;
}
break;
default:
SISErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n", pScrn->bitsPerPixel);
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
xf86LoaderReqSymLists(fbSymbols, NULL);
@@ -6783,13 +6852,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
#endif
if(modName && (!xf86LoadSubModule(pScrn, modName))) {
SISErrorLog(pScrn, "Could not load %s module\n", modName);
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- sisRestoreExtRegisterLock(pSiS, srlockReg, crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
if(symNames) {
xf86LoaderReqSymLists(symNames, NULL);
@@ -6801,13 +6864,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
if(pSiS->ShadowFB) {
if(!xf86LoadSubModule(pScrn, "shadowfb")) {
SISErrorLog(pScrn, "Could not load shadowfb module\n");
-#ifdef SISDUALHEAD
- if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
-#endif
- if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
- sisRestoreExtRegisterLock(pSiS,srlockReg,crlockReg);
- SISFreeRec(pScrn);
- return FALSE;
+ goto my_error_1;
}
xf86LoaderReqSymLists(shadowSymbols, NULL);
}
@@ -6896,6 +6953,19 @@ SISPreInit(ScrnInfoPtr pScrn, int flags)
pSiS->VBFlagsInit = pSiS->VBFlags;
return TRUE;
+
+ /* ---- */
+
+my_error_1:
+ sisRestoreExtRegisterLock(pSiS, srlockReg, crlockReg);
+my_error_0:
+#ifdef SISDUALHEAD
+ if(pSiSEnt) pSiSEnt->ErrorAfterFirst = TRUE;
+#endif
+ if(pSiS->pInt) xf86FreeInt10(pSiS->pInt);
+ pSiS->pInt = NULL;
+ SISFreeRec(pScrn);
+ return FALSE;
}
/*
@@ -7171,7 +7241,7 @@ SISSave(ScrnInfoPtr pScrn)
SiSVGASave(pScrn, sisReg, flags);
}
- sisSaveUnlockExtRegisterLock(pSiS,&sisReg->sisRegs3C4[0x05],&sisReg->sisRegs3D4[0x80]);
+ sisSaveUnlockExtRegisterLock(pSiS, &sisReg->sisRegs3C4[0x05], &sisReg->sisRegs3D4[0x80]);
(*pSiS->SiSSave)(pScrn, sisReg);
@@ -7288,7 +7358,7 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
SISErrorLog(pScrn, "SiSSetVESAMode() failed\n");
return FALSE;
}
- sisSaveUnlockExtRegisterLock(pSiS,NULL,NULL);
+ 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);
@@ -7538,7 +7608,7 @@ SISSpecialRestore(ScrnInfoPtr pScrn)
if(temp > 0x13) return;
#ifdef UNLOCK_ALWAYS
- sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
SiS_UnLockCRT2(pSiS->SiS_Pr);
@@ -7658,7 +7728,7 @@ SISRestore(ScrnInfoPtr pScrn)
#endif
#ifdef UNLOCK_ALWAYS
- sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
/* We must not disable the sequencer if the bridge is in SlaveMode! */
@@ -7872,7 +7942,7 @@ SISRestore(ScrnInfoPtr pScrn)
SiSVGAProtect(pScrn, TRUE);
#ifdef UNLOCK_ALWAYS
- sisSaveUnlockExtRegisterLock(pSiS, NULL,NULL);
+ sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL);
#endif
(*pSiS->SiSRestore)(pScrn, sisReg);
@@ -13502,26 +13572,33 @@ sisSaveUnlockExtRegisterLock(SISPtr pSiS, UChar *reg1, UChar *reg2)
{
register UChar val;
ULong mylockcalls;
+#ifdef TWDEBUG
+ UChar val1, val2;
+ int i;
+#endif
pSiS->lockcalls++;
mylockcalls = pSiS->lockcalls;
/* check if already unlocked */
inSISIDXREG(SISSR, 0x05, val);
+
if(val != 0xa1) {
+
/* save State */
if(reg1) *reg1 = val;
+
/* unlock */
outSISIDXREG(SISSR, 0x05, 0x86);
+
+ /* Now check again */
inSISIDXREG(SISSR, 0x05, val);
+
if(val != 0xA1) {
-#ifdef TWDEBUG
- UChar val1, val2;
- int i;
-#endif
- SISErrorLog(pSiS->pScrn,
- "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
- (void *)pSiS, (ULong)pSiS->RelIO, val, mylockcalls);
+
+ xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+ "Failed to unlock SR registers at relocated i/o ports\n");
+
#ifdef TWDEBUG
for(i = 0; i <= 0x3f; i++) {
inSISIDXREG(SISSR, i, val1);
@@ -13531,12 +13608,28 @@ sisSaveUnlockExtRegisterLock(SISPtr pSiS, UChar *reg1, UChar *reg2)
i, val1, val2, mylockcalls);
}
#endif
- if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
- /* Emergency measure: unlock at 0x3c4, and try to enable Relocated IO ports */
- outSISIDXREG(0x3c4,0x05,0x86);
- andSISIDXREG(0x3c4,0x33,~0x20);
- outSISIDXREG(SISSR, 0x05, 0x86);
+
+ /* Emergency measure: unlock at 0x3c4, and try to enable relocated IO ports */
+ switch(pSiS->VGAEngine) {
+ case SIS_OLD_VGA:
+ case SIS_530_VGA:
+ outSISIDXREG(0x3c4, 0x05, 0x86);
+ andSISIDXREG(0x3c4, 0x33, ~0x20);
+ break;
+ case SIS_300_VGA:
+ case SIS_315_VGA:
+ outSISIDXREG(0x3c4, 0x05, 0x86);
+ orSISIDXREG(0x3c4, 0x20, 0x20);
+ break;
}
+ outSISIDXREG(SISSR, 0x05, 0x86);
+ inSISIDXREG(SISSR, 0x05, val);
+ if(val != 0xa1) {
+ SISErrorLog(pSiS->pScrn,
+ "Failed to unlock SR registers (%p, %lx, 0x%02x; %ld)\n",
+ (void *)pSiS, (ULong)pSiS->RelIO, val, mylockcalls);
+ /* Now await doom... */
+ }
}
}
if((pSiS->VGAEngine == SIS_OLD_VGA) || (pSiS->VGAEngine == SIS_530_VGA)) {
diff --git a/src/sis_driver.h b/src/sis_driver.h
index 6d05413..9a5fb6e 100644
--- a/src/sis_driver.h
+++ b/src/sis_driver.h
@@ -1353,7 +1353,13 @@ struct _SISFB_INFO {
CARD16 sisfb_pci_vendor; /* PCI vendor (SiS or XGI) */
- CARD8 reserved[190]; /* for future use */
+ CARD32 sisfb_vbflags2;
+
+ CARD8 sisfb_can_post; /* sisfb can POST this card */
+ CARD8 sisfb_card_posted; /* card is POSTED */
+ CARD8 sisfb_was_boot_device; /* This card was the boot video device (ie is primary) */
+
+ CARD8 reserved[183]; /* for future use */
};
/* Mandatory functions */
diff --git a/src/sis_utility.c b/src/sis_utility.c
index c44c585..29e3e57 100644
--- a/src/sis_utility.c
+++ b/src/sis_utility.c
@@ -885,9 +885,9 @@ SiSHandleSiSDirectCommand(xSiSCtrlCommandReply *sdcbuf)
}
sdcbuf->sdc_result[0] = pSiS->IsAGPCard ? SDC_BUS_TYPE_AGP : SDC_BUS_TYPE_PCI;
if(pSiS->IsPCIExpress) sdcbuf->sdc_result[0] = SDC_BUS_TYPE_PCIE;
- sdcbuf->sdc_result[1] = pSiS->PciInfo->bus;
- sdcbuf->sdc_result[2] = pSiS->PciInfo->device;
- sdcbuf->sdc_result[3] = pSiS->PciInfo->func;
+ sdcbuf->sdc_result[1] = pSiS->PciBus;
+ sdcbuf->sdc_result[2] = pSiS->PciDevice;
+ sdcbuf->sdc_result[3] = pSiS->PciFunc;
sdcbuf->sdc_result[4] = pSiS->ROM661New ? 1 : (pSiS->HaveXGIBIOS ? 2 : 0),
sdcbuf->sdc_result[5] = pSiS->ChipFlags;
sdcbuf->sdc_result[6] = pSiS->ChipType;
@@ -1848,6 +1848,10 @@ SiSCtrlExtInit(ScrnInfoPtr pScrn)
xSiSCtrlScreenTable *myctrl;
unsigned int version, revision;
+ if((pSiS->VGAEngine != SIS_300_VGA) &&
+ (pSiS->VGAEngine != SIS_315_VGA))
+ return;
+
pSiS->SCLogQuiet = FALSE;
if(!(myext = CheckExtension(SISCTRL_PROTOCOL_NAME))) {
@@ -2258,7 +2262,7 @@ SISGetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
} else if(attribute == pSiS->xv_GHI) {
*value = (pSiS->ChipFlags & 0xffff) | (pSiS->ChipType << 16) | (pSiS->ChipRev << 24);
} else if(attribute == pSiS->xv_GBI) {
- *value = (pSiS->PciInfo->bus << 16) | (pSiS->PciInfo->device << 8) | pSiS->PciInfo->func;
+ *value = (pSiS->PciBus << 16) | (pSiS->PciDevice << 8) | pSiS->PciFunc;
} else if(attribute == pSiS->xv_QVV) {
*value = SIS_VBFlagsVersion;
} else if(attribute == pSiS->xv_QDD) {