diff options
author | alex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2003-10-07 23:12:16 +0000 |
---|---|---|
committer | alex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2003-10-07 23:12:16 +0000 |
commit | e441a33600029f74647539267079bc141f6669bd (patch) | |
tree | a6153bc326006ccc91dd50fb20f0262f9d6ac675 /vidix/drivers | |
parent | c1d54011c1ccb9afd4f26dbdb0c37a02b323a33c (diff) | |
download | mpv-e441a33600029f74647539267079bc141f6669bd.tar.bz2 mpv-e441a33600029f74647539267079bc141f6669bd.tar.xz |
SiS 650/651/740/etc driver by Jake Page <jake@CS.Stanford.EDU>
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@11039 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'vidix/drivers')
-rw-r--r-- | vidix/drivers/Makefile | 14 | ||||
-rw-r--r-- | vidix/drivers/sis_bridge.c | 827 | ||||
-rw-r--r-- | vidix/drivers/sis_defs.h | 106 | ||||
-rw-r--r-- | vidix/drivers/sis_regs.h | 412 | ||||
-rw-r--r-- | vidix/drivers/sis_vid.c | 1561 |
5 files changed, 2919 insertions, 1 deletions
diff --git a/vidix/drivers/Makefile b/vidix/drivers/Makefile index 0ff7f35b21..244e34245d 100644 --- a/vidix/drivers/Makefile +++ b/vidix/drivers/Makefile @@ -52,7 +52,13 @@ NVIDIA_OBJS=nvidia_vid.o NVIDIA_LIBS=-L../../libdha -ldha -lm NVIDIA_CFLAGS=$(OPTFLAGS) -fPIC -I. -I.. -all: $(CYBERBLADE_VID) $(RADEON_VID) $(RAGE128_VID) $(MACH64_VID) $(NVIDIA_VID) $(GENFB_VID) $(MGA_VID) $(MGA_CRTC2_VID) $(PM3_VID) +SIS_VID=sis_vid.so +SIS_SRCS=sis_vid.c sis_bridge.c +SIS_OBJS=sis_vid.o sis_bridge.o +SIS_LIBS=-L../../libdha -ldha +SIS_CFLAGS=$(OPTFLAGS) -fPIC -I. -I.. + +all: $(CYBERBLADE_VID) $(RADEON_VID) $(RAGE128_VID) $(MACH64_VID) $(NVIDIA_VID) $(GENFB_VID) $(MGA_VID) $(MGA_CRTC2_VID) $(PM3_VID) $(SIS_VID) .SUFFIXES: .c .o @@ -113,6 +119,12 @@ $(MGA_CRTC2_OBJS): $(MGA_CRTC2_SRCS) $(MGA_CRTC2_VID): $(MGA_CRTC2_OBJS) $(CC) -shared $(MGA_CRTC2_OBJS) $(MGA_CRTC2_LIBS) -Wl,-soname,$(MGA_CRTC2_VID) -o $(MGA_CRTC2_VID) +$(SIS_OBJS): $(SIS_SRCS) + $(CC) -c $(SIS_CFLAGS) -o $@ $(basename $@).c + +$(SIS_VID): $(SIS_OBJS) + $(LD) -g $(SIS_LIBS) -shared -soname $(SIS_VID) -o $(SIS_VID) $(SIS_OBJS) + clean: rm -f *.o *.so *~ diff --git a/vidix/drivers/sis_bridge.c b/vidix/drivers/sis_bridge.c new file mode 100644 index 0000000000..bde297347d --- /dev/null +++ b/vidix/drivers/sis_bridge.c @@ -0,0 +1,827 @@ +/** + Video bridge detection for SiS 300 and 310/325 series chips. + + Copyright 2003 Jake Page, Sugar Media. + + Based on SiS Xv driver: + Copyright 2002-2003 by Thomas Winischhofer, Vienna, Austria. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +**/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +#include "sis_regs.h" +#include "sis_defs.h" + + +static void sis_ddc2_delay(unsigned short delaytime) +{ + unsigned short i; + int temp; + + for (i = 0; i < delaytime; i++) { + inSISIDXREG(SISSR, 0x05, temp); + } +} + + +static int sis_do_sense(int tempbl, int tempbh, int tempcl, int tempch) +{ + int temp; + + outSISIDXREG(SISPART4, 0x11, tempbl); + temp = tempbh | tempcl; + setSISIDXREG(SISPART4, 0x10, 0xe0, temp); + //usleep(200000); + sis_ddc2_delay(0x1000); + tempch &= 0x7f; + inSISIDXREG(SISPART4, 0x03, temp); + temp ^= 0x0e; + temp &= tempch; + return (temp == tempch); +} + + +/* sense connected devices on 30x bridge */ +static void sis_sense_30x() +{ + unsigned char backupP4_0d, backupP2_00, biosflag; + unsigned char testsvhs_tempbl, testsvhs_tempbh; + unsigned char testsvhs_tempcl, testsvhs_tempch; + unsigned char testcvbs_tempbl, testcvbs_tempbh; + unsigned char testcvbs_tempcl, testcvbs_tempch; + unsigned char testvga2_tempbl, testvga2_tempbh; + unsigned char testvga2_tempcl, testvga2_tempch; + int myflag, result = 0, i, j, haveresult; + unsigned short temp; + + inSISIDXREG(SISPART4, 0x0d, backupP4_0d); + outSISIDXREG(SISPART4, 0x0d, (backupP4_0d | 0x04)); + + inSISIDXREG(SISPART2, 0x00, backupP2_00); + outSISIDXREG(SISPART2, 0x00, (backupP2_00 | 0x1c)); + + sis_do_sense(0, 0, 0, 0); + + if ((sis_vga_engine == SIS_315_VGA) || + (sis_device_id == DEVICE_SIS_300)) { +#if 0 + if (0 /*pSiS->sishw_ext.UseROM */ ) { + if (sis_vga_engine == SIS_300_VGA) + temp = 0xfe; + else { + temp = 0xf3; + if (sis_device_id == DEVICE_SIS_330) + temp = 0x11b; + } + if (pSiS->BIOS[temp] & 0x08) { + if (sis_verbose > 1) { + printf + ("[SiS] SiS30x: Video bridge has DVI-I TMDS/VGA combo connector\n"); + } + orSISIDXREG(SISCR, 0x32, 0x80); + } else { + andSISIDXREG(SISCR, 0x32, 0x7f); + } + } +#endif + } + + if (sis_vga_engine == SIS_300_VGA) { + if (0 /*pSiS->sishw_ext.UseROM */ ) { +#if 0 + testvga2_tempbh = pSiS->BIOS[0xf9]; + testvga2_tempbl = pSiS->BIOS[0xf8]; + testsvhs_tempbh = pSiS->BIOS[0xfb]; + testsvhs_tempbl = pSiS->BIOS[0xfa]; + testcvbs_tempbh = pSiS->BIOS[0xfd]; + testcvbs_tempbl = pSiS->BIOS[0xfc]; + biosflag = pSiS->BIOS[0xfe]; +#endif + } else { + testvga2_tempbh = 0x00; + testvga2_tempbl = 0xd1; + testsvhs_tempbh = 0x00; + testsvhs_tempbl = 0xb9; + testcvbs_tempbh = 0x00; + testcvbs_tempbl = 0xb3; + biosflag = 0; + } + if (sis_vbflags & (VB_301B | VB_302B | VB_301LV | VB_302LV)) { + testvga2_tempbh = 0x01; + testvga2_tempbl = 0x90; + testsvhs_tempbh = 0x01; + testsvhs_tempbl = 0x6b; + testcvbs_tempbh = 0x01; + testcvbs_tempbl = 0x74; + } + inSISIDXREG(SISPART4, 0x01, myflag); + if (myflag & 0x04) { + testvga2_tempbh = 0x00; + testvga2_tempbl = 0xfd; + testsvhs_tempbh = 0x00; + testsvhs_tempbl = 0xdd; + testcvbs_tempbh = 0x00; + testcvbs_tempbl = 0xee; + } + testvga2_tempch = 0x0e; + testvga2_tempcl = 0x08; + testsvhs_tempch = 0x06; + testsvhs_tempcl = 0x04; + testcvbs_tempch = 0x08; + testcvbs_tempcl = 0x04; + + if (sis_device_id == DEVICE_SIS_300) { + inSISIDXREG(SISSR, 0x3b, myflag); + if (!(myflag & 0x01)) { + testvga2_tempbh = 0x00; + testvga2_tempbl = 0x00; + testvga2_tempch = 0x00; + testvga2_tempcl = 0x00; + } + } + } else { + if (0 /*pSiS->sishw_ext.UseROM */ ) { +#if 0 + if (sis_device_id == DEVICE_SIS_330) { + testvga2_tempbh = pSiS->BIOS[0xe6]; + testvga2_tempbl = pSiS->BIOS[0xe5]; + testsvhs_tempbh = pSiS->BIOS[0xe8]; + testsvhs_tempbl = pSiS->BIOS[0xe7]; + testcvbs_tempbh = pSiS->BIOS[0xea]; + testcvbs_tempbl = pSiS->BIOS[0xe9]; + biosflag = pSiS->BIOS[0x11b]; + } else { + testvga2_tempbh = pSiS->BIOS[0xbe]; + testvga2_tempbl = pSiS->BIOS[0xbd]; + testsvhs_tempbh = pSiS->BIOS[0xc0]; + testsvhs_tempbl = pSiS->BIOS[0xbf]; + testcvbs_tempbh = pSiS->BIOS[0xc2]; + testcvbs_tempbl = pSiS->BIOS[0xc1]; + biosflag = pSiS->BIOS[0xf3]; + } +#endif + } else { + testvga2_tempbh = 0x00; + testvga2_tempbl = 0xd1; + testsvhs_tempbh = 0x00; + testsvhs_tempbl = 0xb9; + testcvbs_tempbh = 0x00; + testcvbs_tempbl = 0xb3; + biosflag = 0; + } + + if (sis_vbflags & (VB_301B | VB_302B | VB_301LV | VB_302LV)) { + if (0 /*pSiS->sishw_ext.UseROM */ ) { +#if 0 + if (sis_device_id == DEVICE_SIS_330) { + testvga2_tempbh = pSiS->BIOS[0xec]; + testvga2_tempbl = pSiS->BIOS[0xeb]; + testsvhs_tempbh = pSiS->BIOS[0xee]; + testsvhs_tempbl = pSiS->BIOS[0xed]; + testcvbs_tempbh = pSiS->BIOS[0xf0]; + testcvbs_tempbl = pSiS->BIOS[0xef]; + } else { + testvga2_tempbh = pSiS->BIOS[0xc4]; + testvga2_tempbl = pSiS->BIOS[0xc3]; + testsvhs_tempbh = pSiS->BIOS[0xc6]; + testsvhs_tempbl = pSiS->BIOS[0xc5]; + testcvbs_tempbh = pSiS->BIOS[0xc8]; + testcvbs_tempbl = pSiS->BIOS[0xc7]; + } +#endif + } else { + if (sis_vbflags & (VB_301B | VB_302B)) { + testvga2_tempbh = 0x01; + testvga2_tempbl = 0x90; + testsvhs_tempbh = 0x01; + testsvhs_tempbl = 0x6b; + testcvbs_tempbh = 0x01; + testcvbs_tempbl = 0x74; + } else { + testvga2_tempbh = 0x00; + testvga2_tempbl = 0x00; + testsvhs_tempbh = 0x02; + testsvhs_tempbl = 0x00; + testcvbs_tempbh = 0x01; + testcvbs_tempbl = 0x00; + } + } + } + if (sis_vbflags & (VB_301 | VB_301B | VB_302B)) { + inSISIDXREG(SISPART4, 0x01, myflag); + if (myflag & 0x04) { + testvga2_tempbh = 0x00; + testvga2_tempbl = 0xfd; + testsvhs_tempbh = 0x00; + testsvhs_tempbl = 0xdd; + testcvbs_tempbh = 0x00; + testcvbs_tempbl = 0xee; + } + } + if (sis_vbflags & (VB_301LV | VB_302LV)) { + /* TW: No VGA2 or SCART on LV bridges */ + testvga2_tempbh = 0x00; + testvga2_tempbl = 0x00; + testvga2_tempch = 0x00; + testvga2_tempcl = 0x00; + testsvhs_tempch = 0x04; + testsvhs_tempcl = 0x08; + testcvbs_tempch = 0x08; + testcvbs_tempcl = 0x08; + } else { + testvga2_tempch = 0x0e; + testvga2_tempcl = 0x08; + testsvhs_tempch = 0x06; + testsvhs_tempcl = 0x04; + testcvbs_tempch = 0x08; + testcvbs_tempcl = 0x04; + } + } + + /* XXX: ?? andSISIDXREG(SISCR, 0x32, ~0x14); */ + /* pSiS->postVBCR32 &= ~0x14; */ + + /* scan for VGA2/SCART */ + if (testvga2_tempch || testvga2_tempcl || + testvga2_tempbh || testvga2_tempbl) { + + haveresult = 0; + for (j = 0; j < 10; j++) { + result = 0; + for (i = 0; i < 3; i++) { + if (sis_do_sense(testvga2_tempbl, testvga2_tempbh, + testvga2_tempcl, testvga2_tempch)) + result++; + } + if ((result == 0) || (result >= 2)) + break; + } + if (result) { + if (biosflag & 0x01) { + if (sis_verbose > 1) { + printf + ("[SiS] SiS30x: Detected TV connected to SCART output\n"); + } + sis_vbflags |= TV_SCART; + orSISIDXREG(SISCR, 0x32, 0x04); + /*pSiS->postVBCR32 |= 0x04; */ + } else { + if (sis_verbose > 1) { + printf + ("[SiS] SiS30x: Detected secondary VGA connection\n"); + } + sis_vbflags |= VGA2_CONNECTED; + orSISIDXREG(SISCR, 0x32, 0x10); + /*pSiS->postVBCR32 |= 0x10; */ + } + } + } + + /* scanning for TV */ + + /* XXX: ?? andSISIDXREG(SISCR, 0x32, ~0x03); */ + /* pSiS->postVBCR32 &= ~0x03; */ + + result = sis_do_sense(testsvhs_tempbl, testsvhs_tempbh, + testsvhs_tempcl, testsvhs_tempch); + + + haveresult = 0; + for (j = 0; j < 10; j++) { + result = 0; + for (i = 0; i < 3; i++) { + if (sis_do_sense(testsvhs_tempbl, testsvhs_tempbh, + testsvhs_tempcl, testsvhs_tempch)) + result++; + } + if ((result == 0) || (result >= 2)) + break; + } + if (result) { + if (sis_verbose > 1) { + printf + ("[SiS] SiS30x: Detected TV connected to SVIDEO output\n"); + } + /* TW: So we can be sure that there IS a SVIDEO output */ + sis_vbflags |= TV_SVIDEO; + orSISIDXREG(SISCR, 0x32, 0x02); + //pSiS->postVBCR32 |= 0x02; + } + + if ((biosflag & 0x02) || (!(result))) { + haveresult = 0; + for (j = 0; j < 10; j++) { + result = 0; + for (i = 0; i < 3; i++) { + if (sis_do_sense(testcvbs_tempbl, testcvbs_tempbh, + testcvbs_tempcl, testcvbs_tempch)) + result++; + } + if ((result == 0) || (result >= 2)) + break; + } + if (result) { + if (sis_verbose > 1) { + printf + ("[SiS] SiS30x: Detected TV connected to COMPOSITE output\n"); + } + sis_vbflags |= TV_AVIDEO; + orSISIDXREG(SISCR, 0x32, 0x01); + //pSiS->postVBCR32 |= 0x01; + } + } + + sis_do_sense(0, 0, 0, 0); + + outSISIDXREG(SISPART2, 0x00, backupP2_00); + outSISIDXREG(SISPART4, 0x0d, backupP4_0d); +} + + +static void sis_detect_crt1() +{ + unsigned char CR32; + unsigned char CRT1Detected = 0; + unsigned char OtherDevices = 0; + + if (!(sis_vbflags & VB_VIDEOBRIDGE)) { + sis_crt1_off = 0; + return; + } + + inSISIDXREG(SISCR, 0x32, CR32); + + if (CR32 & 0x20) + CRT1Detected = 1; + if (CR32 & 0x5F) + OtherDevices = 1; + + if (sis_crt1_off == -1) { + if (!CRT1Detected) { + /* BIOS detected no CRT1. */ + /* If other devices exist, switch it off */ + if (OtherDevices) + sis_crt1_off = 1; + else + sis_crt1_off = 0; + } else { + /* BIOS detected CRT1, leave/switch it on */ + sis_crt1_off = 0; + } + } + if (sis_verbose > 0) { + printf("[SiS] %sCRT1 connection detected\n", + sis_crt1_off ? "No " : ""); + } +} + + +static void sis_detect_lcd() +{ + unsigned char CR32, CR36, CR37; + + if (!(sis_vbflags & VB_VIDEOBRIDGE)) { + return; + } + + inSISIDXREG(SISCR, 0x32, CR32); + + if (CR32 & 0x08) + sis_vbflags |= CRT2_LCD; + + /* DDC detection of LCD - not supported yet */ + + /* Get other misc info about LCD - not supported */ +} + + +static void sis_detect_tv() +{ + unsigned char SR16, SR38, CR32, CR38 = 0, CR79; + int temp = 0; + + if (!(sis_vbflags & VB_VIDEOBRIDGE)) + return; + + inSISIDXREG(SISCR, 0x32, CR32); + inSISIDXREG(SISSR, 0x16, SR16); + inSISIDXREG(SISSR, 0x38, SR38); + switch (sis_vga_engine) { + case SIS_300_VGA: + if (sis_device_id == DEVICE_SIS_630_VGA) + temp = 0x35; + break; + case SIS_315_VGA: + temp = 0x38; + break; + } + if (temp) { + inSISIDXREG(SISCR, temp, CR38); + } + + if (CR32 & 0x47) + sis_vbflags |= CRT2_TV; + + if (CR32 & 0x04) + sis_vbflags |= TV_SCART; + else if (CR32 & 0x02) + sis_vbflags |= TV_SVIDEO; + else if (CR32 & 0x01) + sis_vbflags |= TV_AVIDEO; + else if (CR32 & 0x40) + sis_vbflags |= (TV_SVIDEO | TV_HIVISION); + else if ((CR38 & 0x04) && (sis_vbflags & (VB_301LV | VB_302LV))) + sis_vbflags |= TV_HIVISION_LV; + else if ((CR38 & 0x04) && (sis_vbflags & VB_CHRONTEL)) + sis_vbflags |= (TV_CHSCART | TV_PAL); + else if ((CR38 & 0x08) && (sis_vbflags & VB_CHRONTEL)) + sis_vbflags |= (TV_CHHDTV | TV_NTSC); + + if (sis_vbflags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION)) { + if (sis_vga_engine == SIS_300_VGA) { + /* TW: Should be SR38 here as well, but this + * does not work. Looks like a BIOS bug (2.04.5c). + */ + if (SR16 & 0x20) + sis_vbflags |= TV_PAL; + else + sis_vbflags |= TV_NTSC; + } else if ((sis_device_id == DEVICE_SIS_550_VGA)) { + inSISIDXREG(SISCR, 0x79, CR79); + if (CR79 & 0x08) { + inSISIDXREG(SISCR, 0x79, CR79); + CR79 >>= 5; + } + if (CR79 & 0x01) { + sis_vbflags |= TV_PAL; + if (CR38 & 0x40) + sis_vbflags |= TV_PALM; + else if (CR38 & 0x80) + sis_vbflags |= TV_PALN; + } else + sis_vbflags |= TV_NTSC; + } else if ((sis_device_id == DEVICE_SIS_650_VGA)) { + inSISIDXREG(SISCR, 0x79, CR79); + if (CR79 & 0x20) { + sis_vbflags |= TV_PAL; + if (CR38 & 0x40) + sis_vbflags |= TV_PALM; + else if (CR38 & 0x80) + sis_vbflags |= TV_PALN; + } else + sis_vbflags |= TV_NTSC; + } else { /* 315, 330 */ + if (SR38 & 0x01) { + sis_vbflags |= TV_PAL; + if (CR38 & 0x40) + sis_vbflags |= TV_PALM; + else if (CR38 & 0x80) + sis_vbflags |= TV_PALN; + } else + sis_vbflags |= TV_NTSC; + } + } + + if (sis_vbflags & + (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION | TV_CHSCART | + TV_CHHDTV)) { + if (sis_verbose > 0) { + printf("[SiS] %sTV standard %s\n", + (sis_vbflags & (TV_CHSCART | TV_CHHDTV)) ? "Using " : + "Detected default ", + (sis_vbflags & TV_NTSC) ? ((sis_vbflags & TV_CHHDTV) ? + "480i HDTV" : "NTSC") + : ((sis_vbflags & TV_PALM) ? "PALM" + : ((sis_vbflags & TV_PALN) ? "PALN" : "PAL"))); + } + } + +} + + +static void sis_detect_crt2() +{ + unsigned char CR32; + + if (!(sis_vbflags & VB_VIDEOBRIDGE)) + return; + + /* CRT2-VGA not supported on LVDS and 30xLV */ + if (sis_vbflags & (VB_LVDS | VB_301LV | VB_302LV)) + return; + + inSISIDXREG(SISCR, 0x32, CR32); + + if (CR32 & 0x10) + sis_vbflags |= CRT2_VGA; + +#if 0 + if (!(pSiS->nocrt2ddcdetection)) { + if (sis_vbflags & (VB_301B | VB_302B)) { + if (!(sis_vbflags & (CRT2_VGA | CRT2_LCD))) { + printf + ("[SiS] BIOS detected no secondary VGA, sensing via DDC\n"); + if (SiS_SenseVGA2DDC(pSiS->SiS_Pr, pSiS)) { + printf + ("[SiS] DDC error during secondary VGA detection\n"); + } else { + inSISIDXREG(SISCR, 0x32, CR32); + if (CR32 & 0x10) { + sis_vbflags |= CRT2_VGA; + /*pSiS->postVBCR32 |= 0x10; */ + printf + ("[SiS] Detected secondary VGA connection\n"); + } else { + printf + ("[SiS] No secondary VGA connection detected\n"); + } + } + } + } + } +#endif + +} + + +/* Preinit: detect video bridge and sense connected devs */ +static void sis_detect_video_bridge() +{ + int temp, temp1, temp2; + + + sis_vbflags = 0; + + if (sis_vga_engine != SIS_300_VGA && sis_vga_engine != SIS_315_VGA) + return; + + inSISIDXREG(SISPART4, 0x00, temp); + temp &= 0x0F; + if (temp == 1) { + inSISIDXREG(SISPART4, 0x01, temp1); + temp1 &= 0xff; + if (temp1 >= 0xE0) { + sis_vbflags |= VB_302LV; + //pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; + if (sis_verbose > 1) { + printf + ("[SiS] Detected SiS302LV video bridge (ID 1; Revision 0x%x)\n", + temp1); + } + + } else if (temp1 >= 0xD0) { + sis_vbflags |= VB_301LV; + //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; + if (sis_verbose > 1) { + printf + ("[SiS] Detected SiS301LV video bridge (ID 1; Revision 0x%x)\n", + temp1); + } + } else if (temp1 >= 0xB0) { + sis_vbflags |= VB_301B; + //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301B; + inSISIDXREG(SISPART4, 0x23, temp2); + if (!(temp2 & 0x02)) + sis_vbflags |= VB_30xBDH; + if (sis_verbose > 1) { + printf + ("[SiS] Detected SiS301B%s video bridge (Revision 0x%x)\n", + (temp2 & 0x02) ? "" : " (DH)", temp1); + } + } else { + sis_vbflags |= VB_301; + //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301; + if (sis_verbose > 1) { + printf + ("[SiS] Detected SiS301 video bridge (Revision 0x%x)\n", + temp1); + } + } + + sis_sense_30x(); + + } else if (temp == 2) { + + inSISIDXREG(SISPART4, 0x01, temp1); + temp1 &= 0xff; + if (temp1 >= 0xE0) { + sis_vbflags |= VB_302LV; + //pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; + if (sis_verbose > 1) { + printf + ("[SiS] Detected SiS302LV video bridge (ID 2; Revision 0x%x)\n", + temp1); + } + } else if (temp1 >= 0xD0) { + sis_vbflags |= VB_301LV; + //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; + if (sis_verbose > 1) { + printf + ("[SiS] Detected SiS301LV video bridge (ID 2; Revision 0x%x)\n", + temp1); + } + } else { + sis_vbflags |= VB_302B; + //pSiS->sishw_ext.ujVBChipID = VB_CHIP_302B; + inSISIDXREG(SISPART4, 0x23, temp2); + if (!(temp & 0x02)) + sis_vbflags |= VB_30xBDH; + if (sis_verbose > 1) { + printf + ("[SiS] Detected SiS302B%s video bridge (Revision 0x%x)\n", + (temp2 & 0x02) ? "" : " (DH)", temp1); + } + } + + sis_sense_30x(); + + } else if (temp == 3) { + if (sis_verbose > 1) { + printf("[SiS] Detected SiS303 video bridge - not supported\n"); + } + } else { + /* big scary mess of code to handle unknown or Chrontel LVDS */ + /* skipping it for now */ + if (sis_verbose > 1) { + printf + ("[SiS] Detected Chrontel video bridge - not supported\n"); + } + } + + /* this is probably not relevant to video overlay driver... */ + /* detects if brdige uses LCDA for low res text modes */ + if (sis_vga_engine == SIS_315_VGA) { + if (sis_vbflags & (VB_302B | VB_301LV | VB_302LV)) { +#if 0 + if (pSiS->sisfblcda != 0xff) { + if ((pSiS->sisfblcda & 0x03) == 0x03) { + //pSiS->SiS_Pr->SiS_UseLCDA = TRUE; + sis_vbflags |= VB_USELCDA; + } + } else +#endif + { + inSISIDXREG(SISCR, 0x34, temp); + if (temp <= 0x13) { + inSISIDXREG(SISCR, 0x38, temp); + if ((temp & 0x03) == 0x03) { + //pSiS->SiS_Pr->SiS_UseLCDA = TRUE; + sis_vbflags |= VB_USELCDA; + } else { + inSISIDXREG(SISCR, 0x30, temp); + if (temp & 0x20) { + inSISIDXREG(SISPART1, 0x13, temp); + if (temp & 0x40) { + //pSiS->SiS_Pr->SiS_UseLCDA = TRUE; + sis_vbflags |= VB_USELCDA; + } + } + } + } + } + if (sis_vbflags & VB_USELCDA) { + /* printf("Bridge uses LCDA for low resolution and text modes\n"); */ + } + } + } + + +} + + +/* detect video bridge type and sense connected devices */ +void sis_init_video_bridge() +{ + + sis_detect_video_bridge(); + + sis_detect_crt1(); + //sis_detect_lcd(); + sis_detect_tv(); + sis_detect_crt2(); + + sis_detected_crt2_devices = + sis_vbflags & (CRT2_LCD | CRT2_TV | CRT2_VGA); + + // force crt2 type + if (sis_force_crt2_type == CRT2_DEFAULT) { + if (sis_vbflags & CRT2_VGA) + sis_force_crt2_type = CRT2_VGA; + else if (sis_vbflags & CRT2_LCD) + sis_force_crt2_type = CRT2_LCD; + else if (sis_vbflags & CRT2_TV) + sis_force_crt2_type = CRT2_TV; + } + + switch (sis_force_crt2_type) { + case CRT2_TV: + sis_vbflags = sis_vbflags & ~(CRT2_LCD | CRT2_VGA); + if (sis_vbflags & VB_VIDEOBRIDGE) + sis_vbflags = sis_vbflags | CRT2_TV; + else + sis_vbflags = sis_vbflags & ~(CRT2_TV); + break; + case CRT2_LCD: + sis_vbflags = sis_vbflags & ~(CRT2_TV | CRT2_VGA); + if ((sis_vbflags & VB_VIDEOBRIDGE) /* XXX: && (pSiS->VBLCDFlags) */ + ) + sis_vbflags = sis_vbflags | CRT2_LCD; + else { + sis_vbflags = sis_vbflags & ~(CRT2_LCD); + if (sis_verbose > 0) { + printf + ("[SiS] Can't force CRT2 to LCD, no panel detected\n"); + } + } + break; + case CRT2_VGA: + if (sis_vbflags & VB_LVDS) { + if (sis_verbose > 0) { + printf("[SiS] LVDS does not support secondary VGA\n"); + } + break; + } + if (sis_vbflags & (VB_301LV | VB_302LV)) { + if (sis_verbose > 0) { + printf + ("[SiS] SiS30xLV bridge does not support secondary VGA\n"); + } + break; + } + sis_vbflags = sis_vbflags & ~(CRT2_TV | CRT2_LCD); + if (sis_vbflags & VB_VIDEOBRIDGE) + sis_vbflags = sis_vbflags | CRT2_VGA; + else + sis_vbflags = sis_vbflags & ~(CRT2_VGA); + break; + default: + sis_vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA); + } + + /* CRT2 gamma correction?? */ + + /* other force modes: */ + /* have a 'force tv type' (svideo, composite, scart) option? */ + /* have a 'force crt1 type' (to turn it off, etc??) */ + + /* TW: Check if CRT1 used (or needed; this eg. if no CRT2 detected) */ + if (sis_vbflags & VB_VIDEOBRIDGE) { + + /* TW: No CRT2 output? Then we NEED CRT1! + * We also need CRT1 if depth = 8 and bridge=LVDS|630+301B + */ + if ((!(sis_vbflags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) || ( /*(pScrn->bitsPerPixel == 8) && */ + ((sis_vbflags & (VB_LVDS | VB_CHRONTEL)) || ((sis_vga_engine == SIS_300_VGA) && (sis_vbflags & VB_301B))))) { + sis_crt1_off = 0; + } + /* TW: No CRT2 output? Then we can't use hw overlay on CRT2 */ + if (!(sis_vbflags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) + sis_overlay_on_crt1 = 1; + + } else { /* TW: no video bridge? */ + + /* Then we NEED CRT1... */ + sis_crt1_off = 0; + /* ... and can't use CRT2 for overlay output */ + sis_overlay_on_crt1 = 1; + } + + /* tvstandard options ? */ + + // determine using CRT1 or CRT2? + /* -> NO dualhead right now... */ + if (sis_vbflags & DISPTYPE_DISP2) { + if (sis_crt1_off) { + sis_vbflags |= VB_DISPMODE_SINGLE; + /* TW: No CRT1? Then we use the video overlay on CRT2 */ + sis_overlay_on_crt1 = 0; + } else /* TW: CRT1 and CRT2 - mirror or dual head ----- */ + sis_vbflags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1); + } else { /* TW: CRT1 only ------------------------------- */ + sis_vbflags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1); + } + + if (sis_verbose > 0) { + printf("[SiS] Using hardware overlay on CRT%d\n", + sis_overlay_on_crt1 ? 1 : 2); + } + +} diff --git a/vidix/drivers/sis_defs.h b/vidix/drivers/sis_defs.h new file mode 100644 index 0000000000..79a61a19b2 --- /dev/null +++ b/vidix/drivers/sis_defs.h @@ -0,0 +1,106 @@ +/** + SiS graphics misc definitions. + + Taken from SiS Xv driver: + Copyright 2002-2003 by Thomas Winischhofer, Vienna, Austria. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +**/ + +#ifndef VIDIX_SIS_DEFS_H +#define VIDIX_SIS_DEFS_H + +/** PCI IDs **/ +#define VENDOR_SIS 0x1039 + +#define DEVICE_SIS_300 0x0300 +#define DEVICE_SIS_315H 0x0310 +#define DEVICE_SIS_315 0x0315 +#define DEVICE_SIS_315PRO 0x0325 +#define DEVICE_SIS_330 0x0330 +#define DEVICE_SIS_540 0x0540 +#define DEVICE_SIS_540_VGA 0x5300 +#define DEVICE_SIS_550 0x0550 +#define DEVICE_SIS_550_VGA 0x5315 +#define DEVICE_SIS_630 0x0630 +#define DEVICE_SIS_630_VGA 0x6300 +#define DEVICE_SIS_650 0x0650 +#define DEVICE_SIS_650_VGA 0x6325 +#define DEVICE_SIS_730 0x0730 + + +/* TW: VBFlags */ +#define CRT2_DEFAULT 0x00000001 +#define CRT2_LCD 0x00000002 /* TW: Never change the order of the CRT2_XXX entries */ +#define CRT2_TV 0x00000004 /* (see SISCycleCRT2Type()) */ +#define CRT2_VGA 0x00000008 +#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA) +#define DISPTYPE_DISP2 CRT2_ENABLE +#define TV_NTSC 0x00000010 +#define TV_PAL 0x00000020 +#define TV_HIVISION 0x00000040 +#define TV_HIVISION_LV 0x00000080 +#define TV_TYPE (TV_NTSC | TV_PAL | TV_HIVISION | TV_HIVISION_LV) +#define TV_AVIDEO 0x00000100 +#define TV_SVIDEO 0x00000200 +#define TV_SCART 0x00000400 +#define TV_INTERFACE (TV_AVIDEO | TV_SVIDEO | TV_SCART | TV_CHSCART | TV_CHHDTV) +#define VB_USELCDA 0x00000800 +#define TV_PALM 0x00001000 +#define TV_PALN 0x00002000 +#define TV_CHSCART 0x00008000 +#define TV_CHHDTV 0x00010000 +#define VGA2_CONNECTED 0x00040000 +#define DISPTYPE_CRT1 0x00080000 /* TW: CRT1 connected and used */ +#define DISPTYPE_DISP1 DISPTYPE_CRT1 +#define VB_301 0x00100000 /* Video bridge type */ +#define VB_301B 0x00200000 +#define VB_302B 0x00400000 +#define VB_30xBDH 0x00800000 /* 30xB DH version (w/o LCD support) */ +#define VB_LVDS 0x01000000 +#define VB_CHRONTEL 0x02000000 +#define VB_301LV 0x04000000 +#define VB_302LV 0x08000000 +#define VB_30xLV VB_301LV +#define VB_30xLVX VB_302LV +#define VB_TRUMPION 0x10000000 +#define VB_VIDEOBRIDGE (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV| \ + VB_LVDS|VB_CHRONTEL|VB_TRUMPION) /* TW */ +#define VB_SISBRIDGE (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV) +#define SINGLE_MODE 0x20000000 /* TW: CRT1 or CRT2; determined by DISPTYPE_CRTx */ +#define VB_DISPMODE_SINGLE SINGLE_MODE /* TW: alias */ +#define MIRROR_MODE 0x40000000 /* TW: CRT1 + CRT2 identical (mirror mode) */ +#define VB_DISPMODE_MIRROR MIRROR_MODE /* TW: alias */ +#define DUALVIEW_MODE 0x80000000 /* TW: CRT1 + CRT2 independent (dual head mode) */ +#define VB_DISPMODE_DUAL DUALVIEW_MODE /* TW: alias */ +#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE) /* TW */ + +/* SiS vga engine type */ +#define UNKNOWN_VGA 0 +#define SIS_300_VGA 1 +#define SIS_315_VGA 2 + +extern unsigned int sis_verbose; +extern unsigned short sis_iobase; +extern unsigned int sis_vga_engine; +extern unsigned int sis_vbflags; +extern unsigned int sis_overlay_on_crt1; +extern unsigned int sis_crt1_off; +extern unsigned int sis_detected_crt2_devices; +extern unsigned int sis_force_crt2_type; +extern unsigned int sis_device_id; + +#endif /* VIDIX_SIS_DEFS_H */ diff --git a/vidix/drivers/sis_regs.h b/vidix/drivers/sis_regs.h new file mode 100644 index 0000000000..0157e049a3 --- /dev/null +++ b/vidix/drivers/sis_regs.h @@ -0,0 +1,412 @@ +/** + SiS register definitions and access macros. + From SiS X11 driver. + + Copyright 2001-2003 by Thomas Winischhofer, Vienna, Austria. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +**/ + +#ifndef VIDIX_SIS_REGS_H +#define VIDIX_SIS_REGS_H + +#define inSISREG(base) INPORT8(base) +#define outSISREG(base,val) OUTPORT8(base, val) +#define orSISREG(base,val) do { \ + unsigned char __Temp = INPORT8(base); \ + outSISREG(base, __Temp | (val)); \ + } while (0) +#define andSISREG(base,val) do { \ + unsigned char __Temp = INPORT8(base); \ + outSISREG(base, __Temp & (val)); \ + } while (0) + +#define inSISIDXREG(base,idx,var) do { \ + OUTPORT8(base, idx); var=INPORT8((base)+1); \ + } while (0) +#define outSISIDXREG(base,idx,val) do { \ + OUTPORT8(base, idx); OUTPORT8((base)+1, val); \ + } while (0) +#define orSISIDXREG(base,idx,val) do { \ + unsigned char __Temp; \ + OUTPORT8(base, idx); \ + __Temp = INPORT8((base)+1)|(val); \ + outSISIDXREG(base,idx,__Temp); \ + } while (0) +#define andSISIDXREG(base,idx,and) do { \ + unsigned char __Temp; \ + OUTPORT8(base, idx); \ + __Temp = INPORT8((base)+1)&(and); \ + outSISIDXREG(base,idx,__Temp); \ + } while (0) +#define setSISIDXREG(base,idx,and,or) do { \ + unsigned char __Temp; \ + OUTPORT8(base, idx); \ + __Temp = (INPORT8((base)+1)&(and))|(or); \ + outSISIDXREG(base,idx,__Temp); \ + |