diff options
Diffstat (limited to 'src/sis_dac.c')
-rw-r--r-- | src/sis_dac.c | 1825 |
1 files changed, 831 insertions, 994 deletions
diff --git a/src/sis_dac.c b/src/sis_dac.c index 0ce8e74..6a429e7 100644 --- a/src/sis_dac.c +++ b/src/sis_dac.c @@ -1,7 +1,9 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c,v 1.30 2003/02/05 17:53:22 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c,v 1.49 2003/11/19 21:27:41 twini Exp $ */ /* - * Copyright 1998,1999 by Alan Hourihane, Wigan, England. - * Parts Copyright 2001, 2002 by Thomas Winischhofer, Vienna, Austria. + * DAC helper functions (Save/Restore, MemClk, etc) + * + * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. + * Parts Copyright 1998,1999 by Alan Hourihane, Wigan, England. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -21,12 +23,14 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk> - * Mike Chapman <mike@paranoia.com>, - * Juanjo Santamarta <santamarta@ctv.es>, - * Mitani Hiroshi <hmitani@drl.mei.co.jp> - * David Thomas <davtom@dream.org.uk>. - * Thomas Winischhofer <thomas@winischhofer.net> + * Author: Thomas Winischhofer <thomas@winischhofer.net> + * + * MemClock functions by: + * Alan Hourihane <alanh@fairlite.demon.co.uk> + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. */ #include "xf86.h" @@ -46,23 +50,18 @@ static void SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg); -static void SiS310Save(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiS301Save(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiS301BSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg); -static void SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg); +static void SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); static void SiS301LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual); -static void SiSThreshold(ScrnInfoPtr pScrn, DisplayModePtr mode, - unsigned short *Low, unsigned short *High); static void SetBlock(CARD16 port, CARD8 from, CARD8 to, CARD8 *DataPtr); -#if 0 -Bool SiSI2CInit(ScrnInfoPtr pScrn); -#endif static const unsigned short ch700xidx[] = { 0x00,0x07,0x08,0x0a,0x0b,0x04,0x09,0x20,0x21,0x18,0x19,0x1a, @@ -73,8 +72,8 @@ static const unsigned short ch700xidx[] = { static const unsigned short ch701xidx[] = { 0x1c,0x5f,0x64,0x6f,0x70,0x71,0x72,0x73,0x74,0x76,0x78,0x7d, 0x67,0x68,0x69,0x6a,0x6b,0x1e,0x00,0x01,0x02,0x04,0x03,0x05, - 0x06,0x07,0x08,0x15,0x1f,0x0c,0x0d,0x0e,0x0f,0x10 - }; + 0x06,0x07,0x08,0x15,0x1f,0x0c,0x0d,0x0e,0x0f,0x10,0x66 + }; int SiS_compute_vclk( int Clock, @@ -122,54 +121,55 @@ int SiS_compute_vclk( * * ** this function can select VCLK ranged from 18.75 to 250 Mhz */ + f = (float) Clock; f /= 1000.0; - if ((f > 250.0) || (f < 18.75)) - return 0; + if((f > 250.0) || (f < 18.75)) + return 0; min_error = f; y = 1.0; x = f; - while (x > 31.25) { - y *= 2.0; - x /= 2.0; + while(x > 31.25) { + y *= 2.0; + x /= 2.0; } - if (x >= 18.25) { - x *= 8.0; - y = 8.0 / y; - } else if (x >= 15.625) { - x *= 12.0; - y = 12.0 / y; + if(x >= 18.25) { + x *= 8.0; + y = 8.0 / y; + } else if(x >= 15.625) { + x *= 12.0; + y = 12.0 / y; } t = y; - if (t == (float) 1.5) { - *out_div = 2; - t *= 2.0; + if(t == (float) 1.5) { + *out_div = 2; + t *= 2.0; } else { - *out_div = 1; + *out_div = 1; } - if (t > (float) 4.0) { - *out_sbit = 1; - t /= 2.0; + if(t > (float) 4.0) { + *out_sbit = 1; + t /= 2.0; } else { - *out_sbit = 0; + *out_sbit = 0; } *out_scale = (int) t; - for (dn=2;dn<=32;dn++) { - for (n=1;n<=128;n++) { - error = x; - error -= ((float) 14.318 * (float) n / (float) dn); - if (error < (float) 0) - error = -error; - if (error < min_error) { - min_error = error; - best_n = n; - best_dn = dn; - } - } + for(dn = 2; dn <= 32; dn++) { + for(n = 1; n <= 128; n++) { + error = x; + error -= ((float) 14.318 * (float) n / (float) dn); + if(error < (float) 0) + error = -error; + if(error < min_error) { + min_error = error; + best_n = n; + best_dn = dn; + } + } } *out_n = best_n; *out_dn = best_dn; @@ -186,15 +186,18 @@ SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk) SISPtr pSiS = SISPTR(pScrn); int M, N, P , PSN, VLD , PSNx ; int bestM=0, bestN=0, bestP=0, bestPSN=0, bestVLD=0; - double bestError, abest = 42.0, bestFout; + double abest = 42.0; double target; double Fvco, Fout; double error, aerror; +#ifdef DEBUG + double bestFout; +#endif /* * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler) * - * M = Numerator [1:128] + * M = Numerator [1:128] * N = DeNumerator [1:32] * VLD = Divider (Vco Loop Divider) : divide by 1, 2 * P = Post Scaler : divide by 1, 2, 3, 4 @@ -216,142 +219,138 @@ SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk) #define MAX_PSN 0 /* no pre scaler for this chip */ #define TOLERANCE 0.01 /* search smallest M and N in this tolerance */ - int M_min = 2; + int M_min = 2; int M_max = 128; - -/* abest=10000.0; */ - + target = clock * 1000; - - if (pSiS->Chipset == PCI_CHIP_SIS5597 || pSiS->Chipset == PCI_CHIP_SIS6326){ - int low_N = 2; - int high_N = 5; - - PSN = 1; - P = 1; - if (target < MAX_VCO_5597 / 2) - P = 2; - if (target < MAX_VCO_5597 / 3) - P = 3; - if (target < MAX_VCO_5597 / 4) - P = 4; - if (target < MAX_VCO_5597 / 6) - P = 6; - if (target < MAX_VCO_5597 / 8) - P = 8; - - Fvco = P * target; - - for (N = low_N; N <= high_N; N++){ - double M_desired = Fvco / Fref * N; - if (M_desired > M_max * max_VLD) - continue; - - if ( M_desired > M_max ) { - M = M_desired / 2 + 0.5; - VLD = 2; - } else { - M = Fvco / Fref * N + 0.5; - VLD = 1; - } - - Fout = (double)Fref * (M * VLD)/(N * P); - - error = (target - Fout) / target; - aerror = (error < 0) ? -error : error; -/* if (aerror < abest && abest > TOLERANCE) */ - if (aerror < abest) { - abest = aerror; - bestError = error; - bestM = M; - bestN = N; - bestP = P; - bestPSN = PSN; - bestVLD = VLD; - bestFout = Fout; - } - } + + if(pSiS->Chipset == PCI_CHIP_SIS5597 || pSiS->Chipset == PCI_CHIP_SIS6326) { + + int low_N = 2; + int high_N = 5; + + PSN = 1; + P = 1; + if(target < MAX_VCO_5597 / 2) P = 2; + if(target < MAX_VCO_5597 / 3) P = 3; + if(target < MAX_VCO_5597 / 4) P = 4; + if(target < MAX_VCO_5597 / 6) P = 6; + if(target < MAX_VCO_5597 / 8) P = 8; + + Fvco = P * target; + + for(N = low_N; N <= high_N; N++) { + + double M_desired = Fvco / Fref * N; + if(M_desired > M_max * max_VLD) continue; + + if(M_desired > M_max) { + M = M_desired / 2 + 0.5; + VLD = 2; + } else { + M = Fvco / Fref * N + 0.5; + VLD = 1; + } + + Fout = (double)Fref * (M * VLD)/(N * P); + + error = (target - Fout) / target; + aerror = (error < 0) ? -error : error; + if(aerror < abest) { + abest = aerror; + bestM = M; + bestN = N; + bestP = P; + bestPSN = PSN; + bestVLD = VLD; +#ifdef DEBUG + bestFout = Fout; +#endif + } } - else { - for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { - int low_N, high_N; - double FrefVLDPSN; - - PSN = !PSNx ? 1 : 4; - - low_N = 2; - high_N = 32; - - for ( VLD = 1 ; VLD <= max_VLD ; VLD++ ) { - - FrefVLDPSN = (double)Fref * VLD / PSN; - for (N = low_N; N <= high_N; N++) { - double tmp = FrefVLDPSN / N; - - for (P = 1; P <= 4; P++) { - double Fvco_desired = target * ( P ); - double M_desired = Fvco_desired / tmp; - - /* Which way will M_desired be rounded? - * Do all three just to be safe. - */ - int M_low = M_desired - 1; - int M_hi = M_desired + 1; - - if (M_hi < M_min || M_low > M_max) - continue; - - if (M_low < M_min) - M_low = M_min; - if (M_hi > M_max) - M_hi = M_max; - - for (M = M_low; M <= M_hi; M++) { - Fvco = tmp * M; - if (Fvco <= MIN_VCO) - continue; - if (Fvco > MAX_VCO) - break; - - Fout = Fvco / ( P ); - - error = (target - Fout) / target; - aerror = (error < 0) ? -error : error; - if (aerror < abest) { - abest = aerror; - bestError = error; - bestM = M; - bestN = N; - bestP = P; - bestPSN = PSN; - bestVLD = VLD; - bestFout = Fout; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3, + + } else { + + for(PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { + + int low_N, high_N; + double FrefVLDPSN; + + PSN = !PSNx ? 1 : 4; + + low_N = 2; + high_N = 32; + + for(VLD = 1 ; VLD <= max_VLD ; VLD++) { + + FrefVLDPSN = (double)Fref * VLD / PSN; + + for(N = low_N; N <= high_N; N++) { + double tmp = FrefVLDPSN / N; + + for(P = 1; P <= 4; P++) { + double Fvco_desired = target * ( P ); + double M_desired = Fvco_desired / tmp; + + /* Which way will M_desired be rounded? + * Do all three just to be safe. + */ + int M_low = M_desired - 1; + int M_hi = M_desired + 1; + + if(M_hi < M_min || M_low > M_max) continue; + + if(M_low < M_min) M_low = M_min; + + if(M_hi > M_max) M_hi = M_max; + + for(M = M_low; M <= M_hi; M++) { + Fvco = tmp * M; + if(Fvco <= MIN_VCO) continue; + if(Fvco > MAX_VCO) break; + + Fout = Fvco / ( P ); + + error = (target - Fout) / target; + aerror = (error < 0) ? -error : error; + if(aerror < abest) { + abest = aerror; + bestM = M; + bestN = N; + bestP = P; + bestPSN = PSN; + bestVLD = VLD; +#ifdef DEBUG + bestFout = Fout; +#endif + } +#ifdef TWDEBUG + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3, "Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", (float)(clock / 1000.), M, N, P, VLD, PSN); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3, + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3, "Freq. set: %.2f MHz\n", Fout / 1.0e6); - } - } - } - } - } +#endif + } + } + } + } + } } - vclk[Midx] = bestM; - vclk[Nidx] = bestN; - vclk[VLDidx] = bestVLD; - vclk[Pidx] = bestP; - vclk[PSNidx] = bestPSN; + vclk[Midx] = bestM; + vclk[Nidx] = bestN; + vclk[VLDidx] = bestVLD; + vclk[Pidx] = bestP; + vclk[PSNidx] = bestPSN; - PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", - (float)(clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx], + (float)(clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx], vclk[PSNidx])); - PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Freq. set: %.2f MHz\n", bestFout / 1.0e6)); - PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "VCO Freq.: %.2f MHz\n", bestFout*bestP / 1.0e6)); } @@ -369,7 +368,7 @@ SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - switch (pSiS->Chipset) { + switch(pSiS->Chipset) { case PCI_CHIP_SIS5597: max=0x3C; break; @@ -383,22 +382,18 @@ SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) } /* Save extended SR registers */ - for (i = 0x06; i <= max; i++) { - inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); -#ifdef DEBUG - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "XR%02X Contents - %02X \n", i, sisReg->sisRegs3C4[i]); -#endif + for(i = 0x00; i <= max; i++) { + inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]); #endif } #ifdef TWDEBUG - for (i = 0x00; i <= 0x3f; i++) { - inSISIDXREG(SISCR, i, max); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + for(i = 0x00; i <= 0x3f; i++) { + inSISIDXREG(SISCR, i, max); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CR%02X - %02X \n", i,max); } #endif @@ -412,9 +407,9 @@ SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { outSISIDXREG(SISCR, 0x80, 0x86); for(i = 0x00; i <= 0x44; i++) { - sisReg->sis6326tv[i] = SiS6326GetTVReg(pScrn, i); + sisReg->sis6326tv[i] = SiS6326GetTVReg(pScrn, i); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VR%02X - %02X \n", i,sisReg->sis6326tv[i]); #endif } @@ -427,9 +422,6 @@ SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) SISPtr pSiS = SISPTR(pScrn); int i,max; unsigned char tmp; -#ifdef DEBUG - int temp; -#endif xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); @@ -438,7 +430,7 @@ SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - switch (pSiS->Chipset) { + switch(pSiS->Chipset) { case PCI_CHIP_SIS5597: max = 0x3C; break; @@ -459,48 +451,10 @@ SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) SiS6326SetTVReg(pScrn, 0x00, tmp); } - /* Restore VCLKs */ -#if 0 /* TW: No, we didn't save SR2x-1 and SR2x-2! */ - andSISIDXREG(SISSR, 0x38, 0xfc); - inSISIDXREG(SISSR, 0x13, tmp); - tmp &= ~0x40; - tmp |= (sisReg->sisRegs3C4[0x13] & 0x40); - outSISIDXREG(SISSR, 0x13, tmp); - outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]); - outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]); - orSISIDXREG(SISSR, 0x38, 0x01); - inSISIDXREG(SISSR, 0x13, tmp); - tmp &= ~0x40; - tmp |= (sisReg->sisRegs3C4[0x13] & 0x40); - outSISIDXREG(SISSR, 0x13, tmp); - outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]); - outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]); - andSISIDXREG(SISSR, 0x38, 0xfc); - orSISIDXREG(SISSR, 0x38, 0x02); - inSISIDXREG(SISSR, 0x13, tmp); - tmp &= ~0x40; - tmp |= (sisReg->sisRegs3C4[0x13] & 0x40); - outSISIDXREG(SISSR, 0x13, tmp); - outSISIDXREG(SISSR, 0x2a, sisReg->sisRegs3C4[0x2a]); - outSISIDXREG(SISSR, 0x2b, sisReg->sisRegs3C4[0x2b]); - andSISIDXREG(SISSR, 0x38, 0xfc); -#endif - /* Restore other extended SR registers */ - for (i = 0x06; i <= max; i++) { - if((i == 0x13) || (i == 0x2a) || (i == 0x2b)) continue; -#ifdef DEBUG - inSISIDXREG(SISSR, i, temp); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "SR%X Contents: %02X - ", i, temp); -#endif - outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); -#ifdef DEBUG - inSISIDXREG(SISSR, i, temp); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "Restored to %02X - Read: %02X\n", - sisReg->sisRegs3C4[i], temp); -#endif + for(i = 0x06; i <= max; i++) { + if((i == 0x13) || (i == 0x2a) || (i == 0x2b)) continue; + outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); } /* Now restore VCLK (with correct SR38 setting) */ @@ -520,9 +474,9 @@ SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) pSiS->SiS6326Flags &= ~SIS6326_TVON; if((pSiS->Chipset == PCI_CHIP_SIS6326) && (pSiS->SiS6326Flags & SIS6326_HASTV)) { for(i = 0x01; i <= 0x44; i++) { - SiS6326SetTVReg(pScrn, i, sisReg->sis6326tv[i]); + SiS6326SetTVReg(pScrn, i, sisReg->sis6326tv[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VR%02x restored to %02x\n", i, sisReg->sis6326tv[i]); #endif @@ -556,23 +510,23 @@ SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #endif /* Save SR registers */ - for (i = 0x00; i <= 0x3D; i++) { - inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); + for(i = 0x00; i <= 0x3D; i++) { + inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]); #endif } /* Save CR registers */ - for (i = 0x00; i < 0x40; i++) { - inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); + for(i = 0x00; i < 0x40; i++) { + inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CR%02X Contents - %02X \n", i,sisReg->sisRegs3D4[i]); #endif } - + /* Save Misc register */ sisReg->sisRegs3C2 = inSISREG(SISMISCR); @@ -592,12 +546,12 @@ SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #ifndef TWDEBUG if(!pSiS->UseVESA) { #endif - if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) - (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301|VB_303)) - (*pSiS->SiSSave2)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) - (*pSiS->SiSSave3)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg); + if(pSiS->VBFlags & VB_301) + (*pSiS->SiSSave2)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) + (*pSiS->SiSSave3)(pScrn, sisReg); #ifndef TWDEBUG } #endif @@ -606,7 +560,7 @@ SiS300Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) if(!(pSiS->UseVESA)) #endif - pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); #ifdef TWDEBUG xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -630,68 +584,68 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - /* TW: Wait for accelerator to finish on-going drawing operations. */ + /* Wait for accelerator to finish on-going drawing operations. */ inSISIDXREG(SISSR, 0x1E, temp); if(temp & (0x40|0x10|0x02)) { - while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; - while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; - while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; + while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; + while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; + while ( (MMIO_IN16(pSiS->IOBase, 0x8242) & 0xE000) != 0xE000){}; } - - if (!(pSiS->UseVESA)) { + + if(!(pSiS->UseVESA)) { if(pSiS->VBFlags & VB_LVDS) { - SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); } } /* Restore extended CR registers */ for(i = 0x19; i < 0x40; i++) { - outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); + outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); } if(pSiS->Chipset != PCI_CHIP_SIS300) { - unsigned char val; - inSISIDXREG(SISCR, 0x1A, val); - if(val == sisReg->sisRegs3D4[0x19]) - outSISIDXREG(SISCR, 0x1A, sisReg->sisRegs3D4[0x19]); - inSISIDXREG(SISCR,0x19,val); - if(val == sisReg->sisRegs3D4[0x1A]) - outSISIDXREG(SISCR, 0x19, sisReg->sisRegs3D4[0x1A]); + unsigned char val; + inSISIDXREG(SISCR, 0x1A, val); + if(val == sisReg->sisRegs3D4[0x19]) + outSISIDXREG(SISCR, 0x1A, sisReg->sisRegs3D4[0x19]); + inSISIDXREG(SISCR,0x19,val); + if(val == sisReg->sisRegs3D4[0x1A]) + outSISIDXREG(SISCR, 0x19, sisReg->sisRegs3D4[0x1A]); } /* Set (and leave) PCI_IO_ENABLE on if accelerators are on */ if(sisReg->sisRegs3C4[0x1e] & 0x50) { - sisReg->sisRegs3C4[0x20] |= 0x20; - outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); + sisReg->sisRegs3C4[0x20] |= 0x20; + outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); } - /* TW: If TQ is switched on, don't switch it off ever again! - * Therefore, always restore registers with TQ enabled. + /* If TQ is switched on, don't switch it off ever again! + * Therefore, always restore registers with TQ enabled. */ if((!pSiS->NoAccel) && (pSiS->TurboQueue)) { - temp = (pScrn->videoRam/64) - 8; - sisReg->sisRegs3C4[0x26] = temp & 0xFF; - sisReg->sisRegs3C4[0x27] = ((temp >> 8) & 3) | 0xF0; + temp = (pScrn->videoRam/64) - 8; + sisReg->sisRegs3C4[0x26] = temp & 0xFF; + sisReg->sisRegs3C4[0x27] = ((temp >> 8) & 3) | 0xF0; } /* Restore extended SR registers */ - for (i = 0x06; i <= 0x3D; i++) { - temp = sisReg->sisRegs3C4[i]; - if(!(pSiS->UseVESA)) { - if(pSiS->VBFlags & VB_LVDS) { - if(i == 0x11) { - inSISIDXREG(SISSR,0x11,temp); - temp &= 0x0c; - temp |= (sisReg->sisRegs3C4[i] & 0xf3); - } - } - } - outSISIDXREG(SISSR, i, temp); + for(i = 0x06; i <= 0x3D; i++) { + temp = sisReg->sisRegs3C4[i]; + if(!(pSiS->UseVESA)) { + if(pSiS->VBFlags & VB_LVDS) { + if(i == 0x11) { + inSISIDXREG(SISSR,0x11,temp); + temp &= 0x0c; + temp |= (sisReg->sisRegs3C4[i] & 0xf3); + } + } + } + outSISIDXREG(SISSR, i, temp); } - - /* TW: Restore VCLK and ECLK */ - if(pSiS->VBFlags & (VB_LVDS | VB_301B)) { + + /* Restore VCLK and ECLK */ + if(pSiS->VBFlags & (VB_LVDS | VB_301B | VB_301C)) { outSISIDXREG(SISSR,0x31,0x20); outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); @@ -705,7 +659,7 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); outSISIDXREG(SISSR,0x2d,0x80); - if(pSiS->VBFlags & (VB_LVDS | VB_301B)) { + if(pSiS->VBFlags & (VB_LVDS | VB_301B | VB_301C)) { outSISIDXREG(SISSR,0x31,0x20); outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); @@ -716,10 +670,10 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); } - + /* Restore Misc register */ - outSISREG(SISMISCW, sisReg->sisRegs3C2); - + outSISREG(SISMISCW, sisReg->sisRegs3C2); + /* Restore FQBQ and GUI timer settings */ if(pSiS->Chipset == PCI_CHIP_SIS630) { temp1 = pciReadLong(0x00000000, 0x50); @@ -729,9 +683,9 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) } else { /* 730 */ temp1 &= 0xfffff9ff; temp1 |= (sisReg->sisRegsPCI50 & ~0xfffff9ff); - } + } pciWriteLong(0x00000000, 0x50, temp1); - + temp1 = pciReadLong(0x00000000, 0xA0); if(pciReadLong(0x00000000, 0x00) == 0x06301039) { temp1 &= 0xf0ffffff; @@ -739,20 +693,20 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) } else { /* 730 */ temp1 &= 0x00ffffff; temp1 |= (sisReg->sisRegsPCIA0 & ~0x00ffffff); - } + } pciWriteLong(0x00000000, 0xA0, temp1); } /* Restore panel link/video bridge registers */ - if (!(pSiS->UseVESA)) { - if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) - (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301|VB_303)) - (*pSiS->SiSRestore2)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) - (*pSiS->SiSRestore3)(pScrn, sisReg); + if(!(pSiS->UseVESA)) { + if(pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg); + if(pSiS->VBFlags & VB_301) + (*pSiS->SiSRestore2)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) + (*pSiS->SiSRestore3)(pScrn, sisReg); } - + /* MemClock needs this to take effect */ outSISIDXREG(SISSR, 0x00, 0x01); /* Synchronous Reset */ outSISIDXREG(SISSR, 0x00, 0x03); /* End Reset */ @@ -761,65 +715,75 @@ SiS300Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) #if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) if(!(pSiS->UseVESA)) #endif - SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); + SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); } -/* Save SiS310 series register contents */ +/* Save SiS315 series register contents */ static void -SiS310Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) +SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); int i; PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, - "SiS310Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n")); + "SiS315Save(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n")); #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif /* Save SR registers */ - for (i = 0x00; i <= 0x3F; i++) { - inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); -#ifdef DEBUG - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]); -#endif + for(i = 0x00; i <= 0x3F; i++) { + inSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SR%02X - %02X \n", i,sisReg->sisRegs3C4[i]); #endif } - /* TW: Save command queue location */ + /* Save command queue location */ sisReg->sisMMIO85C0 = MMIO_IN32(pSiS->IOBase, 0x85C0); /* Save CR registers */ - for (i = 0x00; i <= 0x5f; i++) { - inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); -#ifdef DEBUG - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "CR%02X - %02X \n", i,sisReg->sisRegs3D4[i]); -#endif + for(i = 0x00; i <= 0x7a; i++) { + inSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CR%02X Contents - %02X \n", i,sisReg->sisRegs3D4[i]); #endif } + /* Save video capture registers */ + for(i = 0x00; i <= 0x4f; i++) { + inSISIDXREG(SISCAP, i, sisReg->sisCapt[i]); +#ifdef TWDEBUG + 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++) { + inSISIDXREG(SISVID, i, sisReg->sisVid[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Vid%02X Contents - %02X \n", i,sisReg->sisVid[i]); +#endif + } + /* Save Misc register */ - sisReg->sisRegs3C2 = inSISREG(SISMISCR); + sisReg->sisRegs3C2 = inSISREG(SISMISCR); /* Save panel link/video bridge registers */ #ifndef TWDEBUG - if (!pSiS->UseVESA) { + if(!pSiS->UseVESA) { #endif - if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) - (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301|VB_303)) - (*pSiS->SiSSave2)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) - (*pSiS->SiSSave3)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSSaveLVDSChrontel)(pScrn, sisReg); + if(pSiS->VBFlags & VB_301) + (*pSiS->SiSSave2)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) + (*pSiS->SiSSave3)(pScrn, sisReg); #ifndef TWDEBUG } #endif @@ -828,43 +792,37 @@ SiS310Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) #if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) if(!(pSiS->UseVESA)) #endif - pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + pSiS->BIOSModeSave = SiS_GetSetModeID(pScrn,0xFF); + +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS mode ds:449 = 0x%x\n", pSiS->BIOSModeSave); +#endif } -/* Restore SiS310 series register contents */ +/* Restore SiS315/330 series register contents */ static void -SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) +SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); int i,temp; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); + "SiS315Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n"); #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - /* TW: Wait for accelerator to finish on-going drawing operations. */ + /* Wait for accelerator to finish on-going drawing operations. */ inSISIDXREG(SISSR, 0x1E, temp); - if (temp & (0x40|0x10|0x02)) { /* TW: 0x40 = 2D, 0x10 = 3D enabled*/ - while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; - while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; - while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; - } - - /* Restore extended CR registers */ - for (i = 0x19; i < 0x5C; i++) { - outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); - } - - /* TW: Leave PCI_IO_ENABLE on if accelerators are on (Is this required?) */ - if (sisReg->sisRegs3C4[0x1e] & 0x50) { /*0x40=2D, 0x10=3D*/ - sisReg->sisRegs3C4[0x20] |= 0x20; - outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); + if(temp & (0x40|0x10|0x02)) { /* 0x40 = 2D, 0x10 = 3D enabled*/ + while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; + while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; + while ( (MMIO_IN32(pSiS->IOBase, 0x85CC) & 0x80000000) != 0x80000000){}; } - /* TW: We reset the command queue before restoring. + /* We reset the command queue before restoring. * This might be required because we never know what * console driver (like the kernel framebuffer driver) * or application is running and which queue mode it @@ -873,68 +831,74 @@ SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISSR, 0x27, 0x1F); outSISIDXREG(SISSR, 0x26, 0x01); + /* Restore extended CR registers */ + for(i = 0x19; i < 0x5C; i++) { + outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); + } + if(pSiS->sishw_ext.jChipType < SIS_661) { + outSISIDXREG(SISCR, 0x79, sisReg->sisRegs3D4[0x79]); + } + outSISIDXREG(SISCR, 0x63, sisReg->sisRegs3D4[0x63]); + + /* Leave PCI_IO_ENABLE on if accelerators are on (Is this required?) */ + if(sisReg->sisRegs3C4[0x1e] & 0x50) { /*0x40=2D, 0x10=3D*/ + sisReg->sisRegs3C4[0x20] |= 0x20; + outSISIDXREG(SISSR, 0x20, sisReg->sisRegs3C4[0x20]); + } + /* Restore extended SR registers */ - for (i = 0x06; i <= 0x3F; i++) { -#ifdef DEBUG - inSISIDXREG(SISSR, i, temp); -#endif - outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); -#ifdef DEBUG - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "XR%X Contents %02X - ", i, temp); - inSISIDXREG(SISSR, i, temp); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, - "Restored to %02X - Read: %02X\n", - sisReg->sisRegs3C4[i], temp); -#endif + for(i = 0x06; i <= 0x3F; i++) { + outSISIDXREG(SISSR, i, sisReg->sisRegs3C4[i]); } - /* TW: Restore VCLK and ECLK */ + /* Restore VCLK and ECLK */ andSISIDXREG(SISSR,0x31,0xcf); if(pSiS->VBFlags & VB_LVDS) { - orSISIDXREG(SISSR,0x31,0x20); - outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); - outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); - outSISIDXREG(SISSR,0x2d,0x80); - andSISIDXREG(SISSR,0x31,0xcf); - orSISIDXREG(SISSR,0x31,0x10); - outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); - outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); - outSISIDXREG(SISSR,0x2d,0x80); - andSISIDXREG(SISSR,0x31,0xcf); - outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); - outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); - outSISIDXREG(SISSR,0x2d,0x01); - outSISIDXREG(SISSR,0x31,0x20); - outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); - outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); - outSISIDXREG(SISSR,0x31,0x10); - outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); - outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); - outSISIDXREG(SISSR,0x31,0x00); - outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); - outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + orSISIDXREG(SISSR,0x31,0x20); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x80); + andSISIDXREG(SISSR,0x31,0xcf); + orSISIDXREG(SISSR,0x31,0x10); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x80); + andSISIDXREG(SISSR,0x31,0xcf); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x01); + outSISIDXREG(SISSR,0x31,0x20); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + outSISIDXREG(SISSR,0x31,0x10); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); + outSISIDXREG(SISSR,0x31,0x00); + outSISIDXREG(SISSR,0x2e,sisReg->sisRegs3C4[0x2e]); + outSISIDXREG(SISSR,0x2f,sisReg->sisRegs3C4[0x2f]); } else { - outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); - outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); - outSISIDXREG(SISSR,0x2d,0x01); + outSISIDXREG(SISSR,0x2b,sisReg->sisRegs3C4[0x2b]); + outSISIDXREG(SISSR,0x2c,sisReg->sisRegs3C4[0x2c]); + outSISIDXREG(SISSR,0x2d,0x01); } - /* TW: Initialize read/write pointer for command queue */ +#ifndef SISVRAMQ + /* Initialize read/write pointer for command queue */ MMIO_OUT32(pSiS->IOBase, 0x85C4, MMIO_IN32(pSiS->IOBase, 0x85C8)); - /* TW: Restore queue location */ +#endif + /* Restore queue location */ MMIO_OUT32(pSiS->IOBase, 0x85C0, sisReg->sisMMIO85C0); /* Restore Misc register */ outSISREG(SISMISCW, sisReg->sisRegs3C2); /* Restore panel link/video bridge registers */ - if (!(pSiS->UseVESA)) { - if (pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) - (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301|VB_303)) - (*pSiS->SiSRestore2)(pScrn, sisReg); - if (pSiS->VBFlags & (VB_301B|VB_302B|VB_30xLV|VB_30xLVX)) - (*pSiS->SiSRestore3)(pScrn, sisReg); + if(!(pSiS->UseVESA)) { + if(pSiS->VBFlags & (VB_LVDS|VB_CHRONTEL)) + (*pSiS->SiSRestoreLVDSChrontel)(pScrn, sisReg); + if(pSiS->VBFlags & VB_301) + (*pSiS->SiSRestore2)(pScrn, sisReg); + if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV|VB_302ELV)) + (*pSiS->SiSRestore3)(pScrn, sisReg); } /* MemClock needs this to take effect */ @@ -948,56 +912,56 @@ SiS310Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) SiS_GetSetModeID(pScrn,pSiS->BIOSModeSave); } -/* Save SiS301 bridge register contents */ static void -SiS301Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) +SiSVBSave(ScrnInfoPtr pScrn, SISRegPtr sisReg, int p1, int p2, int p3, int p4) { SISPtr pSiS = SISPTR(pScrn); int i; - int Part1max=0, Part2max=0, Part3max=0, Part4max=0; - - /* Highest register number to save/restore */ - switch (pSiS->VGAEngine) { - case SIS_300_VGA: - Part1max = 0x1d; - Part2max = 0x45; - Part3max = 0x3e; - Part4max = 0x1b; - break; - case SIS_315_VGA: - Part1max = 0x2e; /* 0x23, but we also need 2d-2e */ - Part2max = 0x45; - Part3max = 0x3e; - Part4max = 0x1b; - break; - } - for (i=0; i<=Part1max; i++) { - inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); + for(i=0; i<=p1; i++) { + inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); #ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301Save: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]); + xf86DrvMsg(0, X_INFO, "301xSave: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]); #endif } - for (i=0; i<=Part2max; i++) { - inSISIDXREG(SISPART2, i, sisReg->VBPart2[i]); + for(i=0; i<=p2; i++) { + inSISIDXREG(SISPART2, i, sisReg->VBPart2[i]); #ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301Save: Part2Port 0x%02x = 0x%02x\n", i, sisReg->VBPart2[i]); + xf86DrvMsg(0, X_INFO, "301xSave: Part2Port 0x%02x = 0x%02x\n", i, sisReg->VBPart2[i]); #endif } - for (i=0; i<=Part3max; i++) { - inSISIDXREG(SISPART3, i, sisReg->VBPart3[i]); + for(i=0; i<=p3; i++) { + inSISIDXREG(SISPART3, i, sisReg->VBPart3[i]); #ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301Save: Part3Port 0x%02x = 0x%02x\n", i, sisReg->VBPart3[i]); + xf86DrvMsg(0, X_INFO, "301xSave: Part3Port 0x%02x = 0x%02x\n", i, sisReg->VBPart3[i]); #endif } - for (i=0; i<=Part4max; i++) { - inSISIDXREG(SISPART4, i, sisReg->VBPart4[i]); + for(i=0; i<=p4; i++) { + inSISIDXREG(SISPART4, i, sisReg->VBPart4[i]); #ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301Save: Part4Port 0x%02x = 0x%02x\n", i, sisReg->VBPart4[i]); + xf86DrvMsg(0, X_INFO, "301xSave: Part4Port 0x%02x = 0x%02x\n", i, sisReg->VBPart4[i]); #endif } +} - sisReg->VBPart2[0] &= ~0x20; /* Disable VB Processor */ +/* Save SiS301 bridge register contents */ +static void +SiS301Save(ScrnInfoPtr pScrn, SISRegPtr sisReg) +{ + SISPtr pSiS = SISPTR(pScrn); + int Part1max, Part2max, Part3max, Part4max; + + /* Highest register number to save/restore */ + if(pSiS->VGAEngine == SIS_300_VGA) Part1max = 0x1d; + else Part1max = 0x2e; /* 0x23, but we also need 2d-2e */ + + Part2max = 0x45; + Part3max = 0x3e; + Part4max = 0x1b; + + SiSVBSave(pScrn, sisReg, Part1max, Part2max, Part3max, Part4max); + + sisReg->VBPart2[0x00] &= ~0x20; /* Disable VB Processor */ sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */ } @@ -1006,27 +970,19 @@ static void SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); - int Part1max=0, Part2max=0, Part3max=0, Part4max=0; + int Part1max, Part2max, Part3max, Part4max; /* Highest register number to save/restore */ - switch (pSiS->VGAEngine) { - case SIS_300_VGA: - Part1max = 0x1d; - Part2max = 0x45; - Part3max = 0x3e; - Part4max = 0x1b; - break; - case SIS_315_VGA: - Part1max = 0x23; - Part2max = 0x45; - Part3max = 0x3e; - Part4max = 0x1b; - break; - } + if(pSiS->VGAEngine == SIS_300_VGA) Part1max = 0x1d; + else Part1max = 0x23; + + Part2max = 0x45; + Part3max = 0x3e; + Part4max = 0x1b; - SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); - SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); /* Pre-restore Part1 */ outSISIDXREG(SISPART1, 0x04, 0x00); @@ -1039,22 +995,17 @@ SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISPART4, 0x0D, sisReg->VBPart4[0x0D]); outSISIDXREG(SISPART4, 0x0C, sisReg->VBPart4[0x0C]); - if (!(sisReg->sisRegs3D4[0x30] & 0x03) && - (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - return; + if((!(sisReg->sisRegs3D4[0x30] & 0x03)) && + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); + return; } /* Restore Part1 */ SetBlock(SISPART1, 0x02, Part1max, &(sisReg->VBPart1[0x02])); - switch (pSiS->VGAEngine) { - case SIS_300_VGA: - /* TW: Nothing special here. */ - break; - case SIS_315_VGA: - /* TW: Restore extra registers on 310 series */ - SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C])); - break; + if(pSiS->VGAEngine == SIS_315_VGA) { + /* Restore extra registers on 315 series */ + SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C])); } /* Restore Part2 */ @@ -1074,99 +1025,50 @@ SiS301Restore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISPART4, 0x12, 0x00); outSISIDXREG(SISPART4, 0x12, sisReg->VBPart4[0x12]); - SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); SiS_DisplayOn(pSiS->SiS_Pr); - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); } -/* Save SiS301B/302B/30xLV bridge register contents */ +/* Save SiS30xB/30xLV bridge register contents */ static void SiS301BSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); - int i; - int Part1max=0, Part2max=0, Part3max=0, Part4max=0; - - switch (pSiS->VGAEngine) { - case SIS_300_VGA: - Part1max = 0x37; /* 0x1d, but we also need 2c-2e, 35-37 */ - Part2max = 0x4d; - Part3max = 0x3e; - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) - Part4max = 0x24; - else - Part4max = 0x23; - break; - case SIS_315_VGA: - Part1max = 0x37; /* 0x23, but we also need 2c-2e, 35-37 */ - Part2max = 0x4d; - Part3max = 0x3e; - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) - Part4max = 0x24; - else - Part4max = 0x23; - break; - } + int Part1max, Part2max, Part3max, Part4max; - for (i=0; i<=Part1max; i++) { - inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301BSave: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]); -#endif - } - for (i=0; i<=Part2max; i++) { - inSISIDXREG(SISPART2, i, sisReg->VBPart2[i]); -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301BSave: Part2Port 0x%02x = 0x%02x\n", i, sisReg->VBPart2[i]); -#endif - } - for (i=0; i<=Part3max; i++) { - inSISIDXREG(SISPART3, i, sisReg->VBPart3[i]); -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301BSave: Part3Port 0x%02x = 0x%02x\n", i, sisReg->VBPart3[i]); -#endif - } - for (i=0; i<=Part4max; i++) { - inSISIDXREG(SISPART4, i, sisReg->VBPart4[i]); -#ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301BSave: Part4Port 0x%02x = 0x%02x\n", i, sisReg->VBPart4[i]); -#endif - } - sisReg->VBPart2[0] &= ~0x20; /* Disable VB Processor */ + Part1max = 0x37; /* 0x23, but we also need 2c-2e, 35-37 */ + Part2max = 0x4d; + Part3max = 0x3e; + if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) + Part4max = 0x34; + else + Part4max = 0x23; + + SiSVBSave(pScrn, sisReg, Part1max, Part2max, Part3max, Part4max); + + sisReg->VBPart2[0x00] &= ~0x20; /* Disable VB Processor */ sisReg->sisRegs3C4[0x32] &= ~0x20; /* Disable Lock Mode */ } -/* Restore SiS301B/302B/301LV/302LV bridge register contents */ +/* Restore SiS30xB/30xLV bridge register contents */ static void SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); - int Part1max=0, Part2max=0, Part3max=0, Part4max=0; - - switch (pSiS->VGAEngine) { - case SIS_300_VGA: - Part1max = 0x23; - Part2max = 0x4d; - Part3max = 0x3e; - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) - Part4max = 0x24; - else - Part4max = 0x22; - break; - case SIS_315_VGA: - Part1max = 0x23; - Part2max = 0x4d; - Part3max = 0x3e; - if(pSiS->VBFlags & (VB_30xLV|VB_30xLVX)) - Part4max = 0x24; - else - Part4max = 0x22; - break; - } + int Part1max, Part2max, Part3max, Part4max; - SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + Part1max = 0x23; + Part2max = 0x4d; + Part3max = 0x3e; + if(pSiS->VBFlags & (VB_301LV|VB_302LV|VB_302ELV)) + Part4max = 0x24; + else + Part4max = 0x22; - SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); + + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); /* Pre-restore Part1 */ outSISIDXREG(SISPART1, 0x04, 0x00); @@ -1174,18 +1076,19 @@ SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISPART1, 0x06, 0x00); outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0x00]); outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[0x01]); - /* Mode reg 0x01 became 0x2e on 310 series (0x01 still contains FIFO) */ - if(pSiS->VGAEngine == SIS_315_VGA) - outSISIDXREG(SISPART1, 0x2e, sisReg->VBPart1[0x2e]); + /* Mode reg 0x01 became 0x2e on 315 series (0x01 still contains FIFO) */ + if(pSiS->VGAEngine == SIS_315_VGA) { + outSISIDXREG(SISPART1, 0x2e, sisReg->VBPart1[0x2e]); + } /* Pre-restore Part4 */ outSISIDXREG(SISPART4, 0x0D, sisReg->VBPart4[0x0D]); outSISIDXREG(SISPART4, 0x0C, sisReg->VBPart4[0x0C]); - if (!(sisReg->sisRegs3D4[0x30] & 0x03) && - (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - return; + if((!(sisReg->sisRegs3D4[0x30] & 0x03)) && + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); + return; } /* Restore Part1 */ @@ -1211,9 +1114,9 @@ SiS301BRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISPART4, 0x12, 0x00); outSISIDXREG(SISPART4, 0x12, sisReg->VBPart4[0x12]); - SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); SiS_DisplayOn(pSiS->SiS_Pr); - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); } /* Save LVDS bridge (+ Chrontel) register contents */ @@ -1224,30 +1127,34 @@ SiSLVDSChrontelSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) int i; /* Save Part1 */ - for (i=0; i<0x46; i++) { - inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); + for(i=0; i<0x46; i++) { + inSISIDXREG(SISPART1, i, sisReg->VBPart1[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "LVDSSave: Part1Port 0x%02x = 0x%02x\n", i, sisReg->VBPart1[i]); #endif } /* Save Chrontel registers */ - if (pSiS->VBFlags & VB_CHRONTEL) { - if (pSiS->ChrontelType == CHRONTEL_700x) { - for (i=0; i<0x1D; i++) { - sisReg->ch70xx[i] = SiS_GetCH700x(pSiS->SiS_Pr, ch700xidx[i]); + if(pSiS->VBFlags & VB_CHRONTEL) { + if(pSiS->ChrontelType == CHRONTEL_700x) { + for(i=0; i<0x1D; i++) { + sisReg->ch70xx[i] = SiS_GetCH700x(pSiS->SiS_Pr, ch700xidx[i]); #ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "LVDSSave: Chrontel 0x%02x = 0x%02x\n", ch700xidx[i], sisReg->ch70xx[i]); #endif - } } else { - for (i=0; i<34; i++) { - sisReg->ch70xx[i] = SiS_GetCH701x(pSiS->SiS_Pr, ch701xidx[i]); + for(i=0; i<35; i++) { + sisReg->ch70xx[i] = SiS_GetCH701x(pSiS->SiS_Pr, ch701xidx[i]); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "LVDSSave: Chrontel 0x%02x = 0x%02x\n", + ch701xidx[i], sisReg->ch70xx[i]); +#endif } } } @@ -1263,24 +1170,24 @@ SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) int i; USHORT wtemp; - SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); if(pSiS->sishw_ext.jChipType == SIS_730) { - outSISIDXREG(SISPART1, 0x00, 0x80); + outSISIDXREG(SISPART1, 0x00, 0x80); } - SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_UnLockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); if(pSiS->VBFlags & VB_CHRONTEL) { /* Restore Chrontel registers */ if(pSiS->ChrontelType == CHRONTEL_700x) { for(i=0; i<0x11; i++) { - wtemp = ((sisReg->ch70xx[i]) << 8) | (ch700xidx[i] & 0x00FF); - SiS_SetCH700x(pSiS->SiS_Pr, wtemp); + wtemp = ((sisReg->ch70xx[i]) << 8) | (ch700xidx[i] & 0x00FF); + SiS_SetCH700x(pSiS->SiS_Pr, wtemp); } } else { for(i=0; i<34; i++) { - wtemp = ((sisReg->ch70xx[i]) << 8) | (ch701xidx[i] & 0x00FF); - SiS_SetCH701x(pSiS->SiS_Pr, wtemp); + wtemp = ((sisReg->ch70xx[i]) << 8) | (ch701xidx[i] & 0x00FF); + SiS_SetCH701x(pSiS->SiS_Pr, wtemp); } } } @@ -1290,200 +1197,70 @@ SiSLVDSChrontelRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) outSISIDXREG(SISPART1, 0x05, 0x00); outSISIDXREG(SISPART1, 0x06, 0x00); outSISIDXREG(SISPART1, 0x00, sisReg->VBPart1[0]); - if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VGAEngine == SIS_300_VGA) { outSISIDXREG(SISPART1, 0x01, (sisReg->VBPart1[1] | 0x80)); } else { outSISIDXREG(SISPART1, 0x01, sisReg->VBPart1[1]); } - if (!(sisReg->sisRegs3D4[0x30] & 0x03) && - (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); - return; + if((!(sisReg->sisRegs3D4[0x30] & 0x03)) && + (sisReg->sisRegs3D4[0x31] & 0x20)) { /* disable CRT2 */ + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); + return; } /* Restore Part1 */ - if(pSiS->VGAEngine == SIS_300_VGA) { + if(pSiS->VGAEngine == SIS_300_VGA) { outSISIDXREG(SISPART1, 0x02, (sisReg->VBPart1[2] | 0x40)); } else { outSISIDXREG(SISPART1, 0x02, sisReg->VBPart1[2]); } SetBlock(SISPART1, 0x03, 0x23, &(sisReg->VBPart1[0x03])); if(pSiS->VGAEngine == SIS_315_VGA) { - SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C])); - SetBlock(SISPART1, 0x35, 0x37, &(sisReg->VBPart1[0x35])); /* Panel Link Scaler */ + SetBlock(SISPART1, 0x2C, 0x2E, &(sisReg->VBPart1[0x2C])); + SetBlock(SISPART1, 0x35, 0x37, &(sisReg->VBPart1[0x35])); /* Panel Link Scaler */ } - /* TW: For 550 DSTN registers */ - if (pSiS->DSTN) { - SetBlock(SISPART1, 0x25, 0x2E, &(sisReg->VBPart1[0x25])); - SetBlock(SISPART1, 0x30, 0x45, &(sisReg->VBPart1[0x30])); + /* For 550 DSTN registers */ + if(pSiS->DSTN || pSiS->FSTN) { + SetBlock(SISPART1, 0x25, 0x2E, &(sisReg->VBPart1[0x25])); + SetBlock(SISPART1, 0x30, 0x45, &(sisReg->VBPart1[0x30])); } - SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); SiS_DisplayOn(pSiS->SiS_Pr); - SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext, pSiS->RelIO+0x30); + SiS_LockCRT2(pSiS->SiS_Pr, &pSiS->sishw_ext); } -/* TW: Restore output selection registers (CR30, 31, 33, 35/38) */ +/* Restore output selection registers */ void SiSRestoreBridge(ScrnInfoPtr pScrn, SISRegPtr sisReg) { SISPtr pSiS = SISPTR(pScrn); - unsigned char temp = 0; + int i; #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - outSISIDXREG(SISCR, 0x30, sisReg->sisRegs3D4[0x30]); - outSISIDXREG(SISCR, 0x31, sisReg->sisRegs3D4[0x31]); - outSISIDXREG(SISCR, 0x33, sisReg->sisRegs3D4[0x33]); - if(pSiS->Chipset != PCI_CHIP_SIS300) { - switch(pSiS->VGAEngine) { - case SIS_300_VGA: temp = 0x35; break; - case SIS_315_VGA: temp = 0x38; break; - } - if(temp) { - outSISIDXREG(SISCR, temp, sisReg->sisRegs3D4[temp]); - } + for(i = 0x30; i <= 0x39; i++) { + if(i == 0x34) continue; + outSISIDXREG(SISCR, i, sisReg->sisRegs3D4[i]); } -} - -unsigned int -SiSddc1Read(ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - unsigned char temp; - -#ifdef UNLOCK_ALWAYS - sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); -#endif - - /* Wait until vertical retrace is in progress. */ - while(inSISREG(SISINPSTAT) & 0x08); - while(!(inSISREG(SISINPSTAT) & 0x08)); - /* Get the result */ - inSISIDXREG(SISSR, 0x11, temp); - - return((temp & 0x02)>>1); -} - -#if 0 /* TW: I2C functions not in use */ -/* -static void -SiS_I2CGetBits(I2CBusPtr b, int *clock, int *data) -{ - SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]); - unsigned char val; - - outSISIDXREG(SISSR, 0x05, 0x86); - inSISIDXREG(SISSR, pSiS->SiS_DDC2_Index, val); - *clock = (val & pSiS->SiS_DDC2_Clk) != 0; - *data = (val & pSiS->SiS_DDC2_Data) != 0; -} - -static void -SiS_I2CPutBits(I2CBusPtr b, int clock, int data) -{ - SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]); - unsigned char temp; - - outSISIDXREG(SISSR, 0x05, 0x86); - inSISIDXREG(SISSR, pSiS->SiS_DDC2_Index, temp); - - temp &= ~(pSiS->SiS_DDC2_Clk | pSiS->SiS_DDC2_Data); - - temp |= ((clock ? pSiS->SiS_DDC2_Clk : 0) | (data ? pSiS->SiS_DDC2_Data : 0)); - - outSISIDXREG(SISSR, pSiS->SiS_DDC2_Index, temp); -} -*/ - -static Bool -SiS_I2CAddress(I2CDevPtr d, I2CSlaveAddr addr) -{ - I2CBusPtr b = d->pI2CBus; - SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]); - SiS_SetSwitchDDC2(pSiS->SiS_Pr); - return(SiS_I2C_Address(pSiS->SiS_Pr, addr)); -} - -static void -SiS_I2CStop(I2CDevPtr d) -{ - I2CBusPtr b = d->pI2CBus; - SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]); - SiS_I2C_Stop(pSiS->SiS_Pr); -} - -static Bool -SiS_I2CGetByte(I2CDevPtr d, I2CByte *data, Bool last) -{ - I2CBusPtr b = d->pI2CBus; - SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]); - USHORT temp = SiS_I2C_GetByte(pSiS->SiS_Pr); - if(temp == 0xffff) return FALSE; - return TRUE; -} - -static Bool -SiS_I2CPutByte(I2CDevPtr d, I2CByte data) -{ - I2CBusPtr b = d->pI2CBus; - SISPtr pSiS = SISPTR(xf86Screens[b->scrnIndex]); - return(SiS_I2C_PutByte(pSiS->SiS_Pr, (USHORT)data)); -} - -Bool -SiSI2CInit(ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - I2CBusPtr I2CPtr; - USHORT temp, i; - unsigned char buffer[256]; - xf86MonPtr pMonitor; - - I2CPtr = xf86CreateI2CBusRec(); - if(!I2CPtr) return FALSE; - - pSiS->I2C = I2CPtr; - - I2CPtr->BusName = "DDC"; - I2CPtr->scrnIndex = pScrn->scrnIndex; -/* - I2CPtr->I2CPutBits = SiS_I2CPutBits; - I2CPtr->I2CGetBits = SiS_I2CGetBits; -*/ - I2CPtr->I2CPutByte = SiS_I2CPutByte; - I2CPtr->I2CGetByte = SiS_I2CGetByte; - I2CPtr->I2CAddress = SiS_I2CAddress; - I2CPtr->I2CStop = SiS_I2CStop; - I2CPtr->AcknTimeout = 30; - - - - pSiS->SiS_Pr->SiS_DDC_Index = pSiS->SiS_DDC2_Index; - pSiS->SiS_Pr->SiS_DDC_Data = pSiS->SiS_DDC2_Data; - pSiS->SiS_Pr->SiS_DDC_Clk = pSiS->SiS_DDC2_Clk; - pSiS->SiS_Pr->SiS_DDC_DataShift = 0x00; - - if (!xf86I2CBusInit(I2CPtr)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not create I2C bus record\n"); - return FALSE; - } - - return TRUE; + if(pSiS->VGAEngine == SIS_315_VGA) { + outSISIDXREG(SISCR, 0x63, sisReg->sisRegs3D4[0x63]); + if(pSiS->sishw_ext.jChipType < SIS_661) { + outSISIDXREG(SISCR, 0x79, sisReg->sisRegs3D4[0x79]); + } + } } -#endif -#if 0 /* TW: The following function should take a threshold value - * from predefined tables. This is only needed on some - * 530 boards, which have an ESS sound device on-board. - * However, I don't know how to calculate the index to - * be submitted to this function. +#if 0 /* The following function should take a threshold value + * from predefined tables. This is only needed on some + * 530 boards, which have an ESS sound device on-board. + * However, I don't know how to calculate the index to + * be submitted to this function. */ unsigned short SiS_CalcSpecial530Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode, int index) @@ -1534,17 +1311,8 @@ SiS_CalcSpecial530Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode, int index) } #endif -/* TW: Stub */ -static void -SiSThreshold(ScrnInfoPtr pScrn, DisplayModePtr mode, - unsigned short *Low, unsigned short *High) -{ - return; -} - - /* Auxiliary function to find real memory clock (in Khz) */ -/* TW: Not for 530/620 if UMA (on these, the mclk is stored in SR10) */ +/* Not for 530/620 if UMA (on these, the mclk is stored in SR10) */ int SiSMclk(SISPtr pSiS) { @@ -1552,30 +1320,7 @@ SiSMclk(SISPtr pSiS) unsigned char Num, Denum, Base; switch (pSiS->Chipset) { - case PCI_CHIP_SIS5597: - case PCI_CHIP_SIS6326: - case PCI_CHIP_SIS530: - /* Numerator */ - inSISIDXREG(SISSR, MemClock0, Num); - mclk = 14318 * ((Num & 0x7f) + 1); - - /* Denumerator */ - inSISIDXREG(SISSR, MemClock1, Denum); - mclk = mclk / ((Denum & 0x1f) + 1); - - /* Divider. Doesn't seem to work for mclk in older cards */ - if((Num & 0x80) != 0) mclk *= 2; - /* Post-scaler. Values' meaning depends on SR13 bit 7 */ - inSISIDXREG(SISSR, ClockBase, Base); - if((Base & 0x80) == 0) { - mclk = mclk / (((Denum & 0x60) >> 5) + 1); - } else { - /* Values 00 and 01 are reserved */ - if ((Denum & 0x60) == 0x40) mclk /= 6; - if ((Denum & 0x60) == 0x60) mclk /= 8; - } - break; case PCI_CHIP_SIS300: case PCI_CHIP_SIS540: case PCI_CHIP_SIS630: @@ -1585,6 +1330,7 @@ SiSMclk(SISPtr pSiS) case PCI_CHIP_SIS315H: case PCI_CHIP_SIS315PRO: case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: /* Numerator */ inSISIDXREG(SISSR, 0x28, Num); mclk = 14318 * ((Num & 0x7f) + 1); @@ -1598,30 +1344,53 @@ SiSMclk(SISPtr pSiS) /* Post-Scaler */ if((Denum & 0x80) == 0) { - mclk = mclk / (((Denum & 0x60) >> 5) + 1); + mclk = mclk / (((Denum & 0x60) >> 5) + 1); } else { - mclk = mclk / ((((Denum & 0x60) >> 5) + 1) * 2); + mclk = mclk / ((((Denum & 0x60) >> 5) + 1) * 2); } break; + + case PCI_CHIP_SIS5597: + case PCI_CHIP_SIS6326: + case PCI_CHIP_SIS530: default: - xf86DrvMsg(pSiS->pScrn->scrnIndex, X_ERROR, - "Internal error: SiSMClk() called with invalid chipset (0x%x)\n", - pSiS->Chipset); - mclk = 0; + /* Numerator */ + inSISIDXREG(SISSR, 0x28, Num); + mclk = 14318 * ((Num & 0x7f) + 1); + + /* Denumerator */ + inSISIDXREG(SISSR, 0x29, Denum); + mclk = mclk / ((Denum & 0x1f) + 1); + + /* Divider. Doesn't work on older cards */ + if(pSiS->oldChipset >= OC_SIS5597) { + if(Num & 0x80) mclk *= 2; + } + + /* Post-scaler. Values' meaning depends on SR13 bit 7 */ + inSISIDXREG(SISSR, 0x13, Base); + if((Base & 0x80) == 0) { + mclk = mclk / (((Denum & 0x60) >> 5) + 1); + } else { + /* Values 00 and 01 are reserved */ + if ((Denum & 0x60) == 0x40) mclk /= 6; + if ((Denum & 0x60) == 0x60) mclk /= 8; + } + break; } return(mclk); } -/* TW: This estimates the CRT2 clock we are going to use. - * The total bandwidth is to be reduced by the value - * returned here in order to get an idea of the maximum - * dotclock left for CRT1. - * Since we don't know yet, what mode the user chose, - * we return the maximum dotclock used by - * - either the LCD attached, or - * - TV - * For VGA2, we share the bandwith equally. +/* This estimates the CRT2 clock we are going to use. + * The total bandwidth is to be reduced by the value + * returned here in order to get an idea of the maximum + * dotclock left for CRT1. + * Since we don't know yet, what mode the user chose, + * we return the maximum dotclock used by + * - either the LCD attached, or + * - TV + * For VGA2, we share the bandwith equally. */ static int SiSEstimateCRT2Clock(ScrnInfoPtr pScrn) @@ -1629,37 +1398,39 @@ SiSEstimateCRT2Clock(ScrnInfoPtr pScrn) SISPtr pSiS = SISPTR(pScrn); if(pSiS->VBFlags & CRT2_LCD) { - if(pSiS->VBLCDFlags & (VB_LCD_320x480 | VB_LCD_800x600 | VB_LCD_640x480)) - return 40000; - else if(pSiS->VBLCDFlags & (VB_LCD_1024x768 | VB_LCD_1024x600)) - return 65000; - else if(pSiS->VBLCDFlags & (VB_LCD_1152x768 | VB_LCD_1280x1024 | VB_LCD_1280x960)) - return 108000; - else if(pSiS->VBLCDFlags & VB_LCD_1400x1050) - return 122000; - else if(pSiS->VBLCDFlags & VB_LCD_1600x1200) - return 162000; - else - return 108000; + if(pSiS->VBLCDFlags & (VB_LCD_320x480 | VB_LCD_800x600 | VB_LCD_640x480)) + return 40000; + else if(pSiS->VBLCDFlags & (VB_LCD_1024x768 | VB_LCD_1024x600 | VB_LCD_1152x768)) + return 65000; + else if(pSiS->VBLCDFlags & VB_LCD_1280x768) + return 81000; + else if(pSiS->VBLCDFlags & (VB_LCD_1280x1024 | VB_LCD_1280x960 | VB_LCD_1400x1050)) + return 108000; + else if(pSiS->VBLCDFlags & VB_LCD_1600x1200) + return 162000; + else if((pSiS->VBLCDFlags & VB_LCD_CUSTOM) && (pSiS->SiS_Pr->CP_HaveCustomData)) + return pSiS->SiS_Pr->CP_MaxClock; + else + return 108000; } else if(pSiS->VBFlags & CRT2_TV) { - if(pSiS->VBFlags & VB_CHRONTEL) { - switch(pSiS->VGAEngine) { - case SIS_300_VGA: - return 50000; - case SIS_315_VGA: - default: - return 70000; - } - } else if(pSiS->VBFlags & VB_SISBRIDGE) { - return 70000; - } + if(pSiS->VBFlags & VB_CHRONTEL) { + switch(pSiS->VGAEngine) { + case SIS_300_VGA: + return 50000; + case SIS_315_VGA: + default: + return 70000; + } + } else if(pSiS->VBFlags & VB_SISBRIDGE) { + return 70000; + } } return 0; } /* Calculate the maximum dotclock */ -int SiSMemBandWidth(ScrnInfoPtr pScrn) +int SiSMemBandWidth(ScrnInfoPtr pScrn, BOOLEAN IsForCRT2) { SISPtr pSiS = SISPTR(pScrn); #ifdef SISDUALHEAD @@ -1670,14 +1441,15 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn) int mclk = pSiS->MemClock; int bpp = pSiS->CurrentLayout.bitsPerPixel; int bytesperpixel = (bpp + 7) / 8; - float magic=0.0, total, crt2used; + float magic=0.0, total, crt2used, maxcrt2; int crt2clock, max=0; 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 }; + BOOLEAN DHM, GetForCRT1; - switch (pSiS->Chipset) { + switch(pSiS->Chipset) { case PCI_CHIP_SIS5597: total = ((mclk * (bus / 8)) * 0.7) / bytesperpixel; @@ -1712,6 +1484,7 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn) case PCI_CHIP_SIS550: case PCI_CHIP_SIS650: case PCI_CHIP_SIS330: + case PCI_CHIP_SIS660: switch(pSiS->Chipset) { case PCI_CHIP_SIS300: magic = magic300[bus/64]; @@ -1730,9 +1503,21 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn) max = 780000; break; case PCI_CHIP_SIS550: + magic = magic550[bus/64]; + max = 620000; + break; case PCI_CHIP_SIS650: magic = magic550[bus/64]; - max = 780000; + max = 680000; + break; + case PCI_CHIP_SIS660: + if((pSiS->sishw_ext.jChipType >= SIS_660) && + (!(pSiS->ChipFlags & SiSCF_760UMA))) { + magic = magic315[bus/64]; + } else { + magic = magic550[bus/64]; + } + max = 680000; } PDEBUG(ErrorF("mclk: %d, bus: %d, magic: %g, bpp: %d\n", @@ -1743,18 +1528,39 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory bandwidth at %d bpp is %g MHz\n", bpp, total/1000); - if(pSiS->VBFlags & CRT2_ENABLE) { + if((pSiS->VBFlags & CRT2_ENABLE) && (!pSiS->CRT1off)) { + + maxcrt2 = 135000; + if(pSiS->VBFlags & (VB_301B|VB_302B)) maxcrt2 = 162000; + else if(pSiS->VBFlags & VB_301C) maxcrt2 = 203000; + /* if(pSiS->VBFlags & VB_30xBDH) maxcrt2 = 100000; + Ignore 301B-DH here; seems the current version is like + 301B anyway */ crt2used = 0.0; crt2clock = SiSEstimateCRT2Clock(pScrn); if(crt2clock) { crt2used = crt2clock + 2000; } + DHM = FALSE; + GetForCRT1 = FALSE; #ifdef SISDUALHEAD if((pSiS->DualHeadMode) && (pSiSEnt)) { + DHM = TRUE; + if(pSiS->SecondHead) GetForCRT1 = TRUE; + } +#endif +#ifdef SISMERGED + if(pSiS->MergedFB && IsForCRT2) { + DHM = TRUE; + GetForCRT1 = FALSE; + } +#endif + + if(DHM) { - if(!pSiS->SecondHead) { + if(!GetForCRT1) { /* TW: First head = CRT2 */ @@ -1769,22 +1575,30 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn) * calculation below. */ total = crt2used * magic; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Bandwidth reserved for CRT2 is %g Mhz\n", - crt2used/1000); + } else { /* We don't know about the second head's * depth yet. So we assume it uses the - * same. + * same. But since the maximum dotclock + * is limited on CRT2, we can assume a + * maximum here. */ - total /= 2; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Bandwidth reserved for CRT2 is %g Mhz\n", - total/1000); + if((total / 2) > (maxcrt2 + 2000)) { + total = (maxcrt2 + 2000) * magic; + crt2used = maxcrt2 + 2000; + } else { + total /= 2; + crt2used = total; + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth reserved for CRT2 is %g Mhz\n", + crt2used/1000); } else { - +#ifdef SISDUALHEAD /* TW: Second head = CRT1 */ /* Now We know about the first head's depth, @@ -1807,104 +1621,138 @@ int SiSMemBandWidth(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Bandwidth available for CRT1 is %g MHz\n", total/1000); - +#endif } } else { -#endif + if(crt2clock) { total -= crt2used; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Bandwidth reserved for CRT2 is %g Mhz\n", crt2used/1000); } else { - total /= 2; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Bandwidth reserved for CRT2 is %g Mhz\n", total/1000); + if((total / 2) > (maxcrt2 + 2000)) { + total -= (maxcrt2 + 2000); + crt2used = maxcrt2 + 2000; + } else { + total /= 2; + crt2used = total; + } } + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Bandwidth reserved for CRT2 is %g Mhz\n", crt2used/1000); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Bandwidth available for CRT1 is %g MHz\n", total/1000); -#ifdef SISDUALHEAD + } -#endif } total /= magic; if(total > (max / 2)) total = max / 2; - return (int)(total); + return(int)(total); default: - return 135000; /* guessed */ + return(135000); } } -/* TW: Load the palette. We do this for all supported color depths - * in order to support gamma correction. We hereby convert the - * given colormap to a complete 24bit color palette and enable - * the correspoding bit in SR7 to enable the 24bit lookup table. - * Gamma correction is only supported on CRT1. - * Why are there 6-bit-RGB values submitted even if bpp is 16 and - * weight is 565? (Maybe because rgbBits is 6?) +/* Load the palette. We do this for all supported color depths + * in order to support gamma correction. We hereby convert the + * given colormap to a complete 24bit color palette and enable + * the correspoding bit in SR7 to enable the 24bit lookup table. + * Gamma correction is only supported on CRT1. + * Why are there 6-bit-RGB values submitted even if bpp is 16 and + * weight is 565? (Maybe because rgbBits is 6?) */ void SISLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual) { - SISPtr pSiS = SISPTR(pScrn); - int i, j, index; + SISPtr pSiS = SISPTR(pScrn); + int i, j, index; + unsigned char backup = 0; + Bool dogamma1 = pSiS->CRT1gamma; + Bool resetxvgamma = FALSE; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiS->DualHeadMode) dogamma1 = pSiSEnt->CRT1gamma; +#endif - PDEBUG(ErrorF("SiSLoadPalette(%d)\n", numColors)); + PDEBUG(ErrorF("SiSLoadPalette(%d)\n", numColors)); #ifdef SISDUALHEAD - /* TW: No palette changes on CRT2 if in dual head mode */ - if((pSiS->DualHeadMode) && (!pSiS->SecondHead)) return; + if((!pSiS->DualHeadMode) || (pSiS->SecondHead)) { #endif + if(pSiS->VGAEngine == SIS_315_VGA) { + inSISIDXREG(SISSR, 0x1f, backup); + andSISIDXREG(SISSR, 0x1f, 0xe7); + if( (pSiS->XvGamma) && + (pSiS->MiscFlags & MISC_CRT1OVERLAYGAMMA) && + ((pSiS->CurrentLayout.depth == 16) || + (pSiS->CurrentLayout.depth == 24)) ) { + orSISIDXREG(SISSR, 0x1f, 0x10); + resetxvgamma = TRUE; + } + } + switch(pSiS->CurrentLayout.depth) { #ifdef SISGAMMA case 15: - orSISIDXREG(SISSR, 0x07, 0x04); - for(i=0; i<numColors; i++) { - index = indices[i]; - if(index < 32) { /* Paranoia */ - for(j=0; j<8; j++) { - outSISREG(SISCOLIDX, (index * 8) + j); - outSISREG(SISCOLDATA, colors[index].red << (8- pScrn->rgbBits)); - outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits)); - outSISREG(SISCOLDATA, colors[index].blue << (8 - pScrn->rgbBits)); + if(dogamma1) { + orSISIDXREG(SISSR, 0x07, 0x04); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 32) { /* Paranoia */ + for(j=0; j<8; j++) { + outSISREG(SISCOLIDX, (index * 8) + j); + outSISREG(SISCOLDATA, colors[index].red << (8- pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].blue << (8 - pScrn->rgbBits)); + } } - } - } + } + } else { + andSISIDXREG(SISSR, 0x07, ~0x04); + } break; case 16: - orSISIDXREG(SISSR, 0x07, 0x04); - for(i=0; i<numColors; i++) { - index = indices[i]; - if(index < 64) { /* Paranoia */ - for(j=0; j<4; j++) { - outSISREG(SISCOLIDX, (index * 4) + j); - outSISREG(SISCOLDATA, colors[index/2].red << (8 - pScrn->rgbBits)); - outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits)); - outSISREG(SISCOLDATA, colors[index/2].blue << (8 - pScrn->rgbBits)); + if(dogamma1) { + orSISIDXREG(SISSR, 0x07, 0x04); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 64) { /* Paranoia */ + for(j=0; j<4; j++) { + outSISREG(SISCOLIDX, (index * 4) + j); + outSISREG(SISCOLDATA, colors[index/2].red << (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOLDATA, colors[index/2].blue << (8 - pScrn->rgbBits)); + } } - } - } + } + } else { + andSISIDXREG(SISSR, 0x07, ~0x04); + } break; case 24: - orSISIDXREG(SISSR, 0x07, 0x04); - for(i=0; i<numColors; i++) { - index = indices[i]; - if(index < 256) { /* Paranoia */ - outSISREG(SISCOLIDX, index); - outSISREG(SISCOLDATA, colors[index].red); - outSISREG(SISCOLDATA, colors[index].green); - outSISREG(SISCOLDATA, colors[index].blue); - } - } + if(dogamma1) { + orSISIDXREG(SISSR, 0x07, 0x04); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 256) { /* Paranoia */ + outSISREG(SISCOLIDX, index); + outSISREG(SISCOLDATA, colors[index].red); + outSISREG(SISCOLDATA, colors[index].green); + outSISREG(SISCOLDATA, colors[index].blue); + } + } + } else { + andSISIDXREG(SISSR, 0x07, ~0x04); + } break; #endif default: - if(pScrn->rgbBits == 8) + if((pScrn->rgbBits == 8) && (dogamma1)) orSISIDXREG(SISSR, 0x07, 0x04); else andSISIDXREG(SISSR, 0x07, ~0x04); @@ -1917,18 +1765,34 @@ SISLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, } } - switch(pSiS->VGAEngine) { - case SIS_300_VGA: - case SIS_315_VGA: - if(pSiS->VBFlags & CRT2_ENABLE) { - /* TW: Only the SiS bridges support a CRT2 palette */ - if(pSiS->VBFlags & VB_SISBRIDGE) { - (*pSiS->LoadCRT2Palette)(pScrn, numColors, indices, - colors, pVisual); - } - } - break; - } + if(pSiS->VGAEngine == SIS_315_VGA) { + outSISIDXREG(SISSR, 0x1f, backup); + inSISIDXREG(SISSR, 0x07, backup); + if((backup & 0x04) && (resetxvgamma) && (pSiS->ResetXvGamma)) { + (pSiS->ResetXvGamma)(pScrn); + } + } + +#ifdef SISDUALHEAD + } + + if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) { +#endif + + switch(pSiS->VGAEngine) { + case SIS_300_VGA: + case SIS_315_VGA: + if(pSiS->VBFlags & CRT2_ENABLE) { + /* Only the SiS bridges support a CRT2 palette */ + if(pSiS->VBFlags & VB_SISBRIDGE) { + (*pSiS->LoadCRT2Palette)(pScrn, numColors, indices, colors, pVisual); + } + } + } + +#ifdef SISDUALHEAD + } +#endif } @@ -1937,110 +1801,88 @@ SiS301LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, VisualPtr pVisual) { SISPtr pSiS = SISPTR(pScrn); - int i, index; + int i, j, index; + Bool dogamma2 = pSiS->CRT2gamma; +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiS->DualHeadMode) dogamma2 = pSiSEnt->CRT2gamma; +#endif PDEBUG(ErrorF("SiS301LoadPalette(%d)\n", numColors)); - for(i=0; i<numColors; i++) { + /* 301B-DH does not support a color palette for LCD */ + if((pSiS->VBFlags & VB_30xBDH) && (pSiS->VBFlags & CRT2_LCD)) return; + + switch(pSiS->CurrentLayout.depth) { +#ifdef SISGAMMA + case 15: + if(dogamma2) { + orSISIDXREG(SISPART4, 0x0d, 0x08); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 32) { /* Paranoia */ + for(j=0; j<8; j++) { + outSISREG(SISCOL2IDX, (index * 8) + j); + outSISREG(SISCOL2DATA, colors[index].red << (8- pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index].blue << (8 - pScrn->rgbBits)); + } + } + } + } else { + andSISIDXREG(SISPART4, 0x0d, ~0x08); + } + break; + case 16: + if(dogamma2) { + orSISIDXREG(SISPART4, 0x0d, 0x08); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 64) { /* Paranoia */ + for(j=0; j<4; j++) { + outSISREG(SISCOL2IDX, (index * 4) + j); + outSISREG(SISCOL2DATA, colors[index/2].red << (8 - pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index].green << (8 - pScrn->rgbBits)); + outSISREG(SISCOL2DATA, colors[index/2].blue << (8 - pScrn->rgbBits)); + } + } + } + } else { + andSISIDXREG(SISPART4, 0x0d, ~0x08); + } + break; + case 24: + if(dogamma2) { + orSISIDXREG(SISPART4, 0x0d, 0x08); + for(i=0; i<numColors; i++) { + index = indices[i]; + if(index < 256) { /* Paranoia */ + outSISREG(SISCOL2IDX, index); + outSISREG(SISCOL2DATA, colors[index].red); + outSISREG(SISCOL2DATA, colors[index].green); + outSISREG(SISCOL2DATA, colors[index].blue); + } + } + } else { + andSISIDXREG(SISPART4, 0x0d, ~0x08); + } + break; +#endif + default: + if((pScrn->rgbBits == 8) && (dogamma2)) + orSISIDXREG(SISPART4, 0x0d, 0x08); + else + andSISIDXREG(SISPART4, 0x0d, ~0x08); + for(i=0; i<numColors; i++) { index = indices[i]; outSISREG(SISCOL2IDX, index); outSISREG(SISCOL2DATA, colors[index].red); outSISREG(SISCOL2DATA, colors[index].green); outSISREG(SISCOL2DATA, colors[index].blue); - } -} - - -#ifdef DEBUG -/* TW: Debug function to dump registers */ -void SiSIODump(ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - int i, max3c4, min3d4, max3d4; - unsigned char temp; - - switch (pSiS->Chipset) { - case PCI_CHIP_SIS6326: - max3c4 = 0x3F; - max3d4 = 0x19; - min3d4 = 0x26; - break; - case PCI_CHIP_SIS530: - max3c4 = 0x3F; - max3d4 = 0x19; - min3d4 = 0x26; - break; - case PCI_CHIP_SIS300: - case PCI_CHIP_SIS630: - case PCI_CHIP_SIS540: - max3c4 = 0x3D; - max3d4 = 0x37; - min3d4 = 0x30; - break; - case PCI_CHIP_SIS550: - case PCI_CHIP_SIS650: - case PCI_CHIP_SIS315: - case PCI_CHIP_SIS315H: - case PCI_CHIP_SIS315PRO: - case PCI_CHIP_SIS330: - max3c4 = 0x3D; - max3d4 = 0x5f; - min3d4 = 0x30; - break; - default: - max3c4 = 0x38; - max3d4 = 0x19; - min3d4 = 0x26; - } - /* dump Misc Registers */ - temp = inb(pSiS->RelIO+0x4c); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Misc Output 3CC=%x\n", temp); - - temp = inb(pSiS->RelIO+0x4a); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Feature Control 3CA=%x\n", temp); - - /* Dump GR */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Registers 3CE\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n"); - for (i=0; i<=8; i++) { - inSISIDXREG(SISGR, i, temp); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp); - } - - /* dump SR0 ~ SR4 */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Registers 3C4\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n"); - for (i=0; i<=4; i++) { - inSISIDXREG(SISSR, i, temp); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp); - } - - /* dump extended SR */ -#ifdef UNLOCK_ALWAYS - sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); -#endif - for (i=5; i<=max3c4; i++) { - inSISIDXREG(SISSR, i, temp); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp); - } - - /* dump CR0 ~ CR18 */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Registers 3D4\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-------------\n"); - for (i=0; i<=0x18; i++) { - inSISIDXREG(SISCR, i, temp); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp); - } - /* dump extended CR */ - for (i=min3d4; i<=max3d4; i++) { - inSISIDXREG(SISCR, i, temp); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[%2x]=%2x\n", i, temp); - } + } + } } -#endif void SISDACPreInit(ScrnInfoPtr pScrn) @@ -2054,23 +1896,22 @@ SISDACPreInit(ScrnInfoPtr pScrn) case PCI_CHIP_SIS315H: case PCI_CHIP_SIS315PRO: case PCI_CHIP_SIS330: - pSiS->MaxClock = SiSMemBandWidth(pScrn); - pSiS->SiSSave = SiS310Save; + case PCI_CHIP_SIS660: + pSiS->MaxClock = SiSMemBandWidth(pScrn, FALSE); + pSiS->SiSSave = SiS315Save; pSiS->SiSSave2 = SiS301Save; pSiS->SiSSave3 = SiS301BSave; pSiS->SiSSaveLVDSChrontel = SiSLVDSChrontelSave; - pSiS->SiSRestore = SiS310Restore; + pSiS->SiSRestore = SiS315Restore; pSiS->SiSRestore2 = SiS301Restore; pSiS->SiSRestore3 = SiS301BRestore; pSiS->SiSRestoreLVDSChrontel = SiSLVDSChrontelRestore; pSiS->LoadCRT2Palette = SiS301LoadPalette; - pSiS->SetThreshold = SiSThreshold; - pSiS->i2cInit = NULL; /* SiSI2CInit; */ break; case PCI_CHIP_SIS300: case PCI_CHIP_SIS630: case PCI_CHIP_SIS540: - pSiS->MaxClock = SiSMemBandWidth(pScrn); + pSiS->MaxClock = SiSMemBandWidth(pScrn, FALSE); pSiS->SiSSave = SiS300Save; pSiS->SiSSave2 = SiS301Save; pSiS->SiSSave3 = SiS301BSave; @@ -2080,18 +1921,14 @@ SISDACPreInit(ScrnInfoPtr pScrn) pSiS->SiSRestore3 = SiS301BRestore; pSiS->SiSRestoreLVDSChrontel = SiSLVDSChrontelRestore; pSiS->LoadCRT2Palette = SiS301LoadPalette; - pSiS->SetThreshold = SiSThreshold; - pSiS->i2cInit = NULL; /* SiSI2CInit; */ break; case PCI_CHIP_SIS5597: case PCI_CHIP_SIS6326: case PCI_CHIP_SIS530: default: - pSiS->MaxClock = SiSMemBandWidth(pScrn); + pSiS->MaxClock = SiSMemBandWidth(pScrn, FALSE); pSiS->SiSRestore = SiSRestore; pSiS->SiSSave = SiSSave; - pSiS->SetThreshold = SiSThreshold; - pSiS->i2cInit = NULL; break; } } @@ -2101,8 +1938,8 @@ SetBlock(CARD16 port, CARD8 from, CARD8 to, CARD8 *DataPtr) { CARD8 index; - for (index=from; index <= to; index++, DataPtr++) { - outSISIDXREG(port, index, *DataPtr); + for(index = from; index <= to; index++, DataPtr++) { + outSISIDXREG(port, index, *DataPtr); } } @@ -2120,12 +1957,12 @@ SiS6326SetTVReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data) unsigned char SiS6326GetTVReg(ScrnInfoPtr pScrn, CARD8 index) { - SISPtr pSiS = SISPTR(pScrn); - unsigned char data; + SISPtr pSiS = SISPTR(pScrn); + unsigned char data; - outSISIDXREG(SISCR, 0xE0, index); - inSISIDXREG(SISCR, 0xE1, data); - return(data); + outSISIDXREG(SISCR, 0xE0, index); + inSISIDXREG(SISCR, 0xE1, data); + return(data); } void @@ -2139,10 +1976,10 @@ SiS6326SetXXReg(ScrnInfoPtr pScrn, CARD8 index, CARD8 data) unsigned char SiS6326GetXXReg(ScrnInfoPtr pScrn, CARD8 index) { - SISPtr pSiS = SISPTR(pScrn); - unsigned char data; + SISPtr pSiS = SISPTR(pScrn); + unsigned char data; - outSISIDXREG(SISCR, 0xE2, index); - inSISIDXREG(SISCR, 0xE3, data); - return(data); + outSISIDXREG(SISCR, 0xE2, index); + inSISIDXREG(SISCR, 0xE3, data); + return(data); } |