diff options
-rw-r--r-- | src/init.c | 112 | ||||
-rw-r--r-- | src/init.h | 1 | ||||
-rw-r--r-- | src/init301.c | 90 | ||||
-rw-r--r-- | src/init301.h | 2 | ||||
-rw-r--r-- | src/initdef.h | 1 | ||||
-rw-r--r-- | src/sis.h | 6 | ||||
-rw-r--r-- | src/sis_vb.c | 7 | ||||
-rw-r--r-- | src/sis_vga.c | 83 | ||||
-rw-r--r-- | src/vstruct.h | 3 |
9 files changed, 222 insertions, 83 deletions
@@ -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; @@ -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) @@ -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]; |