diff options
author | Thomas Winischhofer <thomas@winischhofer.net> | 2004-07-07 21:14:45 +0000 |
---|---|---|
committer | Thomas Winischhofer <thomas@winischhofer.net> | 2004-07-07 21:14:45 +0000 |
commit | 4b2c04c9f18eae06919d0096dfa70ac234a6a61a (patch) | |
tree | 73ac6adebb826a1db9e4aa87c9c6d7970d7b49f7 | |
parent | 1d8c6bd12b70f49cbb4944194c14b94d1dc42c05 (diff) |
SiS driver, vacation time edition:
- Overrule bogus HSync/VRefresh ranges for LCD and TV
- Fix for videobridgeless systems
-rw-r--r-- | src/sis.h | 6 | ||||
-rw-r--r-- | src/sis_dac.c | 84 | ||||
-rw-r--r-- | src/sis_driver.c | 52 | ||||
-rw-r--r-- | src/sis_opt.c | 30 | ||||
-rw-r--r-- | src/sis_vb.c | 2 |
5 files changed, 101 insertions, 73 deletions
@@ -39,8 +39,8 @@ #define UNLOCK_ALWAYS #define SISDRIVERVERSIONYEAR 4 -#define SISDRIVERVERSIONMONTH 6 -#define SISDRIVERVERSIONDAY 29 +#define SISDRIVERVERSIONMONTH 7 +#define SISDRIVERVERSIONDAY 1 #define SISDRIVERREVISION 1 #define SISDRIVERIVERSION (SISDRIVERVERSIONYEAR << 16) | \ @@ -480,6 +480,7 @@ typedef struct { unsigned long sisMMIO85C0; unsigned char sis6326tv[0x46]; unsigned long sisRegsPCI50, sisRegsPCIA0; + unsigned char BIOSModeSave; } SISRegRec, *SISRegPtr; typedef struct _sisModeInfoPtr { @@ -1019,6 +1020,7 @@ typedef struct { int maxClone_X1, maxClone_X2, maxClone_Y1, maxClone_Y2; int MergedFBXDPI, MergedFBYDPI; IOADDRESS MyPIOOffset; + Bool OverruleRanges; #ifdef SIS_NEED_MAP_IOP CARD32 IOPAddress; /* I/O port physical address */ unsigned char * IOPBase; /* I/O port linear address */ diff --git a/src/sis_dac.c b/src/sis_dac.c index 5b12cda..f87fe62 100644 --- a/src/sis_dac.c +++ b/src/sis_dac.c @@ -587,14 +587,11 @@ SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #endif /* Save Mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + sisReg->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave); + "BIOS mode ds:449 = 0x%x\n", sisReg->BIOSModeSave); #endif } @@ -742,10 +739,7 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ /* Restore mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); + SiS_GetSetModeID(pScrn,sisReg->BIOSModeSave); } /* Save SiS315 series register contents */ @@ -786,16 +780,16 @@ SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) /* Save video capture registers */ for(i = 0x00; i <= 0x4f; i++) { inSISIDXREG(SISCAP, i, sisReg->sisCapt[i]); -#ifdef TWDEBUG +#ifdef TWDEBUG_VID xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Capt%02X Contents - %02X \n", i,sisReg->sisCapt[i]); #endif } /* Save video playback registers */ - for(i = 0x00; i <= 0x3f; i++) { + for(i = 0x00; i <= 0x3f; i++) { inSISIDXREG(SISVID, i, sisReg->sisVid[i]); -#ifdef TWDEBUG +#ifdef TWDEBUG_VID xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vid%02X Contents - %02X \n", i,sisReg->sisVid[i]); #endif @@ -819,14 +813,11 @@ SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #endif /* Save mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + sisReg->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave); + "BIOS mode ds:449 = 0x%x\n", sisReg->BIOSModeSave); #endif } @@ -858,11 +849,12 @@ SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) * or application is running and which queue mode it * uses. */ - outSISIDXREG(SISSR, 0x27, 0x1F); + andSISIDXREG(SISCR, 0x55, 0x33); outSISIDXREG(SISSR, 0x26, 0x01); + outSISIDXREG(SISSR, 0x27, 0x1F); /* Restore extended CR registers */ - for(i = 0x19; i < 0x5C; i++) { + for(i = 0x19; i < 0x5C; i++) { outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); } if(pSiS->sishw_ext.jChipType < SIS_661) { @@ -871,18 +863,27 @@ SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISCR, pSiS->myCR63, sisReg->sisRegs3D4[pSiS->myCR63]); /* Leave PCI_IO_ENABLE on if accelerators are on (Is this required?) */ - if(sisReg->sisRegs3C4[0x1e] & 0x50) { /*0x40=2D, 0x10=3D*/ + if(sisReg->sisRegs3C4[0x1e] & 0x50) { /* 0x40=2D, 0x10=3D */ sisReg->sisRegs3C4[0x20] |= 0x20; outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); } - - /* Restore extended SR registers */ + if(pSiS->sishw_ext.jChipType >= SIS_661) { sisReg->sisRegs3C4[0x11] &= 0x0f; } + + /* Restore extended SR registers */ for(i = 0x06; i <= 0x3F; i++) { - outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); + if(i == 0x26) { + continue; + } else if(i == 0x27) { + outSISIDXREG(SISSR, 0x27, sisReg->sisRegs3C4[0x27]); + outSISIDXREG(SISSR, 0x26, sisReg->sisRegs3C4[0x26]); + } else { + outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); + } } + /* Restore VCLK and ECLK */ andSISIDXREG(SISSR,0x31,0xcf); if(pSiS->VBFlags & VB_LVDS) { @@ -939,10 +940,7 @@ SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ /* Restore Mode number */ -#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) - if(!(pSiS->UseVESA)) -#endif - SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); + SiS_GetSetModeID(pScrn,sisReg->BIOSModeSave); } static void @@ -1168,7 +1166,7 @@ SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) int i; /* Save Part1 */ - for(i=0; i<0x46; i++) { + for(i=0; i<0x46; i++) { inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -1245,7 +1243,7 @@ SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) } if((!(sisReg->sisRegs3D4[0x30] & 0x03)) && - (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); return; } @@ -1310,11 +1308,11 @@ SiSMclk(SISPtr pSiS) case PCI_CHIP_SIS300: case PCI_CHIP_SIS540: case PCI_CHIP_SIS630: - case PCI_CHIP_SIS550: - case PCI_CHIP_SIS650: case PCI_CHIP_SIS315: case PCI_CHIP_SIS315H: case PCI_CHIP_SIS315PRO: + case PCI_CHIP_SIS550: + case PCI_CHIP_SIS650: case PCI_CHIP_SIS330: case PCI_CHIP_SIS660: case PCI_CHIP_SIS340: @@ -1455,10 +1453,8 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) #ifdef __SUNPRO_C #define const #endif - const float magic300[4] = { 1.2, 1.368421, 2.263158, 1.2}; - const float magic630[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; - const float magic315[4] = { 1.2, 1.368421, 1.368421, 1.2 }; - const float magic550[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; + const float magicDED[4] = { 1.2, 1.368421, 2.263158, 1.2}; + const float magicINT[4] = { 1.441177, 1.441177, 2.588235, 1.441177 }; #ifdef __SUNPRO_C #undef const #endif @@ -1503,39 +1499,39 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) case PCI_CHIP_SIS340: switch(pSiS->Chipset) { case PCI_CHIP_SIS300: - magic = magic300[bus/64]; + magic = magicDED[bus/64]; max = 540000; break; case PCI_CHIP_SIS540: case PCI_CHIP_SIS630: - magic = magic630[bus/64]; + magic = magicINT[bus/64]; max = 540000; break; case PCI_CHIP_SIS315: case PCI_CHIP_SIS315H: case PCI_CHIP_SIS315PRO: case PCI_CHIP_SIS330: - magic = magic315[bus/64]; + magic = magicDED[bus/64]; max = 780000; break; case PCI_CHIP_SIS550: - magic = magic550[bus/64]; + magic = magicINT[bus/64]; max = 620000; break; case PCI_CHIP_SIS650: - magic = magic550[bus/64]; + magic = magicINT[bus/64]; max = 680000; break; case PCI_CHIP_SIS660: if((pSiS->sishw_ext.jChipType >= SIS_660) && (!(pSiS->ChipFlags & SiSCF_760UMA))) { - magic = magic315[bus/64]; + magic = magicDED[bus/64]; } else { - magic = magic550[bus/64]; + magic = magicINT[bus/64]; } max = 800000; case PCI_CHIP_SIS340: - magic = magic315[bus/64]; + magic = magicDED[bus/64]; max = 800000; break; } @@ -1560,7 +1556,7 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) crt2used = 0.0; crt2clock = SiSEstimateCRT2Clock(pScrn, IsForCRT2); if(crt2clock) { - crt2used = crt2clock + 2000; + crt2used = crt2clock + 2000; } DHM = FALSE; GetForCRT1 = FALSE; diff --git a/src/sis_driver.c b/src/sis_driver.c index b7b2100..924ab1c 100644 --- a/src/sis_driver.c +++ b/src/sis_driver.c @@ -2385,8 +2385,8 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) static const char *subshstr = "Substituting missing CRT%d monitor HSync data by DDC data\n"; static const char *subsvstr = "Substituting missing CRT%d monitor VRefresh data by DDC data\n"; #endif - static const char *saneh = "Substituting missing CRT%d monitor HSync range by suitable data\n"; - static const char *sanev = "Substituting missing CRT%d monitor VRefresh range by suitable data\n"; + static const char *saneh = "Correcting bogus or missing CRT%d monitor HSync range\n"; + static const char *sanev = "Correcting bogus or missing CRT%d monitor VRefresh range\n"; #ifdef SISMERGED static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n"; static const char *mergednocrt2 = "No CRT2 output selected or no bridge detected. %s.\n"; @@ -5058,10 +5058,17 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* If there is no HSync or VRefresh data for the monitor, * derive it from DDC data. Done by common layer since * 4.3.99.14. + * Addendum: I overrule the ranges now in any case unless + * it would affect a CRT output device. Hence, for LCD(A) + * and TV, we always get proper ranges. This is entirely + * harmless. However, option "NoOverruleRanges" will + * disable this behavior. + * This should "fix" the - by far - most common configuration + * mistakes. */ - if(pScrn->monitor->nHsync <= 0) { + if((pScrn->monitor->nHsync <= 0) || (pSiS->OverruleRanges)) { #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0) - if(pScrn->monitor->DDC) { + if((pScrn->monitor->nHsync <= 0) && (pScrn->monitor->DDC)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, subshstr, #ifdef SISDUALHEAD pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) : @@ -5070,7 +5077,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) SiSSetSyncRangeFromEdid(pScrn, 1); } #endif - if(pScrn->monitor->nHsync <= 0) { + if((pScrn->monitor->nHsync <= 0) || (pSiS->OverruleRanges)) { if(SiSAllowSyncOverride(pSiS)) { /* Set sane ranges for LCD and TV * (our strict checking will filter out invalid ones anyway) @@ -5087,9 +5094,9 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } } - if(pScrn->monitor->nVrefresh <= 0) { + if((pScrn->monitor->nVrefresh <= 0) || (pSiS->OverruleRanges)) { #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0) - if(pScrn->monitor->DDC) { + if((pScrn->monitor->nVrefresh <= 0) && (pScrn->monitor->DDC)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, subsvstr, #ifdef SISDUALHEAD pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) : @@ -5098,7 +5105,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) SiSSetSyncRangeFromEdid(pScrn, 0); } #endif - if(pScrn->monitor->nVrefresh <= 0) { + if((pScrn->monitor->nVrefresh <= 0) || (pSiS->OverruleRanges)) { if(SiSAllowSyncOverride(pSiS)) { /* Set sane ranges for LCD and TV */ pScrn->monitor->nVrefresh = 1; @@ -5116,14 +5123,14 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) #ifdef SISMERGED if(pSiS->MergedFB) { - if(pSiS->CRT2pScrn->monitor->nHsync <= 0) { + if((pSiS->CRT2pScrn->monitor->nHsync <= 0) || (pSiS->OverruleRanges)) { #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0) - if(pSiS->CRT2pScrn->monitor->DDC) { + if((pSiS->CRT2pScrn->monitor->nHsync <= 0) && (pSiS->CRT2pScrn->monitor->DDC)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, subshstr, 2); SiSSetSyncRangeFromEdid(pSiS->CRT2pScrn, 1); } #endif - if(pSiS->CRT2pScrn->monitor->nHsync <= 0) { + if((pSiS->CRT2pScrn->monitor->nHsync <= 0) || (pSiS->OverruleRanges)) { if(pSiS->VBFlags & (CRT2_TV | CRT2_LCD)) { /* Set sane ranges for LCD and TV */ pSiS->CRT2pScrn->monitor->nHsync = 1; @@ -5133,14 +5140,14 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } } } - if(pSiS->CRT2pScrn->monitor->nVrefresh <= 0) { + if((pSiS->CRT2pScrn->monitor->nVrefresh <= 0) || (pSiS->OverruleRanges)) { #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,14,0) - if(pSiS->CRT2pScrn->monitor->DDC) { + if((pSiS->CRT2pScrn->monitor->nVrefresh <= 0) && (pSiS->CRT2pScrn->monitor->DDC)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, subsvstr, 2); SiSSetSyncRangeFromEdid(pSiS->CRT2pScrn, 0); } #endif - if(pSiS->CRT2pScrn->monitor->nVrefresh <= 0) { + if((pSiS->CRT2pScrn->monitor->nVrefresh <= 0) || (pSiS->OverruleRanges)) { if(pSiS->VBFlags & (CRT2_TV | CRT2_LCD)) { /* Set sane ranges for LCD and TV */ pSiS->CRT2pScrn->monitor->nVrefresh = 1; @@ -6820,7 +6827,7 @@ SISRestore(ScrnInfoPtr pScrn) */ if( ( (pSiS->restorebyset) || (pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) || - ((pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ) && + ((pSiS->sishw_ext.jChipType == SIS_730) && (pSiS->VBFlags & VB_LVDS)) ) && (pSiS->OldMode) ) { Bool changedmode = FALSE; @@ -7232,18 +7239,23 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) inSISIDXREG(SISCR, 0x30, cr30); inSISIDXREG(SISCR, 0x31, cr31); - /* What if CR34 is different from the BIOS byte? */ + /* What if CR34 is different from the BIOS scratch byte? */ if(pSiS->OldMode != myoldmode) { - /* If no bridge output is active, trust the BIOS byte */ - if(!cr31 && !cr30) pSiS->OldMode = myoldmode; + /* If no bridge output is active, trust the BIOS scratch byte */ + if( (!(pSiS->VBFlags & VB_VIDEOBRIDGE)) || + (pSiS->OldMode == 0) || + (!cr31 && !cr30) || + (cr31 & 0x20) ) { + pSiS->OldMode = myoldmode; + } /* ..else trust CR34 */ } /* Newer 650 BIOSes set CR34 to 0xff if the mode has been * "patched", for instance for 80x50 text mode. (That mode * has no number of its own, it's 0x03 like 80x25). In this - * case, we trust the BIOS byte (provided that any of these - * two is valid). + * case, we trust the BIOS scratch byte (provided that any + * of these two is valid). */ if(pSiS->OldMode > 0x7f) { pSiS->OldMode = myoldmode; diff --git a/src/sis_opt.c b/src/sis_opt.c index b344cae..0ea5001 100644 --- a/src/sis_opt.c +++ b/src/sis_opt.c @@ -144,6 +144,7 @@ typedef enum { OPTION_ENABLESISCTRL, OPTION_STOREDBRI, OPTION_STOREDPBRI, + OPTION_OVERRULERANGES, #ifdef SIS_CP SIS_CP_OPT_OPTIONS #endif @@ -240,6 +241,7 @@ static const OptionInfoRec SISOptions[] = { { OPTION_CENTERLCD, "CenterLCD", OPTV_BOOLEAN, {0}, -1 }, { OPTION_ENABLEHOTKEY, "EnableHotkey", OPTV_BOOLEAN, {0}, -1 }, { OPTION_ENABLESISCTRL, "EnableSiSCtrl", OPTV_BOOLEAN, {0}, -1 }, + { OPTION_OVERRULERANGES, "OverruleFrequencyRanges",OPTV_BOOLEAN, {0}, -1 }, #ifdef SISMERGED { OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_MERGEDFB2, "TwinView", OPTV_BOOLEAN, {0}, FALSE }, /* alias */ @@ -384,6 +386,7 @@ SiSOptions(ScrnInfoPtr pScrn) pSiS->GammaPBriR = pSiS->GammaPBriG = pSiS->GammaPBriB = 1000; pSiS->HideHWCursor = FALSE; pSiS->HWCursorIsVisible = FALSE; + pSiS->OverruleRanges = TRUE; #ifdef SISMERGED pSiS->MergedFB = pSiS->MergedFBAuto = FALSE; pSiS->CRT2Position = sisRightOf; @@ -403,7 +406,7 @@ SiSOptions(ScrnInfoPtr pScrn) /* Chipset dependent defaults */ if(pSiS->Chipset == PCI_CHIP_SIS530) { - /* TW: TQ still broken on 530/620? */ + /* TQ still broken on 530/620? */ pSiS->TurboQueue = FALSE; } @@ -587,6 +590,20 @@ SiSOptions(ScrnInfoPtr pScrn) #endif #endif + /* OverruleFrequencyRanges + * + * Enable/disable overruling bogus frequency ranges for TV and LCD(A) + */ + if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { + Bool val; + if(xf86GetOptValBool(pSiS->Options, OPTION_OVERRULERANGES, &val)) { + if(!val) { + pSiS->OverruleRanges = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overruling frequency ranges disabled\n"); + } + } + } + /* * MergedFB * @@ -1583,11 +1600,12 @@ SiSOptions(ScrnInfoPtr pScrn) * generated out of the known and supported modes. Use * this option to disable this. NOT RECOMMENDED. */ - from = X_DEFAULT; - if(xf86GetOptValBool(pSiS->Options, OPTION_NOINTERNALMODES, &pSiS->noInternalModes)) - from = X_CONFIG; - xf86DrvMsg(pScrn->scrnIndex, from, "Usage of built-in modes is %s\n", - pSiS->noInternalModes ? disabledstr : enabledstr); + if(xf86GetOptValBool(pSiS->Options, OPTION_NOINTERNALMODES, &pSiS->noInternalModes)) { + if(pSiS->noInternalModes) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Usage of built-in modes is %s\n", disabledstr); + } + } + } /* ShadowFB */ diff --git a/src/sis_vb.c b/src/sis_vb.c index 7e4de7f..2e95c0f 100644 --- a/src/sis_vb.c +++ b/src/sis_vb.c @@ -260,7 +260,7 @@ void SISCRT1PreInit(ScrnInfoPtr pScrn) } xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "%sCRT1 (VGA) connection detected\n", + "%sCRT1/VGA detected\n", CRT1Detected ? "" : "No "); } |