summaryrefslogtreecommitdiff
path: root/src/sis_dac.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sis_dac.c')
-rw-r--r--src/sis_dac.c1825
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);
}