diff options
Diffstat (limited to 'src/sis_vga.c')
-rw-r--r-- | src/sis_vga.c | 650 |
1 files changed, 111 insertions, 539 deletions
diff --git a/src/sis_vga.c b/src/sis_vga.c index 0e0ce37..c7b551c 100644 --- a/src/sis_vga.c +++ b/src/sis_vga.c @@ -1,32 +1,38 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_vga.c,v 1.28 2003/09/04 15:32:45 twini Exp $ */ +/* $XFree86$ */ +/* $XdotOrg$ */ /* * Mode setup and basic video bridge detection * - * Copyright 2001, 2002, 2003 by Thomas Winischhofer, Vienna, Austria. + * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria. * - * Init() function for old series (except for TV and FIFO calculation) based - * on code which was Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * The SISInit() function for old series (except TV and FIFO calculation) + * was previously based on code which was Copyright (C) 1998,1999 by Alan + * Hourihane, Wigan, England. However, the code has been rewritten entirely + * and is - it its current representation - not covered by this old copyright. * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of the copyright holder not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. The copyright holder makes no representations - * about the suitability of this software for any purpose. It is provided - * "as is" without express or implied warranty. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2) Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3) The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Thomas Winischhofer <thomas@winischhofer.net> - * ... + * Author: Thomas Winischhofer <thomas@winischhofer.net> * */ @@ -41,18 +47,14 @@ #include "sis_regs.h" #include "sis_dac.h" -#if 0 -#define TV6326TEST -#endif - static Bool SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode); static Bool SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode); -/* To be used internally only */ -int SISDoSense(ScrnInfoPtr pScrn, int tempbl, int tempbh, int tempcl, int tempch); -void SISSense30x(ScrnInfoPtr pScrn); -int SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl); -void SISSense6326(ScrnInfoPtr pScrn); -static void SiS6326TVDelay(ScrnInfoPtr pScrn, int delay); +static int SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl); +static void SISSense6326(ScrnInfoPtr pScrn); +static void SiS6326TVDelay(ScrnInfoPtr pScrn, int delay); + +extern void SISSense30x(ScrnInfoPtr pScrn, Bool quiet); +extern void SISSenseChrontel(ScrnInfoPtr pScrn, Bool quiet); const CARD8 SiS6326TVRegs1[14] = { 0x00,0x01,0x02,0x03,0x04,0x11,0x12,0x13,0x21,0x26,0x27,0x3a,0x3c,0x43 @@ -67,17 +69,6 @@ const CARD8 SiS6326TVRegs1_NTSC[6][14] = { {0x83,0x5d,0x21,0xbe,0x75,0x03,0x00,0x09,0x08,0x42,0x10,0x4d,0x61,0x79} /* 640x480u */ }; -#ifdef TV6326TEST -const CARD8 SiS6326TVRegs1_NTSC_2[6][3] = { - { 0x00,0x00,0x00}, - { 0x00,0x00,0x00}, - { 0x24,0x92,0x49}, - { 0x24,0x92,0x49}, /* 8a50 */ - { 0x24,0x92,0x49}, /* 640x400, 640x480 */ /* 8afc */ - { 0x21,0xbe,0x75} /* 640x480u */ /* n/a */ -}; -#endif - const CARD8 SiS6326TVRegs2_NTSC[6][54] = { {0x11, 0x17, 0x03, 0x09, 0x94, 0x02, 0x05, 0x06, 0x09, 0x50, 0x0C, 0x0C, 0x06, 0x0D, 0x04, 0x0A, 0x94, 0x06, 0x0D, 0x04, 0x0A, 0x94, @@ -120,17 +111,6 @@ const CARD8 SiS6326TVRegs1_PAL[6][14] = { {0x81,0x63,0xa4,0x03,0xd9,0x01,0x00,0x09,0x10,0x9f,0x10,0xaa,0x71,0x59} /* 720x540 */ }; -#ifdef TV6326TEST -const CARD8 SiS6326TVRegs1_PAL_2[6][3] = { - { 0x00,0x00,0x00}, - { 0x00,0x00,0x00}, - { 0xa4,0x07,0xd9}, /* 640x480 */ /* 887e */ - { 0xa4,0x08,0x19}, /* 800x600 */ /* 8828 */ - { 0xa1,0x7e,0xa3}, /* 800x600u */ /* n/a */ - { 0xa4,0x07,0xd9} /* 720x540 */ /* n/a */ -}; -#endif - const CARD8 SiS6326TVRegs2_PAL[6][54] = { {0x15, 0x4E, 0x35, 0x6E, 0x94, 0x02, 0x04, 0x38, 0x3A, 0x50, 0x3D, 0x70, 0x06, 0x3E, 0x35, 0x6D, 0x94, 0x05, 0x3F, 0x36, 0x6E, 0x94, @@ -164,7 +144,6 @@ const CARD8 SiS6326TVRegs2_PAL[6][54] = { 0x6A, 0x5A, 0x73, 0xA0, 0xC1, 0x95, 0x73, 0xB6, 0x03, 0xA0} }; - const CARD8 SiS6326CR[9][15] = { {0x79,0x63,0x64,0x1d,0x6a,0x93,0x00,0x6f,0xf0,0x58,0x8a,0x57,0x57,0x70,0x20}, /* PAL 800x600 */ {0x79,0x4f,0x50,0x95,0x60,0x93,0x00,0x6f,0xba,0x14,0x86,0xdf,0xe0,0x30,0x00}, /* PAL 640x480 */ @@ -240,7 +219,7 @@ SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->sisRegs3C4[0x06] &= 0x01; } - /* set interlace */ + /* set interlace */ if(!(mode->Flags & V_INTERLACE)) { offset = pSiS->CurrentLayout.displayWidth >> 3; } else { @@ -458,11 +437,13 @@ SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode) /* Programmable Clock */ pReg->sisRegs3C2 = inb(SISMISCR) | 0x0C; +#if 0 if(pSiS->oldChipset <= OC_SIS86202) { /* TODO: Handle SR07 for clock selection */ /* 86C201 does not even have a programmable clock... */ /* pReg->sisRegs3C4[0x07] &= 0x??; */ } +#endif /* Set VCLK */ if((sis6326tvmode) || (sis6326himode)) { @@ -533,7 +514,7 @@ SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->sisRegs3C4[0x2A] = (vclk[Midx] - 1) & 0x7f; pReg->sisRegs3C4[0x2A] |= ((vclk[VLDidx] == 2) ? 1 : 0) << 7; - /* bits [4:0] contain denumerator */ + /* D[4:0]: denumerator */ pReg->sisRegs3C4[0x2B] = (vclk[Nidx] - 1) & 0x1f; if(vclk[Pidx] <= 4){ @@ -585,7 +566,7 @@ SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pSiS->ValidWidth = TRUE; pReg->sisRegs3C4[0x27] &= 0xCF; if(pSiS->CurrentLayout.bitsPerPixel == 24) { - /* Invalid logical width */ + /* "Invalid logical width" */ pReg->sisRegs3C4[0x27] |= 0x30; pSiS->ValidWidth = FALSE; } else { @@ -807,11 +788,6 @@ SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode) for(i=0; i<14; i++) { pReg->sis6326tv[SiS6326TVRegs1[i]] = SiS6326TVRegs1_PAL[index][i]; } -#ifdef TV6326TEST - for(i=0, j=2; i<3; i++, j++) { - pReg->sis6326tv[j] = SiS6326TVRegs1_PAL_2[index][i]; - } -#endif fsc = (SiS6326TVRegs1_PAL[index][2] << 16) | (SiS6326TVRegs1_PAL[index][3] << 8) | (SiS6326TVRegs1_PAL[index][4]); @@ -822,11 +798,6 @@ SISInit(ScrnInfoPtr pScrn, DisplayModePtr mode) for(i=0; i<14; i++) { pReg->sis6326tv[SiS6326TVRegs1[i]] = SiS6326TVRegs1_NTSC[index][i]; } -#ifdef TV6326TEST - for(i=0, j=2; i<3; i++, j++) { - pReg->sis6326tv[j] = SiS6326TVRegs1_NTSC_2[index][i]; - } -#endif fsc = (SiS6326TVRegs1_NTSC[index][2] << 16) | (SiS6326TVRegs1_NTSC[index][3] << 8) | (SiS6326TVRegs1_NTSC[index][4]); @@ -884,11 +855,8 @@ SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode) SISRegPtr pReg = &pSiS->ModeReg; unsigned short temp; DisplayModePtr realmode = mode; -#ifdef SISMERGED - DisplayModePtr realmode2 = NULL; -#endif - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "SIS300Init()\n"); + PDEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "SIS300Init()\n")); xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "virtualX = %d depth = %d Logical width = %d\n", @@ -898,7 +866,6 @@ SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode) #ifdef SISMERGED if(pSiS->MergedFB) { realmode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1; - realmode2 = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; } #endif @@ -910,15 +877,10 @@ SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode) ((pSiS->CurrentLayout.bitsPerPixel + 7) / 8); pSiS->scrnPitch = pSiS->scrnPitch2 = pSiS->scrnOffset; - - if(realmode->Flags & V_INTERLACE) pSiS->scrnPitch <<= 1; - -#ifdef SISMERGED - if(pSiS->MergedFB) { - if(realmode2->Flags & V_INTERLACE) pSiS->scrnPitch2 <<= 1; - } else -#endif - pSiS->scrnPitch2 = pSiS->scrnPitch; + if(!(pSiS->VBFlags & CRT1_LCDA)) { + if(realmode->Flags & V_INTERLACE) pSiS->scrnPitch <<= 1; + } + /* CRT2 mode can never be interlaced */ #ifdef UNLOCK_ALWAYS outSISIDXREG(SISSR, 0x05, 0x86); @@ -977,258 +939,6 @@ SIS300Init(ScrnInfoPtr pScrn, DisplayModePtr mode) return(TRUE); } -int -SISDoSense(ScrnInfoPtr pScrn, int tempbl, int tempbh, int tempcl, int tempch) -{ - SISPtr pSiS = SISPTR(pScrn); - int temp; - - outSISIDXREG(SISPART4,0x11,tempbl); - temp = tempbh | tempcl; - setSISIDXREG(SISPART4,0x10,0xe0,temp); - SiS_DDC2Delay(pSiS->SiS_Pr, 0x1000); - tempch &= 0x7f; - inSISIDXREG(SISPART4,0x03,temp); - temp ^= 0x0e; - temp &= tempch; - return((temp == tempch)); -} - -/* Sense connected devices on 30x */ -void SISSense30x(ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - unsigned char backupP4_0d,backupP2_00,biosflag; - unsigned char svhs_bl, svhs_bh; - unsigned char svhs_cl, svhs_ch; - unsigned char cvbs_bl, cvbs_bh; - unsigned char cvbs_cl, cvbs_ch; - unsigned char vga2_bl, vga2_bh; - unsigned char vga2_cl, vga2_ch; - 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)); - - SISDoSense(pScrn, 0, 0, 0, 0); - - if((pSiS->VGAEngine == SIS_315_VGA) || - (pSiS->Chipset == PCI_CHIP_SIS300)) { - if(pSiS->sishw_ext.UseROM) { - if(pSiS->VGAEngine == SIS_300_VGA) temp = 0xfe; - else { - temp = 0xf3; - if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { - temp = 0x11b; - } - } - if(pSiS->BIOS[temp] & 0x08) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "SiS30x: Video bridge has DVI-I TMDS/VGA combo connector\n"); - orSISIDXREG(SISCR, 0x32, 0x80); - } else { - andSISIDXREG(SISCR, 0x32, 0x7f); - } - } - } - - if(pSiS->VGAEngine == SIS_300_VGA) { - - if(pSiS->sishw_ext.UseROM) { - vga2_bh = pSiS->BIOS[0xf9]; vga2_bl = pSiS->BIOS[0xf8]; - svhs_bh = pSiS->BIOS[0xfb]; svhs_bl = pSiS->BIOS[0xfa]; - cvbs_bh = pSiS->BIOS[0xfd]; cvbs_bl = pSiS->BIOS[0xfc]; - biosflag = pSiS->BIOS[0xfe]; - } else { - vga2_bh = 0x00; vga2_bl = 0xd1; - svhs_bh = 0x00; svhs_bl = 0xb9; - cvbs_bh = 0x00; cvbs_bl = 0xb3; - biosflag = 0; - } - if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)) { - vga2_bh = 0x01; vga2_bl = 0x90; - svhs_bh = 0x01; svhs_bl = 0x6b; - cvbs_bh = 0x01; cvbs_bl = 0x74; - } - inSISIDXREG(SISPART4,0x01,myflag); - if(myflag & 0x04) { - vga2_bh = 0x00; vga2_bl = 0xfd; - svhs_bh = 0x00; svhs_bl = 0xdd; - cvbs_bh = 0x00; cvbs_bl = 0xee; - } - vga2_ch = 0x0e; vga2_cl = 0x08; - svhs_ch = 0x04; svhs_cl = 0x04; - cvbs_ch = 0x08; cvbs_cl = 0x04; - - if(pSiS->Chipset == PCI_CHIP_SIS300) { - inSISIDXREG(SISSR,0x3b,myflag); - if(!(myflag & 0x01)) { - vga2_bh = 0x00; vga2_bl = 0x00; - vga2_ch = 0x00; vga2_cl = 0x00; - } - } - - } else { - - if(pSiS->sishw_ext.UseROM) { - if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { - vga2_bh = pSiS->BIOS[0xe6]; vga2_bl = pSiS->BIOS[0xe5]; - svhs_bh = pSiS->BIOS[0xe8]; svhs_bl = pSiS->BIOS[0xe7]; - cvbs_bh = pSiS->BIOS[0xea]; cvbs_bl = pSiS->BIOS[0xe9]; - biosflag = pSiS->BIOS[0x11b]; - } else { - vga2_bh = pSiS->BIOS[0xbe]; vga2_bl = pSiS->BIOS[0xbd]; - svhs_bh = pSiS->BIOS[0xc0]; svhs_bl = pSiS->BIOS[0xbf]; - cvbs_bh = pSiS->BIOS[0xc2]; cvbs_bl = pSiS->BIOS[0xc1]; - biosflag = pSiS->BIOS[0xf3]; - } - } else { - vga2_bh = 0x00; vga2_bl = 0xd1; - svhs_bh = 0x00; svhs_bl = 0xb9; - cvbs_bh = 0x00; cvbs_bl = 0xb3; - biosflag = 0; - } - - if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)) { - if(pSiS->sishw_ext.UseROM) { - if((pSiS->Chipset == PCI_CHIP_SIS330) || (pSiS->Chipset == PCI_CHIP_SIS660)) { - vga2_bh = pSiS->BIOS[0xec]; vga2_bl = pSiS->BIOS[0xeb]; - svhs_bh = pSiS->BIOS[0xee]; svhs_bl = pSiS->BIOS[0xed]; - cvbs_bh = pSiS->BIOS[0xf0]; cvbs_bl = pSiS->BIOS[0xef]; - } else { - vga2_bh = pSiS->BIOS[0xc4]; vga2_bl = pSiS->BIOS[0xc3]; - svhs_bh = pSiS->BIOS[0xc6]; svhs_bl = pSiS->BIOS[0xc5]; - cvbs_bh = pSiS->BIOS[0xc8]; cvbs_bl = pSiS->BIOS[0xc7]; - } - } else { - if(pSiS->VBFlags & (VB_301B|VB_301C|VB_302B)) { - vga2_bh = 0x01; vga2_bl = 0x90; - svhs_bh = 0x01; svhs_bl = 0x6b; - cvbs_bh = 0x01; cvbs_bl = 0x74; - } else { - vga2_bh = 0x00; vga2_bl = 0x00; - svhs_bh = 0x02; svhs_bl = 0x00; - cvbs_bh = 0x01; cvbs_bl = 0x00; - } - } - } - - if(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)) { - inSISIDXREG(SISPART4,0x01,myflag); - if(myflag & 0x04) { - vga2_bh = 0x00; vga2_bl = 0xfd; - svhs_bh = 0x00; svhs_bl = 0xdd; - cvbs_bh = 0x00; cvbs_bl = 0xee; - } - } - - if(pSiS->VBFlags & (VB_301LV|VB_302LV)) { - /* TW: No VGA2 or SCART on LV bridges */ - vga2_bh = 0x00; vga2_bl = 0x00; - vga2_ch = 0x00; vga2_cl = 0x00; - svhs_ch = 0x04; svhs_cl = 0x08; - cvbs_ch = 0x08; cvbs_cl = 0x08; - } else { - vga2_ch = 0x0e; vga2_cl = 0x08; - svhs_ch = 0x04; svhs_cl = 0x04; - cvbs_ch = 0x08; cvbs_cl = 0x04; - } - - } - - andSISIDXREG(SISCR, 0x32, ~0x14); - pSiS->postVBCR32 &= ~0x14; - if(vga2_ch || vga2_cl || vga2_bh || vga2_bl) { -#ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SiS30x: Scanning for VGA2/SCART (%x %x %x %x)\n", - vga2_bh, vga2_bl, vga2_ch, vga2_cl); -#endif - - haveresult = 0; - for(j = 0; j < 10; j++) { - result = 0; - for(i = 0; i < 3; i++) { - if(SISDoSense(pScrn, vga2_bl, vga2_bh, vga2_cl, vga2_ch)) - result++; - } - if((result == 0) || (result >= 2)) break; - } - if(result) { - if(biosflag & 0x01) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "SiS30x: Detected TV connected to SCART output\n"); - pSiS->VBFlags |= TV_SCART; - orSISIDXREG(SISCR, 0x32, 0x04); - pSiS->postVBCR32 |= 0x04; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "SiS30x: Detected secondary VGA connection\n"); - pSiS->VBFlags |= VGA2_CONNECTED; - orSISIDXREG(SISCR, 0x32, 0x10); - pSiS->postVBCR32 |= 0x10; - } - } - if(biosflag & 0x01) pSiS->SiS_SD_Flags |= SiS_SD_VBHASSCART; - } - -#ifdef TWDEBUG - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "SiS30x: Scanning for TV (%x %x %x %x; %x %x %x %x)\n", - svhs_bh, svhs_bl, svhs_ch, svhs_cl, - cvbs_bh, cvbs_bl, cvbs_ch, cvbs_cl); -#endif - - andSISIDXREG(SISCR, 0x32, ~0x03); - pSiS->postVBCR32 &= ~0x03; - - haveresult = 0; - for(j = 0; j < 10; j++) { - result = 0; - for(i = 0; i < 3; i++) { - if(SISDoSense(pScrn, svhs_bl, svhs_bh, svhs_cl, svhs_ch)) - result++; - } - if((result == 0) || (result >= 2)) break; - } - if(result) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "SiS30x: Detected TV connected to SVIDEO output\n"); - pSiS->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(SISDoSense(pScrn, cvbs_bl, cvbs_bh, cvbs_cl, cvbs_ch)) - result++; - } - if((result == 0) || (result >= 2)) break; - } - if(result) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "SiS30x: Detected TV connected to COMPOSITE output\n"); - pSiS->VBFlags |= TV_AVIDEO; - orSISIDXREG(SISCR, 0x32, 0x01); - pSiS->postVBCR32 |= 0x01; - } - } - - SISDoSense(pScrn, 0, 0, 0, 0); - - outSISIDXREG(SISPART2,0x00,backupP2_00); - outSISIDXREG(SISPART4,0x0d,backupP4_0d); -} - static void SiS6326TVDelay(ScrnInfoPtr pScrn, int delay) { @@ -1239,9 +949,10 @@ SiS6326TVDelay(ScrnInfoPtr pScrn, int delay) for(i=0; i<delay; i++) { inSISIDXREG(SISSR, 0x05, temp); } + (void)temp; } -int +static int SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl) { unsigned char temp; @@ -1261,7 +972,7 @@ SIS6326DoSense(ScrnInfoPtr pScrn, int tempbh, int tempbl, int tempch, int tempcl return(tempcl); } -void +static void SISSense6326(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); @@ -1294,18 +1005,19 @@ SISSense6326(ScrnInfoPtr pScrn) } } -/* TW: Detect video bridge and set VBFlags accordingly */ +/* Detect video bridge and set VBFlags accordingly */ void SISVGAPreInit(ScrnInfoPtr pScrn) { SISPtr pSiS = SISPTR(pScrn); - int temp,temp1,temp2, i; + int temp,temp1,temp2; int upperlimitlvds, lowerlimitlvds; int upperlimitch, lowerlimitch; - int chronteltype, chrontelidreg; - unsigned char test[3]; + int chronteltype, chrontelidreg, upperlimitvb; + + static const char *detectvb = "Detected %s video bridge (ID %d; Revision 0x%x)\n"; #if 0 unsigned char sr17=0; -#endif +#endif static const char *ChrontelTypeStr[] = { "7004", "7005", @@ -1329,6 +1041,7 @@ void SISVGAPreInit(ScrnInfoPtr pScrn) case PCI_CHIP_SIS315PRO: case PCI_CHIP_SIS330: case PCI_CHIP_SIS660: + case PCI_CHIP_SIS340: pSiS->ModeInit = SIS300Init; break; default: @@ -1354,45 +1067,36 @@ void SISVGAPreInit(ScrnInfoPtr pScrn) inSISIDXREG(SISPART4, 0x00, temp); temp &= 0x0F; - if (temp == 1) { + if(temp == 1) { inSISIDXREG(SISPART4, 0x01, temp1); temp1 &= 0xff; if(temp1 >= 0xE0) { - pSiS->VBFlags |= VB_302LV; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS302LV video bridge (ID 1; Revision 0x%x)\n", - temp1); + inSISIDXREG(SISPART4, 0x39, temp2); + if(temp2 == 0xff) { + pSiS->VBFlags |= VB_302LV; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS302LV", 1, temp1); + } else { + pSiS->VBFlags |= VB_301C; /* VB_302ELV; */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301C", 1, temp1); + } } else if(temp1 >= 0xD0) { pSiS->VBFlags |= VB_301LV; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS301LV video bridge (ID 1; Revision 0x%x)\n", - temp1); - } else if(temp1 >= 0xC0) { /* guessed */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301LV", 1, temp1); + } else if(temp1 >= 0xC0) { pSiS->VBFlags |= VB_301C; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_301C; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS301C video bridge (ID 1; Revision 0x%x)\n", - temp1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301C", 1, temp1); } else if(temp1 >= 0xB0) { pSiS->VBFlags |= VB_301B; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_301B; inSISIDXREG(SISPART4, 0x23, temp2); if(!(temp2 & 0x02)) pSiS->VBFlags |= VB_30xBDH; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS301B%s video bridge (Revision 0x%x)\n", - (temp2 & 0x02) ? "" : " (DH)", - temp1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, + (temp2 & 0x02) ? "SiS301B" : "SiS301B-DH", 1, temp1); } else { pSiS->VBFlags |= VB_301; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_301; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS301 video bridge (Revision 0x%x)\n", - temp1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301", 1, temp1); } - SISSense30x(pScrn); + SISSense30x(pScrn, TRUE); } else if (temp == 2) { @@ -1400,67 +1104,49 @@ void SISVGAPreInit(ScrnInfoPtr pScrn) temp1 &= 0xff; if(temp1 >= 0xE0) { pSiS->VBFlags |= VB_302LV; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS302LV video bridge (ID 2; Revision 0x%x)\n", - temp1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS302LV", 2, temp1); } else if(temp1 >= 0xD0) { pSiS->VBFlags |= VB_301LV; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS301LV video bridge (ID 2; Revision 0x%x)\n", - temp1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS301LV", 2, temp1); } else { pSiS->VBFlags |= VB_302B; - pSiS->sishw_ext.ujVBChipID = VB_CHIP_302B; - inSISIDXREG(SISPART4, 0x23, temp2); - if(!(temp & 0x02)) pSiS->VBFlags |= VB_30xBDH; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS302B%s video bridge (Revision 0x%x)\n", - (temp2 & 0x02) ? "" : " (DH)", - temp1); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "SiS302B", 2, temp1); } - SISSense30x(pScrn); + SISSense30x(pScrn, FALSE); } else if (temp == 3) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS303 video bridge - not supported\n"); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, detectvb, "unsupported SiS303", temp, 0); } else { - pSiS->sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN; - inSISIDXREG(SISCR, 0x37, temp); - temp = (temp >> 1) & 0x07; -#if 0 /* TW: This does not seem to be used on any machine */ - if ( (temp == 0) || (temp == 1)) { - pSiS->VBFlags |= VB_301; /* TW: 301 ? */ - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected SiS301 video bridge (Irregular bridge type %d)\n", temp); + if(pSiS->NewCRLayout) { + inSISIDXREG(SISCR, 0x38, temp); + temp = (temp >> 5) & 0x07; + } else { + inSISIDXREG(SISCR, 0x37, temp); + temp = (temp >> 1) & 0x07; } -#endif if(pSiS->VGAEngine == SIS_300_VGA) { lowerlimitlvds = 2; upperlimitlvds = 4; lowerlimitch = 4; upperlimitch = 5; chronteltype = 1; chrontelidreg = 0x25; + upperlimitvb = upperlimitlvds; } else { lowerlimitlvds = 2; upperlimitlvds = 3; lowerlimitch = 3; upperlimitch = 3; chronteltype = 2; chrontelidreg = 0x4b; + upperlimitvb = upperlimitlvds; + if(pSiS->NewCRLayout) { + upperlimitvb = 4; + } } if((temp >= lowerlimitlvds) && (temp <= upperlimitlvds)) { pSiS->VBFlags |= VB_LVDS; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected LVDS transmitter (Bridge type %d)\n", temp); - if(pSiS->Chipset == PCI_CHIP_SIS650) { - inSISIDXREG(SISCR, 0x38, temp1); - if(temp1 & 0x02) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "[LVDS: LCD channel A]\n"); - } - } + "Detected LVDS transmitter (External chip ID %d)\n", temp); } if((temp >= lowerlimitch) && (temp <= upperlimitch)) { /* Set global for init301.c */ @@ -1504,123 +1190,12 @@ void SISVGAPreInit(ScrnInfoPtr pScrn) default: temp2 = 8; pSiS->ChrontelType = CHRONTEL_701x; break; } xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected Chrontel %s TV encoder (ID 0x%02x; bridge type %d)\n", + "Detected Chrontel %s TV encoder (ID 0x%02x; chip ID %d)\n", ChrontelTypeStr[temp2], temp1, temp); /* Sense connected TV's */ - - if(chronteltype == 1) { - - /* Chrontel 700x */ - - /* Read power status */ - temp1 = SiS_GetCH700x(pSiS->SiS_Pr, 0x0e); /* Power status */ - if((temp1 & 0x03) != 0x03) { - /* TW: Power all outputs */ - SiS_SetCH700x(pSiS->SiS_Pr, 0x0B0E); - SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); - } - /* Sense connected TV devices */ - for(i = 0; i < 3; i++) { - SiS_SetCH700x(pSiS->SiS_Pr, 0x0110); - SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); - SiS_SetCH700x(pSiS->SiS_Pr, 0x0010); - SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); - temp1 = SiS_GetCH700x(pSiS->SiS_Pr, 0x10); - if(!(temp1 & 0x08)) test[i] = 0x02; - else if(!(temp1 & 0x02)) test[i] = 0x01; - else test[i] = 0; - SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); - } - - if(test[0] == test[1]) temp1 = test[0]; - else if(test[0] == test[2]) temp1 = test[0]; - else if(test[1] == test[2]) temp1 = test[1]; - else { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "TV detection unreliable - test results varied\n"); - temp1 = test[2]; - } - - } else { - - /* Chrontel 701x */ - - /* Backup Power register */ - temp1 = SiS_GetCH701x(pSiS->SiS_Pr, 0x49); - - /* Enable TV path */ - SiS_SetCH701x(pSiS->SiS_Pr, 0x2049); - - SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); - - /* Sense connected TV devices */ - temp2 = SiS_GetCH701x(pSiS->SiS_Pr, 0x20); - temp2 |= 0x01; - SiS_SetCH701x(pSiS->SiS_Pr, (temp2 << 8) | 0x20); - - SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); - - temp2 ^= 0x01; - SiS_SetCH701x(pSiS->SiS_Pr, (temp2 << 8) | 0x20); - - SiS_DDC2Delay(pSiS->SiS_Pr, 0x96); - - temp2 = SiS_GetCH701x(pSiS->SiS_Pr, 0x20); - - /* Restore Power register */ - SiS_SetCH701x(pSiS->SiS_Pr, (temp1 << 8) | 0x49); - - temp1 = 0; - if(temp2 & 0x02) temp1 |= 0x01; - if(temp2 & 0x10) temp1 |= 0x01; - if(temp2 & 0x04) temp1 |= 0x02; - - if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04; - - } - - switch(temp1) { - case 0x01: - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Chrontel: Detected TV connected to COMPOSITE output\n"); - pSiS->VBFlags |= TV_AVIDEO; - orSISIDXREG(SISCR, 0x32, 0x01); - andSISIDXREG(SISCR, 0x32, ~0x06); - pSiS->postVBCR32 |= 0x01; - pSiS->postVBCR32 &= ~0x06; - break; - case 0x02: - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Chrontel: Detected TV connected to SVIDEO output\n"); - pSiS->VBFlags |= TV_SVIDEO; - orSISIDXREG(SISCR, 0x32, 0x02); - andSISIDXREG(SISCR, 0x32, ~0x05); - pSiS->postVBCR32 |= 0x02; - pSiS->postVBCR32 &= ~0x05; - break; - case 0x04: - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Chrontel: Detected TV connected to SCART output or 480i HDTV\n"); - if(pSiS->chtvtype == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Chrontel: Use CHTVType option to select either SCART or HDTV\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Chrontel: Using SCART by default\n"); - pSiS->chtvtype = 1; - } - if(pSiS->chtvtype) - pSiS->VBFlags |= TV_CHSCART; - else - pSiS->VBFlags |= TV_CHHDTV; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Chrontel: No TV detected.\n"); - andSISIDXREG(SISCR, 0x32, ~0x07); - pSiS->postVBCR32 &= ~0x07; - } - + SISSenseChrontel(pScrn, FALSE); + } else if(temp1==0) { /* This indicates a communication problem, but it only occures if there * is no TV attached. So we don't use TV in this case. @@ -1640,11 +1215,17 @@ void SISVGAPreInit(ScrnInfoPtr pScrn) SiS_SetChrontelGPIO(pSiS->SiS_Pr, 0x00); } } - if ((pSiS->VGAEngine == SIS_300_VGA) && (temp == 3)) { + if((pSiS->NewCRLayout) && (temp == 4)) { + pSiS->VBFlags |= VB_CONEXANT; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected Conexant video bridge - UNSUPPORTED\n"); + } + if((pSiS->VGAEngine == SIS_300_VGA) && (temp == 3)) { + pSiS->VBFlags |= VB_TRUMPION; xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Detected Trumpion Zurac (I/II/III) LVDS scaler - UNSUPPORTED\n"); + "Detected Trumpion Zurac (I/II/III) LVDS scaler\n"); } - if (temp > upperlimitlvds) { + if(temp > upperlimitvb) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected unknown bridge type (%d)\n", temp); } @@ -1700,11 +1281,12 @@ void SISVGAPreInit(ScrnInfoPtr pScrn) * relevant registers ourselves. */ if(pSiS->VGAEngine == SIS_315_VGA) { - if(pSiS->VBFlags & (VB_302B | VB_301LV | VB_302LV)) { - if(pSiS->sisfblcda != 0xff) { + + if(pSiS->VBFlags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) { + if(pSiS->sisfblcda != 0xff) { if((pSiS->sisfblcda & 0x03) == 0x03) { pSiS->SiS_Pr->SiS_UseLCDA = TRUE; - pSiS->VBFlags |= VB_USELCDA; + pSiS->ChipFlags |= SiSCF_UseLCDA; } } else { inSISIDXREG(SISCR,0x34,temp); @@ -1712,32 +1294,22 @@ void SISVGAPreInit(ScrnInfoPtr pScrn) inSISIDXREG(SISCR,0x38,temp); if((temp & 0x03) == 0x03) { pSiS->SiS_Pr->SiS_UseLCDA = TRUE; - pSiS->VBFlags |= VB_USELCDA; + pSiS->ChipFlags |= SiSCF_UseLCDA; pSiS->SiS_Pr->Backup = TRUE; } else { - inSISIDXREG(SISCR,0x35,temp); - if(temp & 0x01) { + orSISIDXREG(SISPART1,0x2f,0x01); /* Unlock CRT2 */ + inSISIDXREG(SISPART1,0x13,temp); + if(temp & 0x04) { pSiS->SiS_Pr->SiS_UseLCDA = TRUE; - pSiS->VBFlags |= VB_USELCDA; + pSiS->ChipFlags |= SiSCF_UseLCDA; pSiS->SiS_Pr->Backup = TRUE; - } else { - inSISIDXREG(SISCR,0x30,temp); - if(temp & 0x20) { - orSISIDXREG(SISPART1,0x2f,0x01); /* Unlock CRT2 */ - inSISIDXREG(SISPART1,0x13,temp); - if(temp & 0x04) { - pSiS->SiS_Pr->SiS_UseLCDA = TRUE; - pSiS->VBFlags |= VB_USELCDA; - pSiS->SiS_Pr->Backup = TRUE; - } - } } } } } - if(pSiS->VBFlags & VB_USELCDA) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Bridge uses LCDA for low resolution and text modes\n"); + if(pSiS->ChipFlags & SiSCF_UseLCDA) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 3, + "BIOS uses LCDA for low resolution and text modes\n"); if(pSiS->SiS_Pr->Backup == TRUE) { inSISIDXREG(SISCR,0x34,pSiS->SiS_Pr->Backup_Mode); inSISIDXREG(SISPART1,0x14,pSiS->SiS_Pr->Backup_14); |