diff options
author | Thomas Winischhofer <thomas@winischhofer.net> | 2004-06-29 10:09:58 +0000 |
---|---|---|
committer | Thomas Winischhofer <thomas@winischhofer.net> | 2004-06-29 10:09:58 +0000 |
commit | 1d8c6bd12b70f49cbb4944194c14b94d1dc42c05 (patch) | |
tree | 09d342c85868d2b8f40434d5bfad293346f72dd6 | |
parent | f112c72223b4964b0f8f2a510e323fee55742d3e (diff) |
SiS driver:
- Fix detection of non-standard panels
- Support Sanyo PLV-Z2 in non-HDCP mode
- Rework mode validation (map unsupported modes for TV to modes with same
resolution)
-rw-r--r-- | src/init.c | 117 | ||||
-rw-r--r-- | src/init.h | 27 | ||||
-rw-r--r-- | src/init301.c | 184 | ||||
-rw-r--r-- | src/init301.h | 4 | ||||
-rw-r--r-- | src/initdef.h | 3 | ||||
-rw-r--r-- | src/sis.h | 14 | ||||
-rw-r--r-- | src/sis_dac.c | 8 | ||||
-rw-r--r-- | src/sis_dri.c | 8 | ||||
-rw-r--r-- | src/sis_driver.c | 726 | ||||
-rw-r--r-- | src/sis_driver.h | 9 | ||||
-rw-r--r-- | src/sis_vb.c | 26 | ||||
-rw-r--r-- | src/sis_video.c | 1 |
12 files changed, 649 insertions, 478 deletions
@@ -960,7 +960,7 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, break; case 1400: if(VGAEngine == SIS_315_VGA) { - if(VBFlags & (VB_301B | VB_301C | VB_302B | VB_302LV | VB_302ELV)) { + if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) { if((LCDwidth == 1400) || (LCDwidth == 1600) || (LCDwidth == 1680)) { ModeIndex = ModeIndex_1400x1050[Depth]; } @@ -969,18 +969,20 @@ SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, break; case 1600: if(VGAEngine == SIS_315_VGA) { - if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) { + if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) { if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; } } break; +#ifndef VB_FORBID_CRT2LCD_OVER_1600 case 1680: if(VGAEngine == SIS_315_VGA) { - if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) { + if(VBFlags & (VB_301C | VB_302LV | VB_302ELV)) { if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; } } break; +#endif } } @@ -3653,28 +3655,29 @@ BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom) { - SISPtr pSiS = SISPTR(pScrn); - UShort ModeNo=0; + SISPtr pSiS = SISPTR(pScrn); + UShort ModeNo = 0; SiS_Pr->UseCustomMode = FALSE; if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", SiS_Pr->CHDisplay, (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 : (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 : SiS_Pr->CVDisplay))); - return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE)); - - } - - ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes); - if(!ModeNo) return FALSE; + } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo); + /* Don't need vbflags here; checks done earlier */ + ModeNo = SiS_GetModeNumber(pScrn, mode, 0); + if(!ModeNo) return FALSE; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo); + + } + return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE)); } @@ -3698,9 +3701,8 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, SiS_Pr->UseCustomMode = FALSE; /* Remember: Custom modes for CRT2 are ONLY supported - * -) on 315/330 series, - * -) on the 30x/B/C, and - * -) if CRT2 is LCD or VGA + * -) on the 30x/B/C, and + * -) if CRT2 is LCD or VGA, or CRT1 is LCDA */ if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { @@ -3709,13 +3711,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, } else { - BOOLEAN havecustommodes = pSiS->HaveCustomModes; - -#ifdef SISMERGED - if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2; -#endif - - ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, havecustommodes); + ModeNo = SiS_GetModeNumber(pScrn, mode, 0); if(!ModeNo) return FALSE; } @@ -3754,7 +3750,7 @@ SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, } #endif - /* We don't clear the buffer under X */ + /* We don't clear the buffer in X */ SiS_Pr->SiS_flag_clearbuffer=0; if(SiS_Pr->UseCustomMode) { @@ -3893,7 +3889,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, } else { - ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes); + ModeNo = SiS_GetModeNumber(pScrn, mode, 0); if(!ModeNo) return FALSE; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, @@ -3912,7 +3908,7 @@ SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn, SiSSetLVDSetc(SiS_Pr, HwInfo); SiSDetermineROMUsage(SiS_Pr, HwInfo); - /* We don't clear the buffer under X */ + /* We don't clear the buffer in X */ SiS_Pr->SiS_flag_clearbuffer = 0; SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); @@ -4430,7 +4426,39 @@ SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags) return 1; } -/* Build a list of supported modes */ +int +SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy) +{ + int i, j; + BOOLEAN done = FALSE; + + i = 0; + while((!done) && (SiS_PlasmaTable[i].vendor) && panelvendor) { + if(SiS_PlasmaTable[i].vendor == panelvendor) { + for(j=0; j<SiS_PlasmaTable[i].productnum; j++) { + if(SiS_PlasmaTable[i].product[j] == panelproduct) { + if(SiS_PlasmaTable[i].maxx && SiS_PlasmaTable[i].maxy) { + (*maxx) = (int)SiS_PlasmaTable[i].maxx; + (*maxy) = (int)SiS_PlasmaTable[i].maxy; + done = TRUE; + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, + "Identified %s, correcting max X res %d, max Y res %d\n", + SiS_PlasmaTable[i].plasmaname, + SiS_PlasmaTable[i].maxx, SiS_PlasmaTable[i].maxy); + break; + } + } + } + } + i++; + } + return (done) ? 1 : 0; +} + +/* Build a list of supported modes: + * Built-in modes for which we have all data are M_T_DEFAULT, + * modes derived from DDC or database data are M_T_BUILTIN + */ DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi) { @@ -4740,27 +4768,6 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfo current->VTotal >>= 1; } -#if 0 - if((backup = xalloc(sizeof(DisplayModeRec)))) { - if(!pSiS->backupmodelist) pSiS->backupmodelist = backup; - else { - pSiS->backupmodelist->next = backup; - backup->prev = pSiS->backupmodelist; - } - backup->next = NULL; - backup->HDisplay = current->HDisplay; - backup->HSyncStart = current->HSyncStart; - backup->HSyncEnd = current->HSyncEnd; - backup->HTotal = current->HTotal; - backup->VDisplay = current->VDisplay; - backup->VSyncStart = current->VSyncStart; - backup->VSyncEnd = current->VSyncEnd; - backup->VTotal = current->VTotal; - backup->Flags = current->Flags; - backup->Clock = current->Clock; - } -#endif - #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Built-in: %s %.2f %d %d %d %d %d %d %d %d\n", @@ -4803,11 +4810,19 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfo } else { if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue; } + + l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f; + + if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301LV)) { + if(isfordvi) { + if(SiS_PlasmaMode[l].VDisplay > 1024) continue; + } + } if(!(new = xalloc(sizeof(DisplayModeRec)))) return first; memset(new, 0, sizeof(DisplayModeRec)); - if(!(new->name = xalloc(10))) { + if(!(new->name = xalloc(12))) { xfree(new); return first; } @@ -4820,9 +4835,7 @@ SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfo current = new; pSiS->AddedPlasmaModes = TRUE; - - l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f; - + sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay, SiS_PlasmaMode[l].VDisplay); @@ -2127,10 +2127,12 @@ typedef struct _SiS_PlasmaTables USHORT product[5]; const char *DDCnames[5]; const char *plasmaname; + USHORT maxx,maxy; UCHAR modenum; UCHAR plasmamodes[20]; /* | 0x80 = DVI-capable, | 0x40 = analog */ } SiS_PlasmaTables; + static const SiS_PlasmaModes SiS_PlasmaMode[] = { { "640x400", /* 00: IBM 400@70 */ 25175, @@ -2245,6 +2247,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG", + 0, 0, 11, /* All DVI, except 0, 7, 13 */ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0, 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2255,6 +2258,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 42PD1/50PD1/50PD2", + 0, 0, 5, /* DVI entirely unknown */ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2263,6 +2267,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 42PD3", + 0, 0, 10, /* DVI entirely unknown */ { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2271,6 +2276,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 42VM3/61XM1", + 0, 0, 11, /* DVI entirely unknown */ { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0, 17|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2279,6 +2285,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 42MP1/42MP2", + 0, 0, 6, /* DVI entirely unknown */ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2287,6 +2294,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 50MP1", + 0, 0, 10, /* DVI entirely unknown */ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2296,6 +2304,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 }, { "PX-42VM", "", "", "", "" }, "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1", + 0, 0, 11, /* All DVI except 0, 7, 13, 17 */ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0, 17|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2305,6 +2314,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 3300W", + 0, 0, 3, { 0|0x40, 1|0xc0,18|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2321,6 +2331,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "NEC PlasmaSync 4210W", + 0, 0, 6, /* DVI entirely unknown */ { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2338,6 +2349,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "Pioneer 503CMX/PDA-5002", + 0, 0, 6, /* DVI unknown */ { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2346,6 +2358,7 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 }, { "", "", "", "", "" }, "Panasonic TH-42", + 0, 0, 5, /* No DVI output */ { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } @@ -2354,10 +2367,20 @@ static const SiS_PlasmaTables SiS_PlasmaTable[] = { { 0xa005, 0x0000, 0x0000, 0x0000, 0x0000 }, { "TH-42PW*4", "", "", "", "" }, "Panasonic TH-42PW5", + 0, 0, 1, /* No special modes otherwise; no DVI. */ {20|0x40,19|0x40, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } }, + { 0x4c2e, 1, + { 0x9b05, 0x0000, 0x0000, 0x0000, 0x0000 }, + { "PLV-Z2", "", "", "", "" }, + "Sanyo PLV-Z2 (non HDCP-mode)", /* HDCP mode would be id 9b06, but not needed */ + 1280, 768, /* as it then advertises correct size */ + 1, /* 1280x720, no special modes otherwise */ + { 6|0xc0, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } + }, { 0x0000 } }; @@ -2407,6 +2430,7 @@ int SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber); 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); #else BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo); #endif @@ -2447,8 +2471,7 @@ extern void SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned in extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value); extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id); -extern USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, - BOOLEAN hcm); +extern USHORT SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags); #endif #endif diff --git a/src/init301.c b/src/init301.c index 2508eaa..196f8cb 100644 --- a/src/init301.c +++ b/src/init301.c @@ -981,7 +981,7 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, #ifdef SIS315H if(HwInfo->jChipType >= SIS_315H) { - if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) { + if(SiS_Pr->SiS_VBType & VB_SISLCDA) { if(ModeNo == 0x03) { /* Mode 0x03 is never in driver mode */ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf); @@ -1012,13 +1012,13 @@ SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, if(HwInfo->jChipType >= SIS_661) { tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision); temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); - if(SiS_Pr->SiS_VBType & (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) { + if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { if(temp & 0x04) { temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0; if(temp == 0x60) tempbx |= SetCRT2ToHiVision; else tempbx |= SetCRT2ToYPbPr525750; } - } else if(SiS_Pr->SiS_VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B)) { + } else if(SiS_Pr->SiS_VBType & VB_SISHIVISION) { if(temp & 0x04) { temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0; if(temp == 0x60) tempbx |= SetCRT2ToHiVision; @@ -9557,7 +9557,7 @@ USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) { USHORT DDCdatatype, paneltype, flag, xres=0, yres=0; - USHORT index, myindex, lumsize, numcodes; + USHORT index, myindex, lumsize, numcodes, panelvendor, panelproduct; unsigned char cr37=0, seekcode; BOOLEAN checkexpand = FALSE; int retry, i; @@ -9652,15 +9652,15 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) paneltype = Panel_Custom; checkexpand = FALSE; + + panelvendor = buffer[9] | (buffer[8] << 8); + panelproduct = buffer[10] | (buffer[11] << 8); if(buffer[0x18] & 0x02) { - xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4); - yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4); - - SiS_Pr->CP_PreferredX = xres; - SiS_Pr->CP_PreferredY = yres; - + SiS_Pr->CP_PreferredX = xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4); + SiS_Pr->CP_PreferredY = yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4); + switch(xres) { #if 0 /* Treat as custom */ case 800: @@ -9704,7 +9704,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) } } break; -#if 0 /* Treat this as custom, as we have no valid timing data yet */ case 1600: if(pSiS->VGAEngine == SIS_315_VGA) { if(pSiS->VBFlags & VB_301C) { @@ -9715,7 +9714,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) } } break; -#endif } if(paneltype != Panel_Custom) { @@ -9730,6 +9728,21 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) } } + + /* Check against our database; Eg. Sanyo projector reports + * 1024x768 as preferred mode, although it supports 1280x720 + * natively in non-HTCP mode. Treat such wrongly reporting + * panels as custom and fixup actual maximum resolutions. + */ + if(paneltype != Panel_Custom) { + int maxx, maxy; + if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy))) { + paneltype = Panel_Custom; + SiS_Pr->CP_MaxX = maxx; + SiS_Pr->CP_MaxY = maxy; + /* Leave preferred unchanged (MUST contain a valid mode!) */ + } + } /* If we still don't know what panel this is, we take it * as a custom panel and derive the timing data from the @@ -9740,16 +9753,21 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) BOOLEAN havesync = FALSE; int i, temp, base = 0x36; unsigned long estpack; - unsigned short estx[] = { + const unsigned short estx[] = { 720, 720, 640, 640, 640, 640, 800, 800, 800, 800, 832,1024,1024,1024,1024,1280, 1152 }; - unsigned short esty[] = { + const unsigned short esty[] = { 400, 400, 480, 480, 480, 480, 600, 600, 600, 600, 624, 768, 768, 768, 768,1024, 870 }; + const int estclk[] = { + 0, 0, 25100, 0, 31500, 31500, 36100, 40000, + 50100, 49500, 0, 0, 65100, 75200, 78700,135200, + 0 + }; paneltype = 0; SiS_Pr->CP_Supports64048075 = TRUE; @@ -9762,8 +9780,14 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) if(estpack & (1 << i)) { if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i]; if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i]; + if(estclk[16 - i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = estclk[16 - i]; } } + + /* By default we drive the LCD at 75Hz in 640x480 mode; if + * the panel does not provide this mode, use 60hz + */ + if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE; /* 2. From Standard Timings */ for(i=0x26; i < 0x36; i+=2) { @@ -9808,29 +9832,28 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) SiS_Pr->CP_DataValid[i] = TRUE; /* Sort out invalid timings, interlace and too high clocks */ - if((SiS_Pr->CP_HDisplay[i] & 7) || - (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) || - (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) || - (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) || - (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) || - (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) || - (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) || - (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) || - (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) || - (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) || - (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) || - (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) || - (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) || + if((SiS_Pr->CP_HDisplay[i] & 7) || + (SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i]) || + (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i]) || + (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) || + (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i]) || + (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i]) || + (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i]) || + (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i]) || + (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) || + (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) || (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) || - ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) || + ((!(pSiS->VBFlags & VB_301C)) && + ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) || (buffer[base+17] & 0x80)) { SiS_Pr->CP_DataValid[i] = FALSE; } else { - paneltype = Panel_Custom; - SiS_Pr->CP_HaveCustomData = TRUE; if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres; @@ -9841,20 +9864,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) SiS_Pr->CP_PreferredIndex = i; } - SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8); - SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8); - - /* By default we drive the LCD at 75Hz in 640x480 mode; if - * the panel does not provide this mode, use 60hz - */ - if(!(buffer[0x23] & 0x04)) SiS_Pr->CP_Supports64048075 = FALSE; - - /* We must assume the panel can scale, since we have - * no scaling data - */ - checkexpand = FALSE; - cr37 |= 0x10; - /* Extract the sync polarisation information. This only works * if the Flags indicate a digital separate output. */ @@ -9869,13 +9878,32 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) } else { SiS_Pr->CP_SyncValid[i] = FALSE; } + } - } + + } else if((!buffer[base]) && (!buffer[base+1]) && (!buffer[base+2]) && (!buffer[base+4])) { + + /* Maximum pixclock from Monitor Range Limits */ + if((buffer[base+3] == 0xfd) && (buffer[base+9] != 0xff)) { + SiS_Pr->CP_MaxClock = buffer[base+9] * 10 * 1000; + } + + } + } - if(!havesync) { - xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, + + if(SiS_Pr->CP_MaxX && SiS_Pr->CP_MaxY) { + paneltype = Panel_Custom; + checkexpand = FALSE; + cr37 |= 0x10; + SiS_Pr->CP_Vendor = panelvendor; + SiS_Pr->CP_Product = panelproduct; + if(!havesync) { + xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, "CRT2: Unable to retrieve Sync polarity information\n"); - } + } + } + } if(paneltype && checkexpand) { @@ -9916,10 +9944,14 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) buffer[0x41]); return 0; } - + + SiS_Pr->CP_Vendor = panelvendor = buffer[2] | (buffer[1] << 8); + SiS_Pr->CP_Product = panelproduct = buffer[3] | (buffer[4] << 8); + paneltype = Panel_Custom; - SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8); - SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8); + SiS_Pr->CP_MaxX = SiS_Pr->CP_PreferredX = xres = buffer[0x76] | (buffer[0x77] << 8); + SiS_Pr->CP_MaxY = SiS_Pr->CP_PreferredY = yres = buffer[0x78] | (buffer[0x79] << 8); + switch(xres) { #if 0 case 800: @@ -9956,7 +9988,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) } } break; -#if 0 /* Treat this one as custom since we have no timing data yet */ case 1600: if(pSiS->VGAEngine == SIS_315_VGA) { if(pSiS->VBFlags & VB_301C) { @@ -9967,7 +9998,6 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) } } break; -#endif } /* Determine if RGB18 or RGB24 */ @@ -9990,7 +10020,25 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) lumsize++; /* luminance header byte */ index += lumsize; } +#if 0 /* "pixel rate" = pixel clock? */ + if(buffer[0x7e] & 0x1c) { + for(i=0; i<((buffer[0x7e] & 0x1c) >> 2); i++) { + if(buffer[index + (i*8) + 6] && (buffer[index + (i*8) + 7] & 0x0f)) { + int clk = (buffer[index + (i*8) + 6] | ((buffer[index + (i*8) + 7] & 0x0f) << 4)) * 1000; + if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk; + } + } + } +#endif index += (((buffer[0x7e] & 0x1c) >> 2) * 8); /* skip Frequency Ranges */ + if(buffer[0x7e] & 0x03) { + for(i=0; i<(buffer[0x7e] & 0x03); i++) { + if((buffer[index + (i*27) + 9]) || (buffer[index + (i*27) + 10])) { + int clk = ((buffer[index + (i*27) + 9]) | ((buffer[index + (i*27) + 9]) << 8)) * 10; + if(clk > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = clk; + } + } + } index += ((buffer[0x7e] & 0x03) * 27); /* skip Detailed Range Limits */ numcodes = (buffer[0x7f] & 0xf8) >> 3; if(numcodes) { @@ -10010,6 +10058,21 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, "CRT2: Unable to retrieve Sync polarity information\n"); } + + /* Check against our database; Eg. Sanyo projector reports + * 1024x768 in non-HDPC mode, although it supports 1280x720. + * Treat such wrongly reporting panels as custom. + */ + if(paneltype != Panel_Custom) { + int maxx, maxy; + if((SiS_FindPanelFromDB(pSiS, panelvendor, panelproduct, &maxx, &maxy))) { + paneltype = Panel_Custom; + SiS_Pr->CP_MaxX = maxx; + SiS_Pr->CP_MaxY = maxy; + cr37 |= 0x10; + /* Leave preferred unchanged (MUST be a valid mode!) */ + } + } /* Now seek the detailed timing descriptions for custom panels */ if(paneltype == Panel_Custom) { @@ -10054,7 +10117,8 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i]) || (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i]) || (((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162500)) || - ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108200))) || + ((!(pSiS->VBFlags & VB_301C)) && + ((SiS_Pr->CP_Clock[i] > 108200) || (SiS_Pr->CP_VDisplay[i] > 1024)))) || (buffer[index + 17] & 0x80)) { SiS_Pr->CP_DataValid[i] = FALSE; @@ -10065,7 +10129,7 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i]; - if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) { + if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) { SiS_Pr->CP_PreferredIndex = i; } @@ -10073,17 +10137,11 @@ SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS) SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE; SiS_Pr->CP_SyncValid[i] = TRUE; - SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8); - SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8); - - /* We must assume the panel can scale, since we have - * no scaling data - */ - cr37 |= 0x10; - } } + cr37 |= 0x10; + } break; diff --git a/src/init301.h b/src/init301.h index b0c74dd..f2a72bc 100644 --- a/src/init301.h +++ b/src/init301.h @@ -411,4 +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); +#ifdef LINUX_XF86 +extern int SiS_FindPanelFromDB(SISPtr pSiS, USHORT panelvendor, USHORT panelproduct, int *maxx, int *maxy); +#endif + #endif diff --git a/src/initdef.h b/src/initdef.h index 13fc262..42b2f80 100644 --- a/src/initdef.h +++ b/src/initdef.h @@ -87,6 +87,9 @@ #define VB_SISVB (VB_SIS301 | VB_SIS301BLV302BLV) #define VB_SISTMDS (VB_SIS301 | VB_SIS301B302B) #define VB_SISLVDS VB_SIS301LV302LV +#define VB_SISLCDA (VB_SIS302B|VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV) +#define VB_SISYPBPR (VB_SIS301C|VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV) +#define VB_SISHIVISION (VB_SIS301|VB_SIS301B|VB_SIS302B) /* VBInfo */ #define SetSimuScanMode 0x0001 /* CR 30 */ @@ -40,7 +40,7 @@ #define SISDRIVERVERSIONYEAR 4 #define SISDRIVERVERSIONMONTH 6 -#define SISDRIVERVERSIONDAY 23 +#define SISDRIVERVERSIONDAY 29 #define SISDRIVERREVISION 1 #define SISDRIVERIVERSION (SISDRIVERVERSIONYEAR << 16) | \ @@ -254,6 +254,13 @@ #define VB_VIDEOBRIDGE (VB_SISBRIDGE | VB_LVDS | VB_CHRONTEL | VB_CONEXANT) #define VB_SISLVDSBRIDGE (VB_301LV|VB_302LV|VB_302ELV) #define VB_SISTMDSBRIDGE (VB_301|VB_301B|VB_301C|VB_302B) +#define VB_SISTMDSLCDABRIDGE (VB_301C) +#define VB_SISVGA2BRIDGE (VB_301|VB_301B|VB_301C|VB_302B) +#define VB_SISLCDABRIDGE (VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV) +#define VB_SISHIVISIONBRIDGE (VB_301|VB_301B|VB_302B) +#define VB_SISYPBPRBRIDGE (VB_301C|VB_301LV|VB_302LV|VB_302ELV) +#define VB_SISYPBPRARBRIDGE (VB_301C) +#define VB_SISTAP4SCALER (VB_301C|VB_302ELV) #define DISPTYPE_DISP2 CRT2_ENABLE #define DISPTYPE_DISP1 DISPTYPE_CRT1 @@ -286,6 +293,8 @@ #define VB_LCD_CUSTOM 0x40000000 #define VB_LCD_EXPANDING 0x80000000 +#define VB_FORBID_CRT2LCD_OVER_1600 /* CRT2/LCD supports only up to 1600 pixels */ + /* PresetMode argument */ #define SIS_MODE_SIMU 0 #define SIS_MODE_CRT1 1 @@ -986,6 +995,9 @@ typedef struct { unsigned long mmioSize; BOOLEAN ROM661New; BOOLEAN NewCRLayout; + BOOLEAN skipswitchcheck; + unsigned long VBFlagsInit; + DisplayModePtr currentModeLast; #ifdef SISMERGED Bool MergedFB, MergedFBAuto; SiSScrn2Rel CRT2Position; diff --git a/src/sis_dac.c b/src/sis_dac.c index d5e0ca3..5b12cda 100644 --- a/src/sis_dac.c +++ b/src/sis_dac.c @@ -1412,10 +1412,12 @@ SiSEstimateCRT2Clock(ScrnInfoPtr pScrn, BOOLEAN IsForMergedFBCRT2) else return 122000; } else if(pSiS->VBLCDFlags & VB_LCD_1600x1200) { return 162000; - } else if((pSiS->VBLCDFlags & VB_LCD_CUSTOM) && (pSiS->SiS_Pr->CP_HaveCustomData)) { + } else if((pSiS->VBLCDFlags & VB_LCD_CUSTOM) && (pSiS->SiS_Pr->CP_MaxClock)) { return pSiS->SiS_Pr->CP_MaxClock; - } else - return 108000; + } else { + if(pSiS->VBFlags & VB_301C) return 162000; + else return 108000; + } } else if(pSiS->VBFlags & CRT2_TV) { if(pSiS->VBFlags & VB_CHRONTEL) { switch(pSiS->VGAEngine) { diff --git a/src/sis_dri.c b/src/sis_dri.c index 352e30e..91eedd3 100644 --- a/src/sis_dri.c +++ b/src/sis_dri.c @@ -52,10 +52,14 @@ #undef SISHAVECOMPATLAYER #ifdef XORG_VERSION_CURRENT #define SISHAVECOMPATLAYER +#define SISHAVECREATEBUSID #else # if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,4,99,7,0) # define SISHAVECOMPATLAYER # endif +# if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,4,99,99,0) +# undef SISHAVECREATEBUSID /* Waiting, waiting, waiting... */ +# endif #endif #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) @@ -294,15 +298,19 @@ Bool SISDRIScreenInit(ScreenPtr pScreen) pDRIInfo->drmDriverName = SISKernelDriverName; pDRIInfo->clientDriverName = SISClientDriverName; +#ifdef SISHAVECREATEBUSID if(xf86LoaderCheckSymbol("DRICreatePCIBusID")) { pDRIInfo->busIdString = DRICreatePCIBusID(pSIS->PciInfo); } else { +#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); +#ifdef SISHAVECREATEBUSID } +#endif /* Hack to keep old DRI working -- checked for major==1 and * minor==1. diff --git a/src/sis_driver.c b/src/sis_driver.c index 6068ced..b7b2100 100644 --- a/src/sis_driver.c +++ b/src/sis_driver.c @@ -591,7 +591,7 @@ SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla } } - if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) { + if(pSiS->VBFlags & VB_SISLVDSBRIDGE) { if((docrt2 && (pSiS->VBFlags & CRT2_LCD)) || (docrt1 && (pSiS->VBFlags & CRT1_LCDA))) { if(backlight) { SiS_SiS30xBLOn(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -611,7 +611,7 @@ SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla setSISIDXREG(SISSR, 0x11, 0x3f, pmreg); break; case SIS_315_VGA: - if((!pSiS->CRT1off) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C))) { + if((!pSiS->CRT1off) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_SISTMDSLCDABRIDGE))) { setSISIDXREG(SISCR, pSiS->myCR63, 0xbf, cr63); setSISIDXREG(SISSR, 0x07, 0xef, sr7); } @@ -620,7 +620,7 @@ SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla if(!SiSBridgeIsInSlaveMode(pScrn)) { setSISIDXREG(SISSR, 0x01, ~0x20, sr1); /* Set/Clear "Display On" bit */ } - if((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C)) { + if((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_SISTMDSLCDABRIDGE)) { inSISIDXREG(SISSR, 0x1f, oldpmreg); if((!pSiS->CRT1off) && (!SiSBridgeIsInSlaveMode(pScrn))) { setSISIDXREG(SISSR, 0x1f, 0x3f, pmreg); @@ -660,7 +660,8 @@ SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla } } - if((docrt1) && (pmreg != oldpmreg) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C))) { + if((docrt1) && (pmreg != oldpmreg) && + ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_SISTMDSLCDABRIDGE))) { outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ usleep(10000); outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ @@ -2189,7 +2190,7 @@ SiSInternalDDC(ScrnInfoPtr pScrn, int crtno) } else { /* If CRT1 is LCDA, skip DDC (except 301C: DDC allowed, but uses CRT2 port!) */ if(pSiS->VBFlags & CRT1_LCDA) { - if(pSiS->VBFlags & VB_301C) realcrtno = 1; + if(pSiS->VBFlags & VB_SISTMDSLCDABRIDGE) realcrtno = 1; else return NULL; } } @@ -2311,8 +2312,8 @@ void SISDetermineLCDACap(ScrnInfoPtr pScrn) SISPtr pSiS = SISPTR(pScrn); if( ((pSiS->sishw_ext.jChipType == SIS_650) || - (pSiS->sishw_ext.jChipType >= SIS_661)) && - (pSiS->VBFlags & (VB_301C | VB_302B | VB_301LV | VB_302LV)) && + (pSiS->sishw_ext.jChipType >= SIS_661)) && + (pSiS->VBFlags & VB_SISLCDABRIDGE) && (pSiS->VESA != 1) ) { pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTLCDA; } else { @@ -2384,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 monitor HSync range by suitable data\n"; - static const char *sanev = "Substituting missing monitor VRefresh range by suitable data\n"; + 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"; #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"; @@ -2697,6 +2698,9 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) SISFreeRec(pScrn); return FALSE; } + + /* Always do a ValidMode() inside Switchmode() */ + pSiS->skipswitchcheck = FALSE; /* Determine chipset and VGA engine type */ pSiS->ChipFlags = 0; @@ -4128,7 +4132,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) if(pSiS->ForceCRT1Type == CRT1_LCDA) { if( ((pSiS->sishw_ext.jChipType != SIS_650) && (pSiS->sishw_ext.jChipType < SIS_661)) || - (!(pSiS->VBFlags & (VB_301C | VB_302B | VB_301LV | VB_302LV))) ) { + (!(pSiS->VBFlags & VB_SISLCDABRIDGE)) ) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Chipset/Video bridge does not support LCD-via-CRT1\n"); pSiS->ForceCRT1Type = CRT1_VGA; @@ -4148,20 +4152,20 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) #ifdef ENABLE_YPBPR if((pSiS->VGAEngine == SIS_315_VGA) && - (pSiS->VBFlags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) { + (pSiS->VBFlags & VB_SISYPBPRBRIDGE)) { pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTYPBPR; - if((pSiS->Chipset == PCI_CHIP_SIS660) || (pSiS->VBFlags & VB_301C)) { + if(pSiS->VBFlags & VB_SISYPBPRARBRIDGE) { pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTYPBPRAR; } } - if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B)) { + if(pSiS->VBFlags & VB_SISHIVISIONBRIDGE) { pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTHIVISION; } #endif if((pSiS->VGAEngine != SIS_300_VGA) || (!(pSiS->VBFlags & VB_TRUMPION))) { pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTSCALE; - if((pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301C)) && + if((pSiS->VBFlags & VB_SISTMDSBRIDGE) && (!(pSiS->VBFlags & VB_30xBDH))) { pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTCENTER; } @@ -4209,7 +4213,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) ((pSiS->VBFlags & VB_CHRONTEL) && (pSiS->ChrontelType == CHRONTEL_700x))) { pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTTVPOS; } - if(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) { + if(pSiS->VBFlags & VB_SISVGA2BRIDGE) { pSiS->SiS_SD_Flags |= (SiS_SD_SUPPORTSCART | SiS_SD_SUPPORTVGA2); } if(pSiS->VBFlags & VB_CHRONTEL) { @@ -4271,7 +4275,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) break; case CRT2_VGA: pSiS->VBFlags &= ~(CRT2_TV | CRT2_LCD); - if(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) + if(pSiS->VBFlags & VB_SISVGA2BRIDGE) pSiS->VBFlags |= CRT2_VGA; else { pSiS->VBFlags &= ~(CRT2_VGA); @@ -4743,7 +4747,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) inSISIDXREG(SISCR, 0x30, tmp); /* Save the current PDC if the panel is used at the moment. */ - if(pSiS->VBFlags & (VB_301LV | VB_302LV | VB_302ELV)) { + if(pSiS->VBFlags & VB_SISLVDSBRIDGE) { if(pSiS->sisfbpdc != 0xff) { pSiS->SiS_Pr->PDC = pSiS->sisfbpdc; @@ -4799,7 +4803,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } /* Let user override (for all bridges) */ - if(pSiS->VBFlags & (VB_301B | VB_301C | VB_301LV | VB_302LV | VB_302ELV)) { + if(pSiS->VBFlags & (VB_301B | VB_301C | VB_SISLVDSBRIDGE)) { if(pSiS->PDC != -1) { pSiS->SiS_Pr->PDC = pSiS->PDC & 0x1f; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, @@ -5074,7 +5078,11 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pScrn->monitor->nHsync = 1; pScrn->monitor->hsync[0].lo = 28; pScrn->monitor->hsync[0].hi = 80; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, saneh); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, saneh, +#ifdef SISDUALHEAD + pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) : +#endif + pSiS->CRT1off ? 2 : 1); } } } @@ -5096,7 +5104,11 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pScrn->monitor->nVrefresh = 1; pScrn->monitor->vrefresh[0].lo = 59; pScrn->monitor->vrefresh[0].hi = 71; /* 71 for 640x400 */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, sanev); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, sanev, +#ifdef SISDUALHEAD + pSiS->DualHeadMode ? (pSiS->SecondHead ? 1 : 2) : +#endif + pSiS->CRT1off ? 2 : 1); } } } @@ -5117,7 +5129,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->CRT2pScrn->monitor->nHsync = 1; pSiS->CRT2pScrn->monitor->hsync[0].lo = 28; pSiS->CRT2pScrn->monitor->hsync[0].hi = 80; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, saneh); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, saneh, 2); } } } @@ -5134,7 +5146,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->CRT2pScrn->monitor->nVrefresh = 1; pSiS->CRT2pScrn->monitor->vrefresh[0].lo = 59; pSiS->CRT2pScrn->monitor->vrefresh[0].hi = 71; /* 71 for 640x400 */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, sanev); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, sanev, 2); } } } @@ -5203,51 +5215,92 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) * modes if * -) vbtype is 301, 301B, 301C or 302B, and * -) crt2 device is not TV, and - * -) crt1 is not LCDA + * -) crt1 is not LCDA, unless bridge is TMDS/LCDA capable (301C) */ if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { if(!(pSiS->noInternalModes)) { - BOOLEAN acceptcustommodes = TRUE; - BOOLEAN includelcdmodes = TRUE; - BOOLEAN isfordvi = FALSE; + BOOLEAN acceptcustommodes = TRUE; /* Accept user modelines */ + BOOLEAN includelcdmodes = TRUE; /* Include modes reported by DDC */ + BOOLEAN isfordvi = FALSE; /* Is for digital DVI output */ if(pSiS->UseVESA) { acceptcustommodes = FALSE; includelcdmodes = FALSE; } -#ifdef SISDUALHEAD +#ifdef SISDUALHEAD /* Dual head is static. Output devices will not change. */ if(pSiS->DualHeadMode) { if(!pSiS->SecondHead) { - if((pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && (!(pSiS->VBFlags & VB_30xBDH))) { - if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; - if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; - if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE; + if(pSiS->VBFlags & VB_SISTMDSBRIDGE) { + if(!(pSiS->VBFlags & VB_30xBDH)) { + if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; + if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; + if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE; + } else { + if(pSiS->VBFlags & (CRT2_TV|CRT2_LCD)) { + acceptcustommodes = FALSE; + includelcdmodes = FALSE; + } + } } else { acceptcustommodes = FALSE; includelcdmodes = FALSE; } clockRanges->interlaceAllowed = FALSE; } else { - includelcdmodes = FALSE; - if(pSiS->VBFlags & CRT1_LCDA) { - acceptcustommodes = FALSE; - /* Ignore interlace, mode switching code will handle this */ + if(pSiS->VBFlags & CRT1_LCDA) { + if(!(pSiS->VBFlags & VB_SISTMDSLCDABRIDGE)) { + acceptcustommodes = FALSE; + includelcdmodes = FALSE; + /* Will handle i-lace in mode-switching code */ + } else { + isfordvi = TRUE; + /* Don't allow i-lace modes */ + clockRanges->interlaceAllowed = FALSE; + } + } else { + includelcdmodes = FALSE; } } } else #endif -#ifdef SISMERGED +#ifdef SISMERGED /* MergedFB mode is not static. Output devices may change. */ if(pSiS->MergedFB) { - includelcdmodes = FALSE; if(pSiS->VBFlags & CRT1_LCDA) { - acceptcustommodes = FALSE; - /* Ignore interlace, mode switching code will handle this */ + if(!(pSiS->VBFlags & VB_SISTMDSLCDABRIDGE)) { + acceptcustommodes = FALSE; + includelcdmodes = FALSE; + /* Will handle i-lace in mode-switching code */ + } else { + isfordvi = TRUE; + /* Don't allow i-lace custom modes */ + clockRanges->interlaceAllowed = FALSE; + } + } else { + includelcdmodes = FALSE; } } else -#endif - if((pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && (!(pSiS->VBFlags & VB_30xBDH))) { - if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; - if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; - if(pSiS->VBFlags & (CRT2_TV|CRT1_LCDA)) acceptcustommodes = FALSE; +#endif /* Mirror mode is not static. Output devices may change. */ + if(pSiS->VBFlags & VB_SISTMDSBRIDGE) { + if(!(pSiS->VBFlags & VB_30xBDH)) { + if(!(pSiS->VBFlags & VB_SISTMDSLCDABRIDGE)) { + if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; + if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; + } else { + if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA|CRT1_LCDA))) includelcdmodes = FALSE; + if(pSiS->VBFlags & (CRT2_LCD|CRT1_LCDA)) isfordvi = TRUE; + } + /* Allow user modes, even if CRT2 is TV. Will be filtered through ValidMode(); + * leaving the user modes here might have the advantage that such a mode, if + * it matches in resolution with a supported TV mode, allows us to drive eg. + * non standard panels, and still permits switching to TV. This mode will be + * "mapped" to a supported mode of identical resolution for TV. All this is + * taken care of by ValidMode() and ModeInit()/PresetMode(). + */ + } else { + if(pSiS->VBFlags & (CRT2_TV|CRT2_LCD)) { + acceptcustommodes = FALSE; + includelcdmodes = FALSE; + } + } } else if(pSiS->VBFlags & (CRT2_ENABLE | CRT1_LCDA)) { acceptcustommodes = FALSE; includelcdmodes = FALSE; @@ -5496,10 +5549,17 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Max pixel clock for CRT2 is %d MHz\n", clockRanges->maxClock / 1000); - if((pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && (!(pSiS->VBFlags & VB_30xBDH))) { - if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; - if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; - if(pSiS->VBFlags & CRT2_TV) acceptcustommodes = FALSE; + if(pSiS->VBFlags & VB_SISTMDSBRIDGE) { + if(!(pSiS->VBFlags & VB_30xBDH)) { + if(!(pSiS->VBFlags & (CRT2_LCD|CRT2_VGA))) includelcdmodes = FALSE; + if(pSiS->VBFlags & CRT2_LCD) isfordvi = TRUE; + /* See above for a remark on handling CRT2 = TV */ + } else { + if(pSiS->VBFlags & (CRT2_LCD|CRT2_TV)) { + includelcdmodes = FALSE; + acceptcustommodes = FALSE; + } + } } else { includelcdmodes = FALSE; acceptcustommodes = FALSE; @@ -5771,6 +5831,9 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) #endif if(pSiS->enablesisctrl) pSiS->SiS_SD_Flags |= SiS_SD_ENABLED; + + pSiS->currentModeLast = pScrn->currentMode; + pSiS->VBFlagsInit = pSiS->VBFlags; return TRUE; } @@ -6438,7 +6501,7 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) if(!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT2, - pSiS->IsCustomCRT2)) { + pSiS->IsCustom)) { SISErrorLog(pScrn, "SiSBIOSSetModeCRT2() failed\n"); return FALSE; } @@ -6446,26 +6509,34 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } else { #endif - if(pSiS->VBFlags & CRT1_LCDA) { + if((pSiS->VBFlags & CRT1_LCDA) || (!(mode->type & M_T_DEFAULT))) { + SiSPreSetMode(pScrn, mode, SIS_MODE_CRT1); + if(!SiSBIOSSetModeCRT1(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { SISErrorLog(pScrn, "SiSBIOSSetModeCRT1() failed\n"); return FALSE; } + SiSPreSetMode(pScrn, mode, SIS_MODE_CRT2); + if(!SiSBIOSSetModeCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { SISErrorLog(pScrn, "SiSBIOSSetModeCRT2() failed\n"); return FALSE; } + } else { + SiSPreSetMode(pScrn, mode, SIS_MODE_SIMU); + if(!SiSBIOSSetMode(pSiS->SiS_Pr, &pSiS->sishw_ext, pScrn, mode, pSiS->IsCustom)) { - SISErrorLog(pScrn, "SiSBIOSSetModeCRT() failed\n"); + SISErrorLog(pScrn, "SiSBIOSSetMode() failed\n"); return FALSE; } + } #ifdef SISMERGED @@ -6533,7 +6604,7 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } /* Update Currentlayout */ - pSiS->CurrentLayout.mode = mode; + pSiS->CurrentLayout.mode = pSiS->currentModeLast = mode; return TRUE; } @@ -6648,34 +6719,16 @@ SiSFixupSR11(ScrnInfoPtr pScrn) if(pSiS->sishw_ext.jChipType >= SIS_661) { inSISIDXREG(SISSR,0x11,tmpreg); -#ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SiSFixupSR11(): SR11 reads %02x\n", tmpreg); -#endif if(tmpreg & 0x20) { - inSISIDXREG(SISSR,0x3e,tmpreg); -#ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SiSFixupSR11(): SR3e reads %02x\n", tmpreg); -#endif + inSISIDXREG(SISSR,0x3e,tmpreg); tmpreg = (tmpreg + 1) & 0xff; - outSISIDXREG(SISSR,0x3e,tmpreg); -#ifdef TWDEBUG - inSISIDXREG(SISSR,0x3e,tmpreg); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SiSFixupSR11(): SR3e reads %02x after writing\n", tmpreg); -#endif + outSISIDXREG(SISSR,0x3e,tmpreg); } inSISIDXREG(SISSR,0x11,tmpreg); if(tmpreg & 0xf0) { andSISIDXREG(SISSR,0x11,0x0f); - } -#ifdef TWDEBUG - inSISIDXREG(SISSR,0x11,tmpreg); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SiSFixupSR11(): SR11 reads %02x after AND 0x0f\n", tmpreg); -#endif + } } } @@ -6847,18 +6900,14 @@ SISRestore(ScrnInfoPtr pScrn) /* (This became necessary due to the switch to VRAM queue) */ if(pSiS->VGAEngine == SIS_315_VGA) { unsigned char tempCR55=0; - if(pSiS->sishw_ext.jChipType <= SIS_330) { - inSISIDXREG(SISCR,0x55,tempCR55); - andSISIDXREG(SISCR,0x55,0x33); - } + inSISIDXREG(SISCR,0x55,tempCR55); + andSISIDXREG(SISCR,0x55,0x33); outSISIDXREG(SISSR,0x26,0x01); MMIO_OUT32(pSiS->IOBase, 0x85c4, 0); outSISIDXREG(SISSR,0x27,sisReg->sisRegs3C4[0x27]); outSISIDXREG(SISSR,0x26,sisReg->sisRegs3C4[0x26]); MMIO_OUT32(pSiS->IOBase, 0x85C0, sisReg->sisMMIO85C0); - if(pSiS->sishw_ext.jChipType <= SIS_330) { - outSISIDXREG(SISCR,0x55,tempCR55); - } + outSISIDXREG(SISCR,0x55,tempCR55); } #endif @@ -7010,18 +7059,14 @@ SISVESARestore(ScrnInfoPtr pScrn) if(pSiS->VGAEngine == SIS_315_VGA) { SISRegPtr sisReg = &pSiS->SavedReg; unsigned char tempCR55=0; - if(pSiS->sishw_ext.jChipType <= SIS_330) { - inSISIDXREG(SISCR,0x55,tempCR55); - andSISIDXREG(SISCR,0x55,0x33); - } + inSISIDXREG(SISCR,0x55,tempCR55); + andSISIDXREG(SISCR,0x55,0x33); outSISIDXREG(SISSR,0x26,0x01); MMIO_OUT32(pSiS->IOBase, 0x85c4, 0); outSISIDXREG(SISSR,0x27,sisReg->sisRegs3C4[0x27]); outSISIDXREG(SISSR,0x26,sisReg->sisRegs3C4[0x26]); MMIO_OUT32(pSiS->IOBase, 0x85C0, sisReg->sisMMIO85C0); - if(pSiS->sishw_ext.jChipType <= SIS_330) { - outSISIDXREG(SISCR,0x55,tempCR55); - } + outSISIDXREG(SISCR,0x55,tempCR55); } #endif } @@ -7211,6 +7256,15 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif } + + /* RandR resets screen mode and size in CloseScreen(), hence + * we need to adapt our VBFlags to the initial state if the + * current mode has changed since closescreen() (or Screeninit() + * for the first instance) + */ + if(pScrn->currentMode != pSiS->currentModeLast) { + pSiS->VBFlags = pSiS->VBFlags_backup = pSiS->VBFlagsInit; + } /* Initialise the first mode */ if(!SISModeInit(pScrn, pScrn->currentMode)) { @@ -7229,18 +7283,6 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); /* - * The next step is to setup the screen's visuals, and initialise the - * framebuffer code. In cases where the framebuffer's default - * choices for things like visual layouts and bits per RGB are OK, - * this may be as simple as calling the framebuffer's ScreenInit() - * function. If not, the visuals will need to be setup before calling - * a fb ScreenInit() function and fixed up after. - * - * For most PC hardware at depths >= 8, the defaults that cfb uses - * are not appropriate. In this driver, we fixup the visuals after. - */ - - /* * Reset visual list. */ miClearVisualTypes(); @@ -7322,7 +7364,7 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif /* - * Call the framebuffer layer's ScreenInit function, and fill in other + * Call the framebuffer layer's ScreenInit function and fill in other * pScreen fields. */ switch(pScrn->bitsPerPixel) { @@ -7367,7 +7409,7 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Initialize RENDER ext; must be after RGB ordering fixed */ fbPictureInit(pScreen, 0, 0); - /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */ + /* hardware cursor needs to wrap this layer */ if(!pSiS->ShadowFB) SISDGAInit(pScreen); xf86SetBlackWhitePixels(pScreen); @@ -7619,6 +7661,12 @@ SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SISPtr pSiS = SISPTR(pScrn); + + if(!pSiS->skipswitchcheck) { + if(SISValidMode(scrnIndex, mode, TRUE, flags) != MODE_OK) { + return FALSE; + } + } if(!pSiS->NoAccel) { if(pSiS->AccelInfoPtr) { @@ -7645,13 +7693,15 @@ Bool SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) { SISPtr pSiS = SISPTR(pScrn); - BOOLEAN hcm; + BOOLEAN hcm = pSiS->HaveCustomModes; DisplayModePtr mode = pScrn->currentMode; /* Do NOT use this to switch from CRT2_LCD to CRT1_LCDA */ + /* Switching CRT2 to LCD or VGA will switch CRT1 to VGA if * previously LCD-via-CRT1 */ + /* For usability reasons, the user should not simply "lose" one * of his output devices in MergedFB mode. Therefore, a switch * which might lead to this situation will not be performed in @@ -7707,9 +7757,8 @@ SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) if(mode->Private) { mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; } - } else + } #endif - hcm = pSiS->HaveCustomModes; if((!(newvbflags & CRT2_ENABLE)) && (!newvbflags & DISPTYPE_CRT1)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -7723,12 +7772,10 @@ SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) } /* Check if the current mode is suitable for desired output device (if any) */ - if(newvbflags & CRT2_ENABLE) { - if(!SiS_CheckCalcModeIndex(pScrn, mode, newvbflags, hcm)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + if(SiS_CheckModeCRT2(pScrn, mode, newvbflags, hcm) < 0x14) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Current mode not suitable for desired CRT2 output device\n"); - return FALSE; - } + return FALSE; } /* Remember: Dualhead not supported */ @@ -7748,7 +7795,12 @@ SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) pSiS->VBFlags = pSiS->VBFlags_backup = newvbflags; - if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE; + pSiS->skipswitchcheck = TRUE; + if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) { + pSiS->skipswitchcheck = FALSE; + return FALSE; + } + pSiS->skipswitchcheck = FALSE; SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); return TRUE; } @@ -7835,7 +7887,7 @@ SISCheckModeIndexForCRT2Type(ScrnInfoPtr pScrn, unsigned short cond, unsigned sh } /* Check if the desired mode is suitable for current CRT2 output device */ - if(!SiS_CheckCalcModeIndex(pScrn, mode, vbflags, hcm)) { + if(SiS_CheckModeCRT2(pScrn, mode, vbflags, hcm) < 0x14) { if((!cond) && (!quiet)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Desired mode not suitable for current CRT2 output device\n"); @@ -7876,7 +7928,7 @@ SISCheckModeIndexForCRT2Type(ScrnInfoPtr pScrn, unsigned short cond, unsigned sh } /* Check if the desired mode is suitable for current CRT1 output device */ - if(!SiS_CalcModeIndex(pScrn, mode, vbflags, hcm)) { + if(SiS_CheckModeCRT1(pScrn, mode, vbflags, hcm) < 0x14) { if((!cond) && (!quiet)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Desired mode not suitable for current CRT1 output device\n"); @@ -7913,9 +7965,6 @@ SISRedetectCRT2Devices(ScrnInfoPtr pScrn) } } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Redetection of CRT2 devices initiated...\n"); - if(SISRedetectCRT2Type(pScrn)) { /* If this returns TRUE, we need to reset the display mode */ /* Sync the accelerators */ @@ -7924,12 +7973,14 @@ SISRedetectCRT2Devices(ScrnInfoPtr pScrn) (*pSiS->AccelInfoPtr->Sync)(pScrn); } } - if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE; + pSiS->skipswitchcheck = TRUE; + if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) { + pSiS->skipswitchcheck = FALSE; + return FALSE; + } + pSiS->skipswitchcheck = FALSE; SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Redetection of CRT2 devices finished\n"); return TRUE; } @@ -7943,7 +7994,9 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) int crt1off; /* onoff: 0=OFF, 1=ON(VGA), 2=ON(LCDA) */ + /* Switching to LCDA will disable CRT2 if previously LCD or VGA */ + /* For usability reasons, the user should not simply "lose" one * of his output devices in MergedFB mode. Therefore, a switch * which might lead to this situation will not be performed in @@ -7968,7 +8021,7 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) if(pSiS->DualHeadMode) return FALSE; #endif - /* Can't switch to LCDA of not supported (duh!) */ + /* Can't switch to LCDA if not supported (duh!) */ if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTLCDA)) { if(onoff == 2) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -8013,11 +8066,11 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) } if(vbflags & CRT1_LCDA) { - if(!SiS_CalcModeIndex(pScrn, mode, vbflags, pSiS->HaveCustomModes)) { + if(SiS_CheckModeCRT1(pScrn, mode, vbflags, pSiS->HaveCustomModes) < 0x14) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Current mode not suitable for LCD-via-CRT1\n"); return FALSE; - } + } } pSiS->CRT1off = crt1off; @@ -8030,7 +8083,12 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) } } - if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE; + pSiS->skipswitchcheck = TRUE; + if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) { + pSiS->skipswitchcheck = FALSE; + return FALSE; + } + pSiS->skipswitchcheck = FALSE; SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); return TRUE; } @@ -8708,10 +8766,10 @@ SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { if(pSiS->SecondHead) { - if(SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) + if(SiS_CheckModeCRT1(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) return(MODE_BAD); } else { - if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) + if(SiS_CheckModeCRT2(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) return(MODE_BAD); } } else @@ -8720,30 +8778,28 @@ SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) if(pSiS->MergedFB) { if(!mode->Private) { if(!pSiS->CheckForCRT2) { - if(SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) + if(SiS_CheckModeCRT1(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) return(MODE_BAD); } else { - if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes2) < 0x14) + if(SiS_CheckModeCRT2(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes2) < 0x14) return(MODE_BAD); } } else { - if(SiS_CalcModeIndex(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT1, + if(SiS_CheckModeCRT1(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT1, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) return(MODE_BAD); - if(SiS_CheckCalcModeIndex(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT2, + if(SiS_CheckModeCRT2(pScrn, ((SiSMergedDisplayModePtr)mode->Private)->CRT2, pSiS->VBFlags, pSiS->HaveCustomModes2) < 0x14) return(MODE_BAD); } } else #endif - { + { + if(SiS_CheckModeCRT1(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) + return(MODE_BAD); - if(pSiS->VBFlags & CRT1_LCDA) { - if(SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) - return(MODE_BAD); - } - if(SiS_CheckCalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) + if(SiS_CheckModeCRT2(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes) < 0x14) return(MODE_BAD); } } @@ -8772,7 +8828,7 @@ SISSaveScreen(ScreenPtr pScreen, int mode) if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) { + if(pSiS->VBFlags & VB_SISLVDSBRIDGE) { if(!xf86IsUnblank(mode)) { pSiS->Blank = TRUE; SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -8816,7 +8872,7 @@ SISSaveScreen(ScreenPtr pScreen, int mode) pSiS->Blank = FALSE; outSISIDXREG(SISSR, 0x11, pSiS->LCDon); } - } else if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) { + } else if(pSiS->VBFlags & VB_SISLVDSBRIDGE) { if(!xf86IsUnblank(mode)) { pSiS->Blank = TRUE; SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -8847,7 +8903,7 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) SISPtr pSiS = SISPTR(pScrn); - if((pSiS->SecondHead) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C))) { + if((pSiS->SecondHead) && ((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_SISTMDSLCDABRIDGE))) { /* Slave head is always CRT1 */ if(pSiS->VBFlags & CRT1_LCDA) pSiS->Blank = xf86IsUnblank(mode) ? FALSE : TRUE; @@ -8869,7 +8925,7 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) if(pSiS->VGAEngine == SIS_300_VGA) { - if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) { + if(pSiS->VBFlags & VB_SISLVDSBRIDGE) { checkit = TRUE; if(!xf86IsUnblank(mode)) { SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -8909,7 +8965,7 @@ SISSaveScreenDH(ScreenPtr pScreen, int mode) } else { outSISIDXREG(SISSR, 0x11, pSiS->LCDon); } - } else if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) { + } else if(pSiS->VBFlags & VB_SISLVDSBRIDGE) { checkit = TRUE; if(!xf86IsUnblank(mode)) { SiS_SiS30xBLOff(pSiS->SiS_Pr,&pSiS->sishw_ext); @@ -8975,7 +9031,7 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) unsigned short SR26, SR27; unsigned long temp; - switch (pSiS->VGAEngine) { + switch(pSiS->VGAEngine) { case SIS_300_VGA: if((!pSiS->NoAccel) && (pSiS->TurboQueue)) { /* TQ size is always 512k */ @@ -9026,10 +9082,8 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) /* Set Command Queue Threshold to max value 11111b (?) */ outSISIDXREG(SISSR, 0x27, 0x1F); /* Disable queue flipping */ - if(pSiS->sishw_ext.jChipType <= SIS_330) { - inSISIDXREG(SISCR, 0x55, tempCR55) ; - andSISIDXREG(SISCR, 0x55, 0x33) ; - } + inSISIDXREG(SISCR, 0x55, tempCR55) ; + andSISIDXREG(SISCR, 0x55, 0x33) ; /* Syncronous reset for Command Queue */ outSISIDXREG(SISSR, 0x26, 0x01); MMIO_OUT32(pSiS->IOBase, 0x85c4, 0); @@ -9058,9 +9112,7 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) #endif temp += pSiS->cmdQueueOffset; pSiS->cmdQueueBase = (unsigned long *)temp; - if(pSiS->sishw_ext.jChipType <= SIS_330) { - outSISIDXREG(SISCR, 0x55, tempCR55); - } + outSISIDXREG(SISCR, 0x55, tempCR55); #else /* For MMIO */ /* Set Command Queue Threshold to max value 11111b */ @@ -9097,132 +9149,49 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) unsigned char CR39 = 0, CR3B = 0; unsigned char CR17, CR38 = 0; unsigned char CR35 = 0, CR79 = 0; - unsigned long vbflag; - int temp = 0, i; - int crt1rateindex = 0; - DisplayModePtr mymode; -#ifdef SISMERGED - DisplayModePtr mymode2 = NULL; -#endif - -#ifdef SISMERGED - if(pSiS->MergedFB) { - mymode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1; - mymode2 = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; - } else -#endif - mymode = mode; - - vbflag = pSiS->VBFlags; + int temp = 0, crt1rateindex = 0; + unsigned long vbflag = pSiS->VBFlags; + DisplayModePtr mymode = mode; + BOOLEAN hcm = pSiS->HaveCustomModes; + pSiS->IsCustom = FALSE; + + /* NEVER call this with viewmode = SIS_MODE_SIMU + * if mode->type is not M_T_DEFAULT! + */ + #ifdef SISMERGED - pSiS->IsCustomCRT2 = FALSE; - if(pSiS->MergedFB) { - /* CRT2 */ - if(vbflag & CRT2_LCD) { - if(pSiS->SiS_Pr->CP_HaveCustomData) { - for(i=0; i<7; i++) { - if(pSiS->SiS_Pr->CP_DataValid[i]) { - if((mymode2->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) && - (mymode2->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) { - if(mymode2->type & M_T_BUILTIN) { - pSiS->IsCustomCRT2 = TRUE; - } - } - } - } - } - } - if(vbflag & (CRT2_VGA|CRT2_LCD)) { - if(pSiS->AddedPlasmaModes) { - if(mymode2->type & M_T_BUILTIN) { - pSiS->IsCustomCRT2 = TRUE; - } - } - if(pSiS->HaveCustomModes2) { - if(!(mymode2->type & M_T_DEFAULT)) { - pSiS->IsCustomCRT2 = TRUE; - } - } - } - /* CRT1 */ - if(pSiS->HaveCustomModes) { - if(!(mymode->type & M_T_DEFAULT)) { - pSiS->IsCustom = TRUE; - } - } - } else -#endif -#ifdef SISDUALHEAD - if(pSiS->DualHeadMode) { - if(!pSiS->SecondHead) { - /* CRT2 */ - if(vbflag & CRT2_LCD) { - if(pSiS->SiS_Pr->CP_HaveCustomData) { - for(i=0; i<7; i++) { - if(pSiS->SiS_Pr->CP_DataValid[i]) { - if((mymode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) && - (mymode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) { - if(mymode->type & M_T_BUILTIN) { - pSiS->IsCustom = TRUE; - } - } - } - } - } - } - if(vbflag & (CRT2_VGA|CRT2_LCD)) { - if(pSiS->AddedPlasmaModes) { - if(mymode->type & M_T_BUILTIN) { - pSiS->IsCustom = TRUE; - } - } - if(pSiS->HaveCustomModes) { - if(!(mymode->type & M_T_DEFAULT)) { - pSiS->IsCustom = TRUE; - } - } - } - } else { - /* CRT1 */ - if(pSiS->HaveCustomModes) { - if(!(mymode->type & M_T_DEFAULT)) { - pSiS->IsCustom = TRUE; - } - } + switch(viewmode) { + case SIS_MODE_CRT1: + mymode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1; + break; + case SIS_MODE_CRT2: + mymode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; + hcm = pSiS->HaveCustomModes2; } - } else + } #endif - { - if(vbflag & CRT2_LCD) { - if(pSiS->SiS_Pr->CP_HaveCustomData) { - for(i=0; i<7; i++) { - if(pSiS->SiS_Pr->CP_DataValid[i]) { - if((mymode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[i]) && - (mymode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[i])) { - if(mymode->type & M_T_BUILTIN) { - pSiS->IsCustom = TRUE; - } - } - } - } - } - } - if(vbflag & (CRT2_LCD|CRT2_VGA)) { - if(pSiS->AddedPlasmaModes) { - if(mymode->type & M_T_BUILTIN) { - pSiS->IsCustom = TRUE; - } - } + + switch(viewmode) { + case SIS_MODE_CRT1: + if(SiS_CheckModeCRT1(pScrn, mymode, vbflag, hcm) == 0xfe) { + pSiS->IsCustom = TRUE; } - if((pSiS->HaveCustomModes) && (!(vbflag & CRT2_TV))) { - if(!(mymode->type & M_T_DEFAULT)) { + break; + case SIS_MODE_CRT2: + if(vbflag & CRT2_ENABLE) { + if(SiS_CheckModeCRT2(pScrn, mymode, vbflag, hcm) == 0xfe) { pSiS->IsCustom = TRUE; + } + } else { + /* This can only happen in mirror mode */ + if(SiS_CheckModeCRT1(pScrn, mymode, vbflag, hcm) == 0xfe) { + pSiS->IsCustom = TRUE; } } } - + #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); /* Unlock Registers */ #endif @@ -9241,6 +9210,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4, "Before: CR30=0x%02x,CR31=0x%02x,CR32=0x%02x,CR33=0x%02x,CR35=0x%02x,CR38=0x%02x\n", CR30, CR31, CR32, CR33, CR35, CR38); + CR38 &= ~0x07; } else { @@ -9257,6 +9227,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) CR38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */ } inSISIDXREG(SISCR, 0x3b, CR3B); + xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4, "Before: CR30=0x%02x, CR31=0x%02x, CR32=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n", CR30, CR31, CR32, CR33, temp, CR38); @@ -9307,7 +9278,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) } else { CR30 |= 0x80; if(pSiS->VGAEngine == SIS_315_VGA) { - if(vbflag & (VB_301LV | VB_302LV | VB_301C)) { + if(vbflag & VB_SISYPBPRBRIDGE) { CR38 |= (0x08 | 0x30); } } @@ -9433,11 +9404,6 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) } } - /* for VESA: no DRIVERMODE, otherwise - * -) CRT2 will not be initialized correctly when using mode - * where LCD has to scale, and - * -) CRT1 will have too low rate - */ if(pSiS->UseVESA) { CR31 &= ~0x40; /* Clear Drivermode */ CR31 |= 0x06; /* Set SlaveMode, Enable SimuMode in Slavemode */ @@ -9450,54 +9416,37 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) CR31 &= ~0x06; /* Disable SlaveMode, disable SimuMode in SlaveMode */ if(!pSiS->IsCustom) { crt1rateindex = SISSearchCRT1Rate(pScrn, mymode); - } else { - crt1rateindex = CR33; - } + } } -#ifdef SISDUALHEAD - if(pSiS->DualHeadMode) { - if(pSiS->SecondHead) { - /* CRT1 */ - CR33 &= 0xf0; - if(!(vbflag & CRT1_LCDA)) { - CR33 |= (crt1rateindex & 0x0f); - } - } else { - /* CRT2 */ - CR33 &= 0x0f; - if(vbflag & CRT2_VGA) { - CR33 |= ((crt1rateindex << 4) & 0xf0); - } - } - } else -#endif -#ifdef SISMERGED - if(pSiS->MergedFB) { - CR33 = 0; - if(!(vbflag & CRT1_LCDA)) { - CR33 |= (crt1rateindex & 0x0f); - } - if(vbflag & CRT2_VGA) { - if(!pSiS->IsCustomCRT2) { - CR33 |= (SISSearchCRT1Rate(pScrn, mymode2) << 4); + switch(viewmode) { + case SIS_MODE_SIMU: + CR33 = 0; + if(!(vbflag & CRT1_LCDA)) { + CR33 |= (crt1rateindex & 0x0f); } - } - } else -#endif - { - CR33 = 0; - if(!(vbflag & CRT1_LCDA)) { - CR33 |= (crt1rateindex & 0x0f); - } - if(vbflag & CRT2_VGA) { - CR33 |= ((crt1rateindex & 0x0f) << 4); - } - if((!(pSiS->UseVESA)) && (vbflag & CRT2_ENABLE)) { - if(pSiS->CRT1off) CR33 &= 0xf0; - } + if(vbflag & CRT2_VGA) { + CR33 |= ((crt1rateindex & 0x0f) << 4); + } + break; + case SIS_MODE_CRT1: + CR33 &= 0xf0; + if(!(vbflag & CRT1_LCDA)) { + CR33 |= (crt1rateindex & 0x0f); + } + break; + case SIS_MODE_CRT2: + CR33 &= 0x0f; + if(vbflag & CRT2_VGA) { + CR33 |= ((crt1rateindex & 0x0f) << 4); + } + break; } - + + if((!pSiS->UseVESA) && (vbflag & CRT2_ENABLE)) { + if(pSiS->CRT1off) CR33 &= 0xf0; + } + if(pSiS->NewCRLayout) { CR31 &= 0xfe; /* Clear PAL flag (now in CR35) */ @@ -9508,6 +9457,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) outSISIDXREG(SISCR, 0x35, CR35); setSISIDXREG(SISCR, 0x38, 0xf8, CR38); outSISIDXREG(SISCR, 0x39, CR39); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR35=0x%02x,CR38=%02x\n", CR30, CR31, CR33, CR35, CR38); @@ -9524,6 +9474,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) outSISIDXREG(SISCR, 0x3b, CR3B); outSISIDXREG(SISCR, 0x79, CR79); } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n", CR30, CR31, CR33, temp, CR38); @@ -11128,7 +11079,7 @@ void SiS_SetTVyscale(ScrnInfoPtr pScrn, int val) } #endif SISWaitRetraceCRT2(pScrn); - if(pSiS->VBFlags & (VB_301C|VB_302ELV)) { + if(pSiS->VBFlags & VB_SISTAP4SCALER) { for(i=0; i<64; i++) { outSISIDXREG(SISPART2,(0xc0 + i),p2scaling[i]); } @@ -11172,7 +11123,7 @@ void SiS_SetTVyscale(ScrnInfoPtr pScrn, int val) SISWaitRetraceCRT2(pScrn); - if(pSiS->VBFlags & (VB_301C|VB_302ELV)) { + if(pSiS->VBFlags & VB_SISTAP4SCALER) { #ifdef TWDEBUG xf86DrvMsg(0, X_INFO, "301C scaler: Table index %d\n", srindex301c); #endif @@ -11621,7 +11572,7 @@ SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) for(i=0; i<9; i++) { inSISIDXREG(SISPART4,SiSScalingP4Regs[i],pSiS->scalingp4[i]); } - if(pSiS->VBFlags & (VB_301C | VB_302ELV)) { + if(pSiS->VBFlags & VB_SISTAP4SCALER) { for(i=0; i<64; i++) { inSISIDXREG(SISPART2,(0xc0 + i),pSiS->scalingp2[i]); } @@ -11646,7 +11597,7 @@ SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) for(i=0; i<9; i++) { pSiSEnt->scalingp4[i] = pSiS->scalingp4[i]; } - if(pSiS->VBFlags & (VB_301C | VB_302ELV)) { + if(pSiS->VBFlags & VB_SISTAP4SCALER) { for(i=0; i<64; i++) { pSiSEnt->scalingp2[i] = pSiS->scalingp2[i]; } @@ -11888,28 +11839,112 @@ SiSCalcVESAModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode) } USHORT -SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN havecustommodes) +SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags) +{ + SISPtr pSiS = SISPTR(pScrn); + UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; + + return(SiS_GetModeID(pSiS->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay, + i, pSiS->FSTN, pSiS->LCDwidth, pSiS->LCDheight)); +} + +static BOOLEAN +SiSValidLCDUserMode(SISPtr pSiS, unsigned long VBFlags, DisplayModePtr mode, BOOLEAN isforlcda) +{ + if(mode->Flags & V_INTERLACE) return FALSE; + + if(mode->HDisplay > 2048) return FALSE; + if(mode->VDisplay > 1536) return FALSE; + + if(VBFlags & VB_301C) { + if(mode->Clock > 162500) return FALSE; +#ifdef VB_FORBID_CRT2LCD_OVER_1600 + if(!isforlcda) { + if(mode->HDisplay > 1600) return FALSE; + } +#endif + } else { /* 301, 301B, 302B (no LCDA!) */ + if(mode->Clock > 108500) return FALSE; + if(mode->HDisplay > 1600) return FALSE; + if(mode->VDisplay > 1024) return FALSE; + } + + return TRUE; +} + +static BOOLEAN +SiSValidVGA2UserMode(SISPtr pSiS, unsigned long VBFlags, DisplayModePtr mode) +{ + if(mode->Flags & V_INTERLACE) return FALSE; + + if(mode->HDisplay > 2048) return FALSE; + if(mode->VDisplay > 1536) return FALSE; + + if(VBFlags & VB_301C) { + if(mode->Clock > 203000) return FALSE; + } else if(VBFlags & (VB_301B|VB_302B)) { + if(mode->Clock > 162500) return FALSE; + } else { + if(mode->Clock > 135500) return FALSE; + } + + return TRUE; +} + +static USHORT +SiS_CheckModeCRT1(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN havecustommodes) { SISPtr pSiS = SISPTR(pScrn); UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; + int j; if(!(VBFlags & CRT1_LCDA)) { + if((havecustommodes) && (!(mode->type & M_T_DEFAULT))) { return 0xfe; } + + } else if(VBFlags & VB_SISTMDSLCDABRIDGE) { + + if(pSiS->SiS_Pr->CP_HaveCustomData) { + for(j=0; j<7; j++) { + if((pSiS->SiS_Pr->CP_DataValid[j]) && + (mode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[j]) && + (mode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[j]) && + (mode->type & M_T_BUILTIN)) + return 0xfe; + } + } + + if((pSiS->AddedPlasmaModes) && (mode->type & M_T_BUILTIN)) + return 0xfe; + + if((havecustommodes) && + (pSiS->LCDwidth) && /* = test if LCD present */ + (!(mode->type & M_T_DEFAULT)) && + (SiSValidLCDUserMode(pSiS, VBFlags, mode, TRUE))) + return 0xfe; + + if((mode->HDisplay > pSiS->LCDwidth) || + (mode->VDisplay > pSiS->LCDheight)) { + return 0; + } + } else { + if((mode->HDisplay > pSiS->LCDwidth) || (mode->VDisplay > pSiS->LCDheight)) { return 0; } + } return(SiS_GetModeID(pSiS->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay, i, pSiS->FSTN, pSiS->LCDwidth, pSiS->LCDheight)); } -USHORT -SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN havecustommodes) +static USHORT +SiS_CheckModeCRT2(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags, BOOLEAN havecustommodes) { SISPtr pSiS = SISPTR(pScrn); UShort i = (pSiS->CurrentLayout.bitsPerPixel+7)/8 - 1; @@ -11923,24 +11958,32 @@ SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBF if(VBFlags & CRT2_LCD) { /* CRT2 is LCD */ - if(pSiS->SiS_Pr->CP_HaveCustomData) { - for(j=0; j<7; j++) { - if((pSiS->SiS_Pr->CP_DataValid[j]) && - (mode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[j]) && - (mode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[j]) && - (mode->type & M_T_BUILTIN)) - return 0xfe; - } - } - - if((pSiS->AddedPlasmaModes) && (mode->type & M_T_BUILTIN)) - return 0xfe; + if((VBFlags & VB_SISTMDSBRIDGE) && (!(VBFlags & VB_30xBDH))) { + + if(pSiS->SiS_Pr->CP_HaveCustomData) { + for(j=0; j<7; j++) { + if((pSiS->SiS_Pr->CP_DataValid[j]) && + (mode->HDisplay == pSiS->SiS_Pr->CP_HDisplay[j]) && + (mode->VDisplay == pSiS->SiS_Pr->CP_VDisplay[j]) && +#ifdef VB_FORBID_CRT2LCD_OVER_1600 + (mode->HDisplay <= 1600) && +#endif + (mode->type & M_T_BUILTIN)) + return 0xfe; + } + } - if((havecustommodes) && - (pSiS->LCDwidth) && /* = test if LCD present */ - (!(mode->type & M_T_DEFAULT)) && - (!(mode->Flags & V_INTERLACE))) - return 0xfe; + /* All plasma modes have HDisplay <= 1600 */ + if((pSiS->AddedPlasmaModes) && (mode->type & M_T_BUILTIN)) + return 0xfe; + + if((havecustommodes) && + (pSiS->LCDwidth) && /* = test if LCD present */ + (!(mode->type & M_T_DEFAULT)) && + (SiSValidLCDUserMode(pSiS, VBFlags, mode, FALSE))) + return 0xfe; + + } if( ((mode->HDisplay <= pSiS->LCDwidth) && (mode->VDisplay <= pSiS->LCDheight)) || @@ -11965,14 +12008,15 @@ SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBF if((havecustommodes) && (!(mode->type & M_T_DEFAULT)) && - (!(mode->Flags & V_INTERLACE))) + (SiSValidVGA2UserMode(pSiS, VBFlags, mode))) return 0xfe; ModeIndex = SiS_GetModeID_VGA2(pSiS->VGAEngine, VBFlags, mode->HDisplay, mode->VDisplay, i); - } else { /* CRT1 only, no CRT2 */ + } else { /* no CRT2 */ - ModeIndex = SiS_CalcModeIndex(pScrn, mode, VBFlags, havecustommodes); + /* Return a valid mode number */ + ModeIndex = 0xfe; } diff --git a/src/sis_driver.h b/src/sis_driver.h index 9a07d4c..594daa9 100644 --- a/src/sis_driver.h +++ b/src/sis_driver.h @@ -1309,14 +1309,15 @@ static void SISWaitVBRetrace(ScrnInfoPtr pScrn); void SISWaitRetraceCRT1(ScrnInfoPtr pScrn); void SISWaitRetraceCRT2(ScrnInfoPtr pScrn); static Bool InRegion(int x, int y, region r); +static USHORT SiS_CheckModeCRT1(ScrnInfoPtr pScrn, DisplayModePtr mode, + unsigned long VBFlags, BOOLEAN hcm); +static USHORT SiS_CheckModeCRT2(ScrnInfoPtr pScrn, DisplayModePtr mode, + unsigned long VBFlags, BOOLEAN hcm); #ifdef SISMERGED static void SISMergePointerMoved(int scrnIndex, int x, int y); #endif BOOLEAN SiSBridgeIsInSlaveMode(ScrnInfoPtr pScrn); -USHORT SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, - unsigned long VBFlags, BOOLEAN hcm); -USHORT SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, - unsigned long VBFlags, BOOLEAN hcm); +USHORT SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags); unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value); #ifdef DEBUG static void SiSDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode); diff --git a/src/sis_vb.c b/src/sis_vb.c index 5f90c03..7e4de7f 100644 --- a/src/sis_vb.c +++ b/src/sis_vb.c @@ -302,11 +302,11 @@ void SISLCDPreInit(ScrnInfoPtr pScrn, Bool quiet) */ #ifdef SISDUALHEAD if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) { -#endif +#endif if((pSiS->VGAEngine == SIS_315_VGA) && - (pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && + (pSiS->VBFlags & VB_SISTMDSBRIDGE) && (!(pSiS->VBFlags & VB_30xBDH)) && - (!pSiS->VESA)) { + (pSiS->VESA != 1)) { if(pSiS->forcecrt2redetection) { pSiS->VBFlags &= ~CRT2_LCD; @@ -390,13 +390,13 @@ void SISLCDPreInit(ScrnInfoPtr pScrn, Bool quiet) inSISIDXREG(SISCR,0x37,CR37); } } - if(((CR36 & 0x0f) == 0x0f) && (pSiS->SiS_Pr->CP_HaveCustomData)) { + if((CR36 & 0x0f) == 0x0f) { pSiS->VBLCDFlags |= VB_LCD_CUSTOM; pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY; pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX; if(CR37 & 0x10) pSiS->VBLCDFlags |= VB_LCD_EXPANDING; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected LCD/Plasma panel (max. X %d Y %d, preferred %dx%d, RGB%d)\n", + "Detected LCD/Plasma panel (max. X %d Y %d, pref. %dx%d, RGB%d)\n", pSiS->SiS_Pr->CP_MaxX, pSiS->SiS_Pr->CP_MaxY, pSiS->SiS_Pr->CP_PreferredX, pSiS->SiS_Pr->CP_PreferredY, (CR37 & 0x01) ? 18 : 24); @@ -603,7 +603,7 @@ void SISCRT2PreInit(ScrnInfoPtr pScrn, Bool quiet) unsigned char CR32; /* CRT2-VGA only supported on these bridges */ - if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) + if(!(pSiS->VBFlags & VB_SISVGA2BRIDGE)) return; inSISIDXREG(SISCR, 0x32, CR32); @@ -768,7 +768,7 @@ SISSense30x(ScrnInfoPtr pScrn, Bool quiet) } } - if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) { + if(!(pSiS->VBFlags & VB_SISVGA2BRIDGE)) { vga2 = vga2_c = 0; } @@ -787,7 +787,7 @@ SISSense30x(ScrnInfoPtr pScrn, Bool quiet) outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc)); inSISIDXREG(SISPART2,0x4d,backupP2_4d); - if(pSiS->VBFlags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV)) { + if(pSiS->VBFlags & VB_SISYPBPRBRIDGE) { outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10)); } @@ -828,7 +828,7 @@ SISSense30x(ScrnInfoPtr pScrn, Bool quiet) orSISIDXREG(SISPART4,0x0d,0x04); } - if((pSiS->VGAEngine == SIS_315_VGA) && (pSiS->VBFlags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) { + if((pSiS->VGAEngine == SIS_315_VGA) && (pSiS->VBFlags & VB_SISYPBPRBRIDGE)) { if(pSiS->SenseYPbPr) { outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10)); SiS_DDC2Delay(pSiS->SiS_Pr, 0x2000); @@ -1052,16 +1052,16 @@ Bool SISRedetectCRT2Type(ScrnInfoPtr pScrn) * there is no way of detecting this). */ if((pSiS->VGAEngine == SIS_315_VGA) && - (pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) && + (pSiS->VBFlags & VB_SISTMDSBRIDGE) && (!(pSiS->VBFlags & VB_30xBDH)) && - (!pSiS->VESA)) { + (pSiS->VESA != 1)) { SISLCDPreInit(pScrn, TRUE); } else { pSiS->VBFlags |= (pSiS->detectedCRT2Devices & CRT2_LCD); } /* Secondary VGA is only supported on these bridges: */ - if(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) { + if(pSiS->VBFlags & VB_SISVGA2BRIDGE) { SISCRT2PreInit(pScrn, TRUE); } @@ -1088,6 +1088,8 @@ Bool SISRedetectCRT2Type(ScrnInfoPtr pScrn) pSiS->VBFlags_backup = pSiS->VBFlags; } + pSiS->VBFlagsInit = pSiS->VBFlags; + /* Save new detection result registers to write them back in EnterVT() */ inSISIDXREG(SISCR,0x32,pSiS->myCR32); inSISIDXREG(SISCR,0x36,pSiS->myCR36); diff --git a/src/sis_video.c b/src/sis_video.c index 35741fc..8bd6abb 100644 --- a/src/sis_video.c +++ b/src/sis_video.c @@ -4713,6 +4713,7 @@ SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet) SiSWritePacketPart(packet[12], packet[13], packet[14], packet[15]); SiSWritePacketPart(packet[16], packet[17], packet[18], packet[19]); SiSSyncWP; + (void)dummybuf; /* Suppress compiler warning */ } static int |