summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.c112
-rw-r--r--src/init.h1
-rw-r--r--src/init301.c90
-rw-r--r--src/init301.h2
-rw-r--r--src/initdef.h1
-rw-r--r--src/sis.h6
-rw-r--r--src/sis_vb.c7
-rw-r--r--src/sis_vga.c83
-rw-r--r--src/vstruct.h3
9 files changed, 222 insertions, 83 deletions
diff --git a/src/init.c b/src/init.c
index ce8b771..ed097e9 100644
--- a/src/init.c
+++ b/src/init.c
@@ -1588,14 +1588,21 @@ SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
/* 315/330 series stick to the standard(s) */
SiS_Pr->SiS_UseROM = TRUE;
if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
+ SiS_Pr->SiS_EMIOffset = 14;
+ SiS_Pr->SiS661LCD2TableSize = 36;
/* Find out about LCD data table entry size */
if((romptr = SISGETROMW(0x0102))) {
if(ROMAddr[romptr + (32 * 16)] == 0xff)
SiS_Pr->SiS661LCD2TableSize = 32;
else if(ROMAddr[romptr + (34 * 16)] == 0xff)
SiS_Pr->SiS661LCD2TableSize = 34;
- else if(ROMAddr[romptr + (36 * 16)] == 0xff)
- SiS_Pr->SiS661LCD2TableSize = 36; /* 0.94 final */
+ else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94 */
+ SiS_Pr->SiS661LCD2TableSize = 36;
+ else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */
+ (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00+ */
+ SiS_Pr->SiS661LCD2TableSize = 38;
+ SiS_Pr->SiS_EMIOffset = 16;
+ }
}
}
}
@@ -1680,7 +1687,7 @@ SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
void
SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- USHORT flag=0, rev=0, nolcd=0;
+ USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27;
SiS_Pr->SiS_VBType = 0;
@@ -1716,6 +1723,20 @@ SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
SiS_Pr->SiS_VBType = VB_SIS301LV;
}
}
+ if(SiS_Pr->SiS_VBType & (VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
+ p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
+ p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
+ p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
+ if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
+ SiS_Pr->SiS_VBType |= VB_UMC;
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
+ }
}
/*********************************************/
@@ -4286,25 +4307,59 @@ SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
#endif
}
-/* ================ XFREE86 ================= */
+void
+SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c)
+{
+ int out_n, out_dn, out_div, out_sbit, out_scale;
+ unsigned int vclk[5];
+
+#define Midx 0
+#define Nidx 1
+#define VLDidx 2
+#define Pidx 3
+#define PSNidx 4
+
+ if(SiS_compute_vclk(clock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
+ (*p2b) = (out_div == 2) ? 0x80 : 0x00;
+ (*p2b) |= ((out_n - 1) & 0x7f);
+ (*p2c) = (out_dn - 1) & 0x1f;
+ (*p2c) |= (((out_scale - 1) & 3) << 5);
+ (*p2c) |= ((out_sbit & 0x01) << 7);
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+ clock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif
+ } else {
+ SiSCalcClock(pScrn, clock, 2, vclk);
+ (*p2b) = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
+ (*p2b) |= (vclk[Midx] - 1) & 0x7f;
+ (*p2c) = (vclk[Nidx] - 1) & 0x1f;
+ if(vclk[Pidx] <= 4) {
+ /* postscale 1,2,3,4 */
+ (*p2c) |= ((vclk[Pidx] - 1) & 3) << 5;
+ } else {
+ /* postscale 6,8 */
+ (*p2c) |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
+ (*p2c) |= 0x80;
+ }
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
+ clock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
+#endif
+ }
+}
+
+/* ================ XFREE86/X.ORG ================= */
/* Helper functions */
#ifdef LINUX_XF86
-
+
USHORT
SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
{
SISPtr pSiS = SISPTR(pScrn);
- int out_n, out_dn, out_div, out_sbit, out_scale;
int depth = pSiS->CurrentLayout.bitsPerPixel;
- unsigned int vclk[5];
-
-#define Midx 0
-#define Nidx 1
-#define VLDidx 2
-#define Pidx 3
-#define PSNidx 4
pSiS->SiS_Pr->CModeFlag = 0;
@@ -4340,35 +4395,8 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
-
- if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
- pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
- pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
- pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
- pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
- pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
- pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
-#endif
- } else {
- SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
- pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
- pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
- pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
- if(vclk[Pidx] <= 4) {
- /* postscale 1,2,3,4 */
- pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
- } else {
- /* postscale 6,8 */
- pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
- pSiS->SiS_Pr->CSR2C |= 0x80;
- }
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
- pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
-#endif
- }
+
+ SiS_MakeClockRegs(pScrn, pSiS->SiS_Pr->CDClock, &pSiS->SiS_Pr->CSR2B, &pSiS->SiS_Pr->CSR2C);
pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
diff --git a/src/init.h b/src/init.h
index 3b46e04..a968fc3 100644
--- a/src/init.h
+++ b/src/init.h
@@ -2431,6 +2431,7 @@ BOOLEAN SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO);
USHORT SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy);
+void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
#else
BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo);
#endif
diff --git a/src/init301.c b/src/init301.c
index 74b14ea..4dba157 100644
--- a/src/init301.c
+++ b/src/init301.c
@@ -1742,6 +1742,19 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
+ if(SiS_Pr->CP_PrefClock) {
+ int idx;
+ SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
+ SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
+ if(HwInfo->jChipType < SIS_315H) idx = VCLK_CUSTOM_300;
+ else idx = VCLK_CUSTOM_315;
+ SiS_Pr->SiS_VCLKData[idx].CLOCK =
+ SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
+ SiS_Pr->SiS_VCLKData[idx].SR2B =
+ SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
+ SiS_Pr->SiS_VCLKData[idx].SR2C =
+ SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
+ }
}
break;
case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
@@ -1760,6 +1773,8 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(!(SiS_Pr->UsePanelScaler)) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
#ifdef SIS315H
if(HwInfo->jChipType >= SIS_661) {
@@ -1827,9 +1842,6 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
/* No idea about the timing and zoom factors */
SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
break;
- case Panel_1280x960:
- SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
- break;
case Panel_1280x1024:
if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
@@ -1899,6 +1911,12 @@ SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
+ SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
+ if(!SiS_Pr->CP_PrefClock) {
+ SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ }
}
if(SiS_Pr->UseCustomMode) {
@@ -2043,6 +2061,9 @@ SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
if(HwInfo->jChipType < SIS_315H) {
VCLKIndex = SiS_Pr->PanelVCLKIdx300;
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ VCLKIndex = VCLKIndexGEN;
+ }
} else {
VCLKIndex = SiS_Pr->PanelVCLKIdx315;
if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
@@ -4288,9 +4309,9 @@ SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
if(romptr) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
SiS_Pr->EMI_30 = 0;
- SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
- SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
- SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
+ SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
+ SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
+ SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
/* emidelay = SISGETROMW((romptr + 0x22)); */
SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
@@ -9569,6 +9590,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
SiS_Pr->CP_PreferredIndex = -1;
+ SiS_Pr->CP_PrefClock = 0;
if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
if(pSiS->VBFlags & VB_30xBDH) return 0;
@@ -9865,6 +9887,8 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
SiS_Pr->CP_PreferredIndex = i;
+ SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
+ SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
}
/* Extract the sync polarisation information. This only works
@@ -9888,7 +9912,9 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
/* Maximum pixclock from Monitor Range Limits */
if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) {
- SiS_Pr->CP_MaxClock = buffer[base+9] * 10 * 1000;
+ int maxclk = buffer[base+9] * 10;
+ /* More than 170 is not supported anyway */
+ if(maxclk <= 170) SiS_Pr->CP_MaxClock = maxclk * 1000;
}
}
@@ -10131,6 +10157,8 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
SiS_Pr->CP_PreferredIndex = i;
+ SiS_MakeClockRegs(pSiS->pScrn, SiS_Pr->CP_Clock[i], &SiS_Pr->CP_PrefSR2B, &SiS_Pr->CP_PrefSR2C);
+ SiS_Pr->CP_PrefClock = (SiS_Pr->CP_Clock[i] / 1000) + 1;
if(!havesync) {
cr37 |= ((((buffer[index + 17] & 0x06) ^ 0x06) << 5) | 0x20);
havesync = TRUE;
@@ -11152,13 +11180,14 @@ static void
SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
USHORT ModeIdIndex, USHORT RTI)
{
- USHORT delay = 0, romptr = 0, index;
+ USHORT delay = 0, romptr = 0, index, lcdpdcindex;
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
return;
/* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
+ /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
if(SiS_Pr->SiS_ROMNew) {
if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
@@ -11176,7 +11205,7 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
index++;
}
- romptr = SISGETROMW(0x104); /* 0x4ae */
+ romptr = SISGETROMW(0x104);
delay = ROMAddr[romptr + index];
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
@@ -11202,10 +11231,12 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
index = GetOEMTVPtr661(SiS_Pr);
if(SiS_Pr->SiS_ROMNew) {
- romptr = SISGETROMW(0x106); /* 0x4ba */
+ romptr = SISGETROMW(0x106);
+ if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
delay = ROMAddr[romptr + index];
} else {
delay = 0x04;
+ if(index > 3) delay = 0;
}
} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
@@ -11215,22 +11246,39 @@ SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
+ lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
+
/* For LV, the BIOS must know about the correct value */
- delay = ROMAddr[romptr + 0x0d]; /* LCD */
- delay |= (ROMAddr[romptr + 0x0c] << 8); /* LCDA */
+ delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */
+ delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */
} else {
- /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
+ /* TMDS: Set our own, since BIOS has no idea */
+ /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
- delay = 0x0404;
- } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
- delay = 0x0404;
- } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
- delay = 0x1004;
- } else
- delay = 0x0000;
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_1024x768: delay = 0x0008; break;
+ case Panel_1280x720: delay = 0x0004; break;
+ case Panel_1280x768: delay = 0x0004; break;
+ case Panel_1280x800: delay = 0x0004; break;
+ case Panel_1280x1024: delay = 0x1e04; break;
+ case Panel_1400x1050: delay = 0x0004; break;
+ case Panel_1600x1200: delay = 0x0400; break;
+ case Panel_1680x1050: delay = 0x0e04; break;
+ default:
+ if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
+ delay = 0x0008;
+ } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
+ delay = 0x1e04;
+ } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
+ delay = 0x0004;
+ } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
+ delay = 0x0400;
+ } else
+ delay = 0x0e04;
+ break;
+ }
}
/* Override by detected or user-set values */
diff --git a/src/init301.h b/src/init301.h
index bd42313..07de3db 100644
--- a/src/init301.h
+++ b/src/init301.h
@@ -411,6 +411,8 @@ extern void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO,USHORT ModeNo,
extern void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
+extern void SiS_MakeClockRegs(ScrnInfoPtr pScrn, int clock, UCHAR *p2b, UCHAR *p2c);
+
#ifdef LINUX_XF86
extern int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy);
#endif
diff --git a/src/initdef.h b/src/initdef.h
index 0db2b00..837f834 100644
--- a/src/initdef.h
+++ b/src/initdef.h
@@ -80,6 +80,7 @@
#define VB_SIS302LV 0x0010
#define VB_SIS302ELV 0x0020
#define VB_SIS301C 0x0040
+#define VB_UMC 0x4000
#define VB_NoLCD 0x8000
#define VB_SIS301BLV302BLV (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
#define VB_SIS301B302B (VB_SIS301B|VB_SIS301C|VB_SIS302B)
diff --git a/src/sis.h b/src/sis.h
index ca34139..8c007c6 100644
--- a/src/sis.h
+++ b/src/sis.h
@@ -40,7 +40,7 @@
#define SISDRIVERVERSIONYEAR 4
#define SISDRIVERVERSIONMONTH 8
-#define SISDRIVERVERSIONDAY 5
+#define SISDRIVERVERSIONDAY 9
#define SISDRIVERREVISION 1
#define SISDRIVERIVERSION (SISDRIVERVERSIONYEAR << 16) | \
@@ -273,6 +273,9 @@
#define VB_DISPMODE_DUAL DUALVIEW_MODE /* alias */
#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
+/* pSiS->VBFlags2 (static stuff only!) */
+#define VB_SISUMC 0x00000001
+
/* pSiS->VBLCDFlags */
#define VB_LCD_320x480 0x00000001 /* DSTN/FSTN for 550 */
#define VB_LCD_640x480 0x00000002
@@ -705,6 +708,7 @@ typedef struct {
unsigned char myCR32, myCR36, myCR37, myCR63;
unsigned char newCR32;
unsigned long VBFlags; /* Video bridge configuration */
+ unsigned long VBFlags2; /* Video bridge configuration 2 (static flags only) */
unsigned long VBFlags_backup; /* Backup for SlaveMode-modes */
unsigned long VBLCDFlags; /* Moved LCD panel size bits here */
int ChrontelType; /* CHRONTEL_700x or CHRONTEL_701x */
diff --git a/src/sis_vb.c b/src/sis_vb.c
index aea709e..5bf1c35 100644
--- a/src/sis_vb.c
+++ b/src/sis_vb.c
@@ -747,7 +747,11 @@ SISSense30x(ScrnInfoPtr pScrn, Bool quiet)
(pSiS->Chipset == PCI_CHIP_SIS340)) {
if(pSiS->ROM661New) {
biosflag = 2;
- vga2 = GETROMWORD(0x63); svhs = cvbs = GETROMWORD(0x65);
+ vga2 = GETROMWORD(0x63);
+ if(pSiS->BIOS[0x6f] & 0x01) {
+ if(pSiS->VBFlags2 & VB_SISUMC) vga2 = GETROMWORD(0x4d);
+ }
+ svhs = cvbs = GETROMWORD(0x65);
if(pSiS->BIOS[0x5d] & 0x04) biosflag |= 0x01;
}
} else if(!pSiS->ROM661New) {
@@ -838,6 +842,7 @@ SISSense30x(ScrnInfoPtr pScrn, Bool quiet)
if(pSiS->SenseYPbPr) {
outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10));
SiS_DDC2Delay(pSiS->SiS_Pr, 0x2000);
+ /* New BIOS (2.x) uses vga2 sensing here for all bridges >301LV */
if((result = SISDoSense(pScrn, svhs, 0x0604))) {
if((result = SISDoSense(pScrn, cvbs, 0x0804))) {
if(!quiet) {
diff --git a/src/sis_vga.c b/src/sis_vga.c
index 2fe87b9..8ca9f8f 100644
--- a/src/sis_vga.c
+++ b/src/sis_vga.c
@@ -1005,16 +1005,34 @@ SISSense6326(ScrnInfoPtr pScrn)
}
}
+static BOOLEAN
+SISIsUMC(SISPtr pSiS)
+{
+ USHORT p4_0f, p4_25, p4_27, temp;
+
+ inSISIDXREG(SISPART4, 0x0f, p4_0f);
+ inSISIDXREG(SISPART4, 0x25, p4_25);
+ inSISIDXREG(SISPART4, 0x27, p4_27);
+ andSISIDXREG(SISPART4, 0x0f, 0x7f);
+ orSISIDXREG(SISPART4, 0x25, 0x08);
+ andSISIDXREG(SISPART4, 0x27, 0xfd);
+ inSISIDXREG(SISPART4, 0x26, temp);
+ outSISIDXREG(SISPART4, 0x27, p4_27);
+ outSISIDXREG(SISPART4, 0x25, p4_25);
+ outSISIDXREG(SISPART4, 0x0f, p4_0f);
+ return((temp & 0x08) ? TRUE : FALSE);
+}
+
/* Detect video bridge and set VBFlags accordingly */
void SISVGAPreInit(ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
- int temp,temp1,temp2;
+ int temp,temp1,temp2,sistypeidx;
int upperlimitlvds, lowerlimitlvds;
int upperlimitch, lowerlimitch;
int chronteltype, chrontelidreg, upperlimitvb;
- static const char *detectvb = "Detected %s video bridge (ID %d; Revision 0x%x)\n";
+ static const char *detectvb = "Detected %s (%s) video bridge (ID %d; Rev 0x%x)\n";
#if 0
unsigned char sr17=0;
#endif
@@ -1029,6 +1047,16 @@ void SISVGAPreInit(ScrnInfoPtr pScrn)
"7020",
"(unknown)"
};
+ static const char *SiSVBTypeStr[] = {
+ "301", /* 0 */
+ "301B", /* 1 */
+ "301B-DH", /* 2 */
+ "301LV", /* 3 */
+ "302LV", /* 4 */
+ "301C", /* 5 */
+ "302ELV", /* 6 */
+ "302B" /* 7 */
+ };
switch (pSiS->Chipset) {
case PCI_CHIP_SIS300:
@@ -1057,7 +1085,7 @@ void SISVGAPreInit(ScrnInfoPtr pScrn)
SISSense6326(pScrn);
}
- pSiS->VBFlags = 0; /* reset VBFlags */
+ pSiS->VBFlags = pSiS->VBFlags2 = 0; /* reset VBFlags */
pSiS->SiS_Pr->SiS_UseLCDA = FALSE;
pSiS->SiS_Pr->Backup = FALSE;
@@ -1068,56 +1096,75 @@ void SISVGAPreInit(ScrnInfoPtr pScrn)
inSISIDXREG(SISPART4, 0x00, temp);
temp &= 0x0F;
if(temp == 1) {
+
inSISIDXREG(SISPART4, 0x01, temp1);
temp1 &= 0xff;
+
+ if(temp1 >= 0xC0) {
+ if(SISIsUMC(pSiS)) pSiS->VBFlags2 |= VB_SISUMC;
+ }
+
if(temp1 >= 0xE0) {
inSISIDXREG(SISPART4, 0x39, temp2);
if(temp2 == 0xff) {
pSiS->VBFlags |= VB_302LV;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS302LV", 1, temp1);
+ sistypeidx = 4;
} else {
- pSiS->VBFlags |= VB_301C; /* VB_302ELV; */
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301C", 1, temp1);
+ pSiS->VBFlags |= VB_301C; /* VB_302ELV; */
+ sistypeidx = 5; /* 6; */
}
} else if(temp1 >= 0xD0) {
pSiS->VBFlags |= VB_301LV;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301LV", 1, temp1);
+ sistypeidx = 3;
} else if(temp1 >= 0xC0) {
pSiS->VBFlags |= VB_301C;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301C", 1, temp1);
+ sistypeidx = 5;
} else if(temp1 >= 0xB0) {
- pSiS->VBFlags |= VB_301B;
+ pSiS->VBFlags |= VB_301B;
+ sistypeidx = 1;
inSISIDXREG(SISPART4, 0x23, temp2);
- if(!(temp2 & 0x02)) pSiS->VBFlags |= VB_30xBDH;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb,
- (temp2 & 0x02) ? "SiS301B" : "SiS301B-DH", 1, temp1);
+ if(!(temp2 & 0x02)) {
+ pSiS->VBFlags |= VB_30xBDH;
+ sistypeidx = 2;
+ }
} else {
pSiS->VBFlags |= VB_301;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301", 1, temp1);
+ sistypeidx = 0;
}
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, SiSVBTypeStr[sistypeidx],
+ (pSiS->VBFlags2 & VB_SISUMC) ? "UMC" : "Charter", 1, temp1);
SISSense30x(pScrn, TRUE);
- } else if (temp == 2) {
+ } else if(temp == 2) {
inSISIDXREG(SISPART4, 0x01, temp1);
temp1 &= 0xff;
+
+ if(temp1 >= 0xC0) {
+ if(SISIsUMC(pSiS)) pSiS->VBFlags2 |= VB_SISUMC;
+ }
+
if(temp1 >= 0xE0) {
pSiS->VBFlags |= VB_302LV;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS302LV", 2, temp1);
+ sistypeidx = 4;
} else if(temp1 >= 0xD0) {
pSiS->VBFlags |= VB_301LV;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301LV", 2, temp1);
+ sistypeidx = 3;
} else {
pSiS->VBFlags |= VB_302B;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS302B", 2, temp1);
+ sistypeidx = 7;
}
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, SiSVBTypeStr[sistypeidx],
+ (pSiS->VBFlags2 & VB_SISUMC) ? "UMC" : "Charter", 2, temp1);
SISSense30x(pScrn, FALSE);
} else if (temp == 3) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "unsupported SiS303", temp, 0);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "unsupported SiS303", "unknown", temp, 0);
} else {
diff --git a/src/vstruct.h b/src/vstruct.h
index 6100ddf..08b20ce 100644
--- a/src/vstruct.h
+++ b/src/vstruct.h
@@ -304,6 +304,7 @@ typedef struct _SiS_Private
BOOLEAN HaveEMILCD;
BOOLEAN OverruleEMI;
UCHAR EMI_30,EMI_31,EMI_32,EMI_33;
+ USHORT SiS_EMIOffset;
SHORT PDC, PDCA;
UCHAR SiS_MyCR63;
USHORT SiS_CRT1Mode;
@@ -663,6 +664,8 @@ typedef struct _SiS_Private
BOOLEAN CP_HaveCustomData;
int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
int CP_MaxX, CP_MaxY, CP_MaxClock;
+ UCHAR CP_PrefSR2B, CP_PrefSR2C;
+ USHORT CP_PrefClock;
BOOLEAN CP_Supports64048075;
int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
int CP_HTotal[7], CP_VTotal[7];