2005-04-17 02:20:36 +04:00
/* $XFree86$ */
/* $XdotOrg$ */
/*
* Mode initializing code ( CRT1 section ) for
2005-09-10 00:04:45 +04:00
* for SiS 300 / 305 / 540 / 630 / 730 ,
* SiS 315 / 550 / [ M ] 650 / 651 / [ M ] 661 [ FGM ] X / [ M ] 74 x [ GX ] / 330 / [ M ] 76 x [ GX ] ,
* XGI Volari V3XT / V5 / V8 , Z7
* ( Universal module for Linux kernel framebuffer and X . org / XFree86 4. x )
2005-04-17 02:20:36 +04:00
*
2005-09-10 00:04:45 +04:00
* Copyright ( C ) 2001 - 2005 by Thomas Winischhofer , Vienna , Austria
2005-04-17 02:20:36 +04:00
*
* If distributed as part of the Linux kernel , the following license terms
* apply :
*
* * 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 named License ,
* * or 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
*
* Otherwise , the following license terms apply :
*
* * 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 .
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS 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 .
*
* Author : Thomas Winischhofer < thomas @ winischhofer . net >
*
* Formerly based on non - functional code - fragements for 300 series by SiS , Inc .
* Used by permission .
*/
2005-09-10 00:04:45 +04:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
2005-04-17 02:20:36 +04:00
# include "init.h"
# ifdef SIS300
# include "300vtbl.h"
# endif
# ifdef SIS315H
# include "310vtbl.h"
# endif
# if defined(ALLOC_PRAGMA)
# pragma alloc_text(PAGE,SiSSetMode)
# endif
/*********************************************/
/* POINTER INITIALIZATION */
/*********************************************/
# if defined(SIS300) || defined(SIS315H)
static void
2005-09-10 00:04:45 +04:00
InitCommonPointer ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_SModeIDTable = SiS_SModeIDTable ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_StResInfo = SiS_StResInfo ;
SiS_Pr - > SiS_ModeResInfo = SiS_ModeResInfo ;
SiS_Pr - > SiS_StandTable = SiS_StandTable ;
SiS_Pr - > SiS_NTSCTiming = SiS_NTSCTiming ;
SiS_Pr - > SiS_PALTiming = SiS_PALTiming ;
SiS_Pr - > SiS_HiTVSt1Timing = SiS_HiTVSt1Timing ;
SiS_Pr - > SiS_HiTVSt2Timing = SiS_HiTVSt2Timing ;
SiS_Pr - > SiS_HiTVExtTiming = SiS_HiTVExtTiming ;
SiS_Pr - > SiS_HiTVGroup3Data = SiS_HiTVGroup3Data ;
SiS_Pr - > SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu ;
#if 0
SiS_Pr - > SiS_HiTVTextTiming = SiS_HiTVTextTiming ;
SiS_Pr - > SiS_HiTVGroup3Text = SiS_HiTVGroup3Text ;
# endif
SiS_Pr - > SiS_StPALData = SiS_StPALData ;
SiS_Pr - > SiS_ExtPALData = SiS_ExtPALData ;
SiS_Pr - > SiS_StNTSCData = SiS_StNTSCData ;
SiS_Pr - > SiS_ExtNTSCData = SiS_ExtNTSCData ;
SiS_Pr - > SiS_St1HiTVData = SiS_StHiTVData ;
SiS_Pr - > SiS_St2HiTVData = SiS_St2HiTVData ;
SiS_Pr - > SiS_ExtHiTVData = SiS_ExtHiTVData ;
SiS_Pr - > SiS_St525iData = SiS_StNTSCData ;
SiS_Pr - > SiS_St525pData = SiS_St525pData ;
SiS_Pr - > SiS_St750pData = SiS_St750pData ;
SiS_Pr - > SiS_Ext525iData = SiS_ExtNTSCData ;
SiS_Pr - > SiS_Ext525pData = SiS_ExtNTSCData ;
SiS_Pr - > SiS_Ext750pData = SiS_Ext750pData ;
SiS_Pr - > pSiS_OutputSelect = & SiS_OutputSelect ;
SiS_Pr - > pSiS_SoftSetting = & SiS_SoftSetting ;
SiS_Pr - > SiS_LCD1280x720Data = SiS_LCD1280x720Data ;
SiS_Pr - > SiS_StLCD1280x768_2Data = SiS_StLCD1280x768_2Data ;
SiS_Pr - > SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data ;
SiS_Pr - > SiS_LCD1280x800Data = SiS_LCD1280x800Data ;
SiS_Pr - > SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_LCD1280x854Data = SiS_LCD1280x854Data ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_LCD1280x960Data = SiS_LCD1280x960Data ;
SiS_Pr - > SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data ;
SiS_Pr - > SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data ;
SiS_Pr - > SiS_LCD1680x1050Data = SiS_LCD1680x1050Data ;
SiS_Pr - > SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data ;
SiS_Pr - > SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data ;
SiS_Pr - > SiS_NoScaleData = SiS_NoScaleData ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_LVDS320x240Data_1 = SiS_LVDS320x240Data_1 ;
SiS_Pr - > SiS_LVDS320x240Data_2 = SiS_LVDS320x240Data_2 ;
SiS_Pr - > SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1 ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1 ;
SiS_Pr - > SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1 ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_LVDSCRT1320x240_1 = SiS_LVDSCRT1320x240_1 ;
SiS_Pr - > SiS_LVDSCRT1320x240_2 = SiS_LVDSCRT1320x240_2 ;
SiS_Pr - > SiS_LVDSCRT1320x240_2_H = SiS_LVDSCRT1320x240_2_H ;
SiS_Pr - > SiS_LVDSCRT1320x240_3 = SiS_LVDSCRT1320x240_3 ;
SiS_Pr - > SiS_LVDSCRT1320x240_3_H = SiS_LVDSCRT1320x240_3_H ;
SiS_Pr - > SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1 ;
SiS_Pr - > SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H ;
#if 0
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1 ;
SiS_Pr - > SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H ;
SiS_Pr - > SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2 ;
SiS_Pr - > SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H ;
2005-09-10 00:04:45 +04:00
# endif
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_CHTVUNTSCData = SiS_CHTVUNTSCData ;
SiS_Pr - > SiS_CHTVONTSCData = SiS_CHTVONTSCData ;
SiS_Pr - > SiS_PanelMinLVDS = Panel_800x600 ; /* lowest value LVDS/LCDA */
SiS_Pr - > SiS_PanelMin301 = Panel_1024x768 ; /* lowest value 301 */
}
# endif
# ifdef SIS300
static void
2005-09-10 00:04:45 +04:00
InitTo300Pointer ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
InitCommonPointer ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_VBModeIDTable = SiS300_VBModeIDTable ;
SiS_Pr - > SiS_EModeIDTable = SiS300_EModeIDTable ;
SiS_Pr - > SiS_RefIndex = SiS300_RefIndex ;
SiS_Pr - > SiS_CRT1Table = SiS300_CRT1Table ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType = = SIS_300 ) {
SiS_Pr - > SiS_MCLKData_0 = SiS300_MCLKData_300 ; /* 300 */
2005-04-17 02:20:36 +04:00
} else {
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_MCLKData_0 = SiS300_MCLKData_630 ; /* 630, 730 */
2005-04-17 02:20:36 +04:00
}
SiS_Pr - > SiS_VCLKData = SiS300_VCLKData ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_VBVCLKData = ( struct SiS_VBVCLKData * ) SiS300_VCLKData ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_SR15 = SiS300_SR15 ;
SiS_Pr - > SiS_PanelDelayTbl = SiS300_PanelDelayTbl ;
SiS_Pr - > SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl ;
SiS_Pr - > SiS_ExtLCD1024x768Data = SiS300_ExtLCD1024x768Data ;
SiS_Pr - > SiS_St2LCD1024x768Data = SiS300_St2LCD1024x768Data ;
SiS_Pr - > SiS_ExtLCD1280x1024Data = SiS300_ExtLCD1280x1024Data ;
SiS_Pr - > SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data ;
SiS_Pr - > SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1 ;
SiS_Pr - > SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2 ;
SiS_Pr - > SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3 ;
SiS_Pr - > SiS_CHTVUPALData = SiS300_CHTVUPALData ;
SiS_Pr - > SiS_CHTVOPALData = SiS300_CHTVOPALData ;
SiS_Pr - > SiS_CHTVUPALMData = SiS_CHTVUNTSCData ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVOPALMData = SiS_CHTVONTSCData ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVUPALNData = SiS300_CHTVUPALData ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVOPALNData = SiS300_CHTVOPALData ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVSOPALData = SiS300_CHTVSOPALData ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_LVDS848x480Data_1 = SiS300_LVDS848x480Data_1 ;
SiS_Pr - > SiS_LVDS848x480Data_2 = SiS300_LVDS848x480Data_2 ;
SiS_Pr - > SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1 ;
SiS_Pr - > SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1 ;
SiS_Pr - > SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2 ;
SiS_Pr - > SiS_PanelType04_1a = SiS300_PanelType04_1a ;
SiS_Pr - > SiS_PanelType04_2a = SiS300_PanelType04_2a ;
SiS_Pr - > SiS_PanelType04_1b = SiS300_PanelType04_1b ;
SiS_Pr - > SiS_PanelType04_2b = SiS300_PanelType04_2b ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC ;
SiS_Pr - > SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC ;
SiS_Pr - > SiS_CHTVCRT1UPAL = SiS300_CHTVCRT1UPAL ;
SiS_Pr - > SiS_CHTVCRT1OPAL = SiS300_CHTVCRT1OPAL ;
SiS_Pr - > SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL ;
SiS_Pr - > SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC ;
SiS_Pr - > SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC ;
SiS_Pr - > SiS_CHTVReg_UPAL = SiS300_CHTVReg_UPAL ;
SiS_Pr - > SiS_CHTVReg_OPAL = SiS300_CHTVReg_OPAL ;
SiS_Pr - > SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL ;
SiS_Pr - > SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC ;
SiS_Pr - > SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC ;
SiS_Pr - > SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL ;
SiS_Pr - > SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL ;
SiS_Pr - > SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL ; /* not supported on 300 series */
SiS_Pr - > SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL ;
}
# endif
# ifdef SIS315H
static void
2005-09-10 00:04:45 +04:00
InitTo310Pointer ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
InitCommonPointer ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_EModeIDTable = SiS310_EModeIDTable ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_RefIndex = SiS310_RefIndex ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_CRT1Table = SiS310_CRT1Table ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_340 ) {
SiS_Pr - > SiS_MCLKData_0 = SiS310_MCLKData_0_340 ; /* 340 + XGI */
} else if ( SiS_Pr - > ChipType > = SIS_761 ) {
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_MCLKData_0 = SiS310_MCLKData_0_761 ; /* 761 - preliminary */
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType > = SIS_760 ) {
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_MCLKData_0 = SiS310_MCLKData_0_760 ; /* 760 */
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType > = SIS_661 ) {
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_MCLKData_0 = SiS310_MCLKData_0_660 ; /* 661/741 */
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType = = SIS_330 ) {
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_MCLKData_0 = SiS310_MCLKData_0_330 ; /* 330 */
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType > SIS_315PRO ) {
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_MCLKData_0 = SiS310_MCLKData_0_650 ; /* 550, 650, 740 */
} else {
SiS_Pr - > SiS_MCLKData_0 = SiS310_MCLKData_0_315 ; /* 315 */
}
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_340 ) {
SiS_Pr - > SiS_MCLKData_1 = SiS310_MCLKData_1_340 ;
2005-04-17 02:20:36 +04:00
} else {
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_MCLKData_1 = SiS310_MCLKData_1 ;
2005-04-17 02:20:36 +04:00
}
SiS_Pr - > SiS_VCLKData = SiS310_VCLKData ;
SiS_Pr - > SiS_VBVCLKData = SiS310_VBVCLKData ;
SiS_Pr - > SiS_SR15 = SiS310_SR15 ;
SiS_Pr - > SiS_PanelDelayTbl = SiS310_PanelDelayTbl ;
SiS_Pr - > SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS ;
SiS_Pr - > SiS_St2LCD1024x768Data = SiS310_St2LCD1024x768Data ;
SiS_Pr - > SiS_ExtLCD1024x768Data = SiS310_ExtLCD1024x768Data ;
SiS_Pr - > SiS_St2LCD1280x1024Data = SiS310_St2LCD1280x1024Data ;
SiS_Pr - > SiS_ExtLCD1280x1024Data = SiS310_ExtLCD1280x1024Data ;
SiS_Pr - > SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1 ;
SiS_Pr - > SiS_CHTVUPALData = SiS310_CHTVUPALData ;
SiS_Pr - > SiS_CHTVOPALData = SiS310_CHTVOPALData ;
SiS_Pr - > SiS_CHTVUPALMData = SiS310_CHTVUPALMData ;
SiS_Pr - > SiS_CHTVOPALMData = SiS310_CHTVOPALMData ;
SiS_Pr - > SiS_CHTVUPALNData = SiS310_CHTVUPALNData ;
SiS_Pr - > SiS_CHTVOPALNData = SiS310_CHTVOPALNData ;
SiS_Pr - > SiS_CHTVSOPALData = SiS310_CHTVSOPALData ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC ;
SiS_Pr - > SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC ;
SiS_Pr - > SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL ;
SiS_Pr - > SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL ;
SiS_Pr - > SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC ;
SiS_Pr - > SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC ;
SiS_Pr - > SiS_CHTVReg_UPAL = SiS310_CHTVReg_UPAL ;
SiS_Pr - > SiS_CHTVReg_OPAL = SiS310_CHTVReg_OPAL ;
SiS_Pr - > SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM ;
SiS_Pr - > SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM ;
SiS_Pr - > SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN ;
SiS_Pr - > SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN ;
SiS_Pr - > SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL ;
SiS_Pr - > SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC ;
SiS_Pr - > SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC ;
SiS_Pr - > SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL ;
SiS_Pr - > SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL ;
SiS_Pr - > SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM ;
SiS_Pr - > SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM ;
SiS_Pr - > SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN ;
SiS_Pr - > SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN ;
SiS_Pr - > SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL ;
}
# endif
2007-02-12 11:55:06 +03:00
bool
2005-09-10 00:04:45 +04:00
SiSInitPtr ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType < SIS_315H ) {
2005-04-17 02:20:36 +04:00
# ifdef SIS300
2005-09-10 00:04:45 +04:00
InitTo300Pointer ( SiS_Pr ) ;
# else
2007-02-12 11:55:06 +03:00
return false ;
2005-09-10 00:04:45 +04:00
# endif
} else {
# ifdef SIS315H
InitTo310Pointer ( SiS_Pr ) ;
# else
2007-02-12 11:55:06 +03:00
return false ;
2005-04-17 02:20:36 +04:00
# endif
}
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* HELPER: Get ModeID */
/*********************************************/
2005-09-10 00:04:45 +04:00
# ifndef SIS_XORG_XF86
static
# endif
unsigned short
SiS_GetModeID ( int VGAEngine , unsigned int VBFlags , int HDisplay , int VDisplay ,
2007-02-12 11:55:06 +03:00
int Depth , bool FSTN , int LCDwidth , int LCDheight )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short ModeIndex = 0 ;
2005-04-17 02:20:36 +04:00
switch ( HDisplay )
{
2005-09-10 00:04:45 +04:00
case 320 :
if ( VDisplay = = 200 ) ModeIndex = ModeIndex_320x200 [ Depth ] ;
else if ( VDisplay = = 240 ) {
if ( ( VBFlags & CRT2_LCD ) & & ( FSTN ) )
ModeIndex = ModeIndex_320x240_FSTN [ Depth ] ;
else
ModeIndex = ModeIndex_320x240 [ Depth ] ;
}
break ;
case 400 :
if ( ( ! ( VBFlags & CRT1_LCDA ) ) | | ( ( LCDwidth > = 800 ) & & ( LCDwidth > = 600 ) ) ) {
if ( VDisplay = = 300 ) ModeIndex = ModeIndex_400x300 [ Depth ] ;
}
break ;
case 512 :
if ( ( ! ( VBFlags & CRT1_LCDA ) ) | | ( ( LCDwidth > = 1024 ) & & ( LCDwidth > = 768 ) ) ) {
if ( VDisplay = = 384 ) ModeIndex = ModeIndex_512x384 [ Depth ] ;
}
break ;
case 640 :
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_640x480 [ Depth ] ;
else if ( VDisplay = = 400 ) ModeIndex = ModeIndex_640x400 [ Depth ] ;
break ;
case 720 :
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_720x480 [ Depth ] ;
else if ( VDisplay = = 576 ) ModeIndex = ModeIndex_720x576 [ Depth ] ;
break ;
case 768 :
if ( VDisplay = = 576 ) ModeIndex = ModeIndex_768x576 [ Depth ] ;
break ;
case 800 :
if ( VDisplay = = 600 ) ModeIndex = ModeIndex_800x600 [ Depth ] ;
else if ( VDisplay = = 480 ) ModeIndex = ModeIndex_800x480 [ Depth ] ;
break ;
case 848 :
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_848x480 [ Depth ] ;
break ;
case 856 :
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_856x480 [ Depth ] ;
break ;
case 960 :
if ( VGAEngine = = SIS_315_VGA ) {
if ( VDisplay = = 540 ) ModeIndex = ModeIndex_960x540 [ Depth ] ;
else if ( VDisplay = = 600 ) ModeIndex = ModeIndex_960x600 [ Depth ] ;
}
break ;
case 1024 :
if ( VDisplay = = 576 ) ModeIndex = ModeIndex_1024x576 [ Depth ] ;
else if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1024x768 [ Depth ] ;
else if ( VGAEngine = = SIS_300_VGA ) {
if ( VDisplay = = 600 ) ModeIndex = ModeIndex_1024x600 [ Depth ] ;
}
break ;
case 1152 :
if ( VDisplay = = 864 ) ModeIndex = ModeIndex_1152x864 [ Depth ] ;
if ( VGAEngine = = SIS_300_VGA ) {
if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1152x768 [ Depth ] ;
}
break ;
case 1280 :
switch ( VDisplay ) {
case 720 :
ModeIndex = ModeIndex_1280x720 [ Depth ] ;
break ;
case 768 :
if ( VGAEngine = = SIS_300_VGA ) {
ModeIndex = ModeIndex_300_1280x768 [ Depth ] ;
} else {
ModeIndex = ModeIndex_310_1280x768 [ Depth ] ;
}
break ;
case 800 :
if ( VGAEngine = = SIS_315_VGA ) {
ModeIndex = ModeIndex_1280x800 [ Depth ] ;
}
break ;
case 854 :
if ( VGAEngine = = SIS_315_VGA ) {
ModeIndex = ModeIndex_1280x854 [ Depth ] ;
}
break ;
case 960 :
ModeIndex = ModeIndex_1280x960 [ Depth ] ;
break ;
case 1024 :
ModeIndex = ModeIndex_1280x1024 [ Depth ] ;
break ;
}
break ;
case 1360 :
if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1360x768 [ Depth ] ;
if ( VGAEngine = = SIS_300_VGA ) {
if ( VDisplay = = 1024 ) ModeIndex = ModeIndex_300_1360x1024 [ Depth ] ;
}
break ;
case 1400 :
if ( VGAEngine = = SIS_315_VGA ) {
if ( VDisplay = = 1050 ) {
ModeIndex = ModeIndex_1400x1050 [ Depth ] ;
}
}
break ;
case 1600 :
if ( VDisplay = = 1200 ) ModeIndex = ModeIndex_1600x1200 [ Depth ] ;
break ;
case 1680 :
if ( VGAEngine = = SIS_315_VGA ) {
if ( VDisplay = = 1050 ) ModeIndex = ModeIndex_1680x1050 [ Depth ] ;
}
break ;
case 1920 :
if ( VDisplay = = 1440 ) ModeIndex = ModeIndex_1920x1440 [ Depth ] ;
else if ( VGAEngine = = SIS_315_VGA ) {
if ( VDisplay = = 1080 ) ModeIndex = ModeIndex_1920x1080 [ Depth ] ;
}
break ;
case 2048 :
if ( VDisplay = = 1536 ) {
if ( VGAEngine = = SIS_300_VGA ) {
ModeIndex = ModeIndex_300_2048x1536 [ Depth ] ;
} else {
ModeIndex = ModeIndex_310_2048x1536 [ Depth ] ;
}
}
break ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
return ModeIndex ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetModeID_LCD ( int VGAEngine , unsigned int VBFlags , int HDisplay , int VDisplay ,
2007-02-12 11:55:06 +03:00
int Depth , bool FSTN , unsigned short CustomT , int LCDwidth , int LCDheight ,
2005-09-10 00:04:45 +04:00
unsigned int VBFlags2 )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short ModeIndex = 0 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( VBFlags2 & ( VB2_LVDS | VB2_30xBDH ) ) {
2005-04-17 02:20:36 +04:00
switch ( HDisplay )
{
case 320 :
2005-09-10 00:04:45 +04:00
if ( ( CustomT ! = CUT_PANEL848 ) & & ( CustomT ! = CUT_PANEL856 ) ) {
if ( VDisplay = = 200 ) {
if ( ! FSTN ) ModeIndex = ModeIndex_320x200 [ Depth ] ;
} else if ( VDisplay = = 240 ) {
2005-04-17 02:20:36 +04:00
if ( ! FSTN ) ModeIndex = ModeIndex_320x240 [ Depth ] ;
2005-09-10 00:04:45 +04:00
else if ( VGAEngine = = SIS_315_VGA ) {
ModeIndex = ModeIndex_320x240_FSTN [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
}
}
2005-09-10 00:04:45 +04:00
break ;
case 400 :
if ( ( CustomT ! = CUT_PANEL848 ) & & ( CustomT ! = CUT_PANEL856 ) ) {
if ( ! ( ( VGAEngine = = SIS_300_VGA ) & & ( VBFlags2 & VB2_TRUMPION ) ) ) {
if ( VDisplay = = 300 ) ModeIndex = ModeIndex_400x300 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
}
2005-09-10 00:04:45 +04:00
break ;
2005-04-17 02:20:36 +04:00
case 512 :
2005-09-10 00:04:45 +04:00
if ( ( CustomT ! = CUT_PANEL848 ) & & ( CustomT ! = CUT_PANEL856 ) ) {
if ( ! ( ( VGAEngine = = SIS_300_VGA ) & & ( VBFlags2 & VB2_TRUMPION ) ) ) {
2005-04-17 02:20:36 +04:00
if ( LCDwidth > = 1024 & & LCDwidth ! = 1152 & & LCDheight > = 768 ) {
if ( VDisplay = = 384 ) {
ModeIndex = ModeIndex_512x384 [ Depth ] ;
}
}
}
}
break ;
case 640 :
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_640x480 [ Depth ] ;
2005-04-17 02:20:36 +04:00
else if ( VDisplay = = 400 ) {
2005-09-10 00:04:45 +04:00
if ( ( CustomT ! = CUT_PANEL848 ) & & ( CustomT ! = CUT_PANEL856 ) )
ModeIndex = ModeIndex_640x400 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 800 :
if ( VDisplay = = 600 ) ModeIndex = ModeIndex_800x600 [ Depth ] ;
break ;
case 848 :
if ( CustomT = = CUT_PANEL848 ) {
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_848x480 [ Depth ] ;
}
break ;
2005-09-10 00:04:45 +04:00
case 856 :
if ( CustomT = = CUT_PANEL856 ) {
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_856x480 [ Depth ] ;
}
break ;
2005-04-17 02:20:36 +04:00
case 1024 :
if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1024x768 [ Depth ] ;
else if ( VGAEngine = = SIS_300_VGA ) {
if ( ( VDisplay = = 600 ) & & ( LCDheight = = 600 ) ) {
ModeIndex = ModeIndex_1024x600 [ Depth ] ;
}
}
break ;
case 1152 :
if ( VGAEngine = = SIS_300_VGA ) {
2005-09-10 00:04:45 +04:00
if ( ( VDisplay = = 768 ) & & ( LCDheight = = 768 ) ) {
2005-04-17 02:20:36 +04:00
ModeIndex = ModeIndex_1152x768 [ Depth ] ;
}
}
break ;
case 1280 :
if ( VDisplay = = 1024 ) ModeIndex = ModeIndex_1280x1024 [ Depth ] ;
else if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( ( VDisplay = = 768 ) & & ( LCDheight = = 768 ) ) {
2005-04-17 02:20:36 +04:00
ModeIndex = ModeIndex_310_1280x768 [ Depth ] ;
}
}
break ;
case 1360 :
if ( VGAEngine = = SIS_300_VGA ) {
2005-09-10 00:04:45 +04:00
if ( CustomT = = CUT_BARCO1366 ) {
2005-04-17 02:20:36 +04:00
if ( VDisplay = = 1024 ) ModeIndex = ModeIndex_300_1360x1024 [ Depth ] ;
}
}
if ( CustomT = = CUT_PANEL848 ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1360x768 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 1400 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 1050 ) ModeIndex = ModeIndex_1400x1050 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 1600 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 1200 ) ModeIndex = ModeIndex_1600x1200 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
}
2005-09-10 00:04:45 +04:00
} else if ( VBFlags2 & VB2_SISBRIDGE ) {
2005-04-17 02:20:36 +04:00
switch ( HDisplay )
{
case 320 :
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 200 ) ModeIndex = ModeIndex_320x200 [ Depth ] ;
2005-04-17 02:20:36 +04:00
else if ( VDisplay = = 240 ) ModeIndex = ModeIndex_320x240 [ Depth ] ;
2005-09-10 00:04:45 +04:00
break ;
case 400 :
2005-04-17 02:20:36 +04:00
if ( LCDwidth > = 800 & & LCDheight > = 600 ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 300 ) ModeIndex = ModeIndex_400x300 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
break ;
2005-04-17 02:20:36 +04:00
case 512 :
if ( LCDwidth > = 1024 & & LCDheight > = 768 & & LCDwidth ! = 1152 ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 384 ) ModeIndex = ModeIndex_512x384 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 640 :
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_640x480 [ Depth ] ;
else if ( VDisplay = = 400 ) ModeIndex = ModeIndex_640x400 [ Depth ] ;
break ;
case 720 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_720x480 [ Depth ] ;
2005-04-17 02:20:36 +04:00
else if ( VDisplay = = 576 ) ModeIndex = ModeIndex_720x576 [ Depth ] ;
}
break ;
case 768 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 576 ) ModeIndex = ModeIndex_768x576 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 800 :
if ( VDisplay = = 600 ) ModeIndex = ModeIndex_800x600 [ Depth ] ;
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_800x480 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 848 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_848x480 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 856 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_856x480 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 960 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 540 ) ModeIndex = ModeIndex_960x540 [ Depth ] ;
2005-04-17 02:20:36 +04:00
else if ( VDisplay = = 600 ) ModeIndex = ModeIndex_960x600 [ Depth ] ;
}
break ;
case 1024 :
if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1024x768 [ Depth ] ;
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 576 ) ModeIndex = ModeIndex_1024x576 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 1152 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 864 ) ModeIndex = ModeIndex_1152x864 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 1280 :
switch ( VDisplay ) {
case 720 :
2005-09-10 00:04:45 +04:00
ModeIndex = ModeIndex_1280x720 [ Depth ] ;
2005-04-17 02:20:36 +04:00
case 768 :
2005-09-10 00:04:45 +04:00
if ( VGAEngine = = SIS_300_VGA ) {
2005-04-17 02:20:36 +04:00
ModeIndex = ModeIndex_300_1280x768 [ Depth ] ;
} else {
ModeIndex = ModeIndex_310_1280x768 [ Depth ] ;
}
break ;
case 800 :
2005-09-10 00:04:45 +04:00
if ( VGAEngine = = SIS_315_VGA ) {
2005-04-17 02:20:36 +04:00
ModeIndex = ModeIndex_1280x800 [ Depth ] ;
}
break ;
2005-09-10 00:04:45 +04:00
case 854 :
if ( VGAEngine = = SIS_315_VGA ) {
ModeIndex = ModeIndex_1280x854 [ Depth ] ;
}
break ;
2005-04-17 02:20:36 +04:00
case 960 :
2005-09-10 00:04:45 +04:00
ModeIndex = ModeIndex_1280x960 [ Depth ] ;
2005-04-17 02:20:36 +04:00
break ;
case 1024 :
2005-09-10 00:04:45 +04:00
ModeIndex = ModeIndex_1280x1024 [ Depth ] ;
2005-04-17 02:20:36 +04:00
break ;
}
break ;
case 1360 :
2005-09-10 00:04:45 +04:00
if ( VGAEngine = = SIS_315_VGA ) { /* OVER1280 only? */
if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1360x768 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 1400 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VBFlags2 & VB2_LCDOVER1280BRIDGE ) {
2005-04-17 02:20:36 +04:00
if ( VDisplay = = 1050 ) ModeIndex = ModeIndex_1400x1050 [ Depth ] ;
}
}
break ;
case 1600 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VBFlags2 & VB2_LCDOVER1280BRIDGE ) {
if ( VDisplay = = 1200 ) ModeIndex = ModeIndex_1600x1200 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
}
break ;
# ifndef VB_FORBID_CRT2LCD_OVER_1600
case 1680 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VBFlags2 & VB2_LCDOVER1280BRIDGE ) {
if ( VDisplay = = 1050 ) ModeIndex = ModeIndex_1680x1050 [ Depth ] ;
}
}
break ;
case 1920 :
if ( VGAEngine = = SIS_315_VGA ) {
if ( VBFlags2 & VB2_LCDOVER1600BRIDGE ) {
if ( VDisplay = = 1440 ) ModeIndex = ModeIndex_1920x1440 [ Depth ] ;
}
}
break ;
case 2048 :
if ( VGAEngine = = SIS_315_VGA ) {
if ( VBFlags2 & VB2_LCDOVER1600BRIDGE ) {
if ( VDisplay = = 1536 ) ModeIndex = ModeIndex_310_2048x1536 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
}
break ;
# endif
}
}
return ModeIndex ;
}
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetModeID_TV ( int VGAEngine , unsigned int VBFlags , int HDisplay , int VDisplay , int Depth ,
unsigned int VBFlags2 )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short ModeIndex = 0 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( VBFlags2 & VB2_CHRONTEL ) {
2005-04-17 02:20:36 +04:00
switch ( HDisplay )
{
2005-09-10 00:04:45 +04:00
case 512 :
2005-04-17 02:20:36 +04:00
if ( VGAEngine = = SIS_315_VGA ) {
if ( VDisplay = = 384 ) ModeIndex = ModeIndex_512x384 [ Depth ] ;
}
break ;
case 640 :
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_640x480 [ Depth ] ;
else if ( VDisplay = = 400 ) ModeIndex = ModeIndex_640x400 [ Depth ] ;
break ;
case 800 :
if ( VDisplay = = 600 ) ModeIndex = ModeIndex_800x600 [ Depth ] ;
break ;
case 1024 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 768 ) ModeIndex = ModeIndex_1024x768 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
}
2005-09-10 00:04:45 +04:00
} else if ( VBFlags2 & VB2_SISTVBRIDGE ) {
2005-04-17 02:20:36 +04:00
switch ( HDisplay )
{
case 320 :
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 200 ) ModeIndex = ModeIndex_320x200 [ Depth ] ;
2005-04-17 02:20:36 +04:00
else if ( VDisplay = = 240 ) ModeIndex = ModeIndex_320x240 [ Depth ] ;
2005-09-10 00:04:45 +04:00
break ;
case 400 :
if ( VDisplay = = 300 ) ModeIndex = ModeIndex_400x300 [ Depth ] ;
break ;
case 512 :
2005-04-17 02:20:36 +04:00
if ( ( ( VBFlags & TV_YPBPR ) & & ( VBFlags & ( TV_YPBPR750P | TV_YPBPR1080I ) ) ) | |
2005-09-10 00:04:45 +04:00
( VBFlags & TV_HIVISION ) | |
( ( ! ( VBFlags & ( TV_YPBPR | TV_PALM ) ) ) & & ( VBFlags & TV_PAL ) ) ) {
if ( VDisplay = = 384 ) ModeIndex = ModeIndex_512x384 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
break ;
case 640 :
if ( VDisplay = = 480 ) ModeIndex = ModeIndex_640x480 [ Depth ] ;
else if ( VDisplay = = 400 ) ModeIndex = ModeIndex_640x400 [ Depth ] ;
break ;
case 720 :
if ( ( ! ( VBFlags & TV_HIVISION ) ) & & ( ! ( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR1080I ) ) ) ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 480 ) {
ModeIndex = ModeIndex_720x480 [ Depth ] ;
} else if ( VDisplay = = 576 ) {
2005-04-17 02:20:36 +04:00
if ( ( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR750P ) ) | |
( ( ! ( VBFlags & ( TV_YPBPR | TV_PALM ) ) ) & & ( VBFlags & TV_PAL ) ) )
2005-09-10 00:04:45 +04:00
ModeIndex = ModeIndex_720x576 [ Depth ] ;
}
2005-04-17 02:20:36 +04:00
}
break ;
case 768 :
if ( ( ! ( VBFlags & TV_HIVISION ) ) & & ( ! ( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR1080I ) ) ) ) {
2005-09-10 00:04:45 +04:00
if ( ( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR750P ) ) | |
2005-04-17 02:20:36 +04:00
( ( ! ( VBFlags & ( TV_YPBPR | TV_PALM ) ) ) & & ( VBFlags & TV_PAL ) ) ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 576 ) ModeIndex = ModeIndex_768x576 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
}
break ;
case 800 :
if ( VDisplay = = 600 ) ModeIndex = ModeIndex_800x600 [ Depth ] ;
else if ( VDisplay = = 480 ) {
2005-09-10 00:04:45 +04:00
if ( ! ( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR750P ) ) ) {
2005-04-17 02:20:36 +04:00
ModeIndex = ModeIndex_800x480 [ Depth ] ;
}
}
break ;
case 960 :
if ( VGAEngine = = SIS_315_VGA ) {
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 600 ) {
2005-04-17 02:20:36 +04:00
if ( ( VBFlags & TV_HIVISION ) | | ( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR1080I ) ) ) {
ModeIndex = ModeIndex_960x600 [ Depth ] ;
}
}
}
break ;
case 1024 :
if ( VDisplay = = 768 ) {
2005-09-10 00:04:45 +04:00
if ( VBFlags2 & VB2_30xBLV ) {
2005-04-17 02:20:36 +04:00
ModeIndex = ModeIndex_1024x768 [ Depth ] ;
}
} else if ( VDisplay = = 576 ) {
2005-09-10 00:04:45 +04:00
if ( ( VBFlags & TV_HIVISION ) | |
( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR1080I ) ) | |
( ( VBFlags2 & VB2_30xBLV ) & &
( ( ! ( VBFlags & ( TV_YPBPR | TV_PALM ) ) ) & & ( VBFlags & TV_PAL ) ) ) ) {
2005-04-17 02:20:36 +04:00
ModeIndex = ModeIndex_1024x576 [ Depth ] ;
}
}
break ;
case 1280 :
if ( VDisplay = = 720 ) {
2005-09-10 00:04:45 +04:00
if ( ( VBFlags & TV_HIVISION ) | |
2005-04-17 02:20:36 +04:00
( ( VBFlags & TV_YPBPR ) & & ( VBFlags & ( TV_YPBPR1080I | TV_YPBPR750P ) ) ) ) {
2005-09-10 00:04:45 +04:00
ModeIndex = ModeIndex_1280x720 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
} else if ( VDisplay = = 1024 ) {
2005-09-10 00:04:45 +04:00
if ( ( VBFlags & TV_HIVISION ) | |
2005-04-17 02:20:36 +04:00
( ( VBFlags & TV_YPBPR ) & & ( VBFlags & TV_YPBPR1080I ) ) ) {
2005-09-10 00:04:45 +04:00
ModeIndex = ModeIndex_1280x1024 [ Depth ] ;
2005-04-17 02:20:36 +04:00
}
}
break ;
}
}
return ModeIndex ;
}
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetModeID_VGA2 ( int VGAEngine , unsigned int VBFlags , int HDisplay , int VDisplay , int Depth ,
unsigned int VBFlags2 )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
if ( ! ( VBFlags2 & VB2_SISVGA2BRIDGE ) ) return 0 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( HDisplay > = 1920 ) return 0 ;
2005-04-17 02:20:36 +04:00
switch ( HDisplay )
{
case 1600 :
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 1200 ) {
if ( VGAEngine ! = SIS_315_VGA ) return 0 ;
if ( ! ( VBFlags2 & VB2_30xB ) ) return 0 ;
2005-04-17 02:20:36 +04:00
}
break ;
case 1680 :
2005-09-10 00:04:45 +04:00
if ( VDisplay = = 1050 ) {
if ( VGAEngine ! = SIS_315_VGA ) return 0 ;
if ( ! ( VBFlags2 & VB2_30xB ) ) return 0 ;
2005-04-17 02:20:36 +04:00
}
break ;
}
2007-02-12 11:55:06 +03:00
return SiS_GetModeID ( VGAEngine , 0 , HDisplay , VDisplay , Depth , false , 0 , 0 ) ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* HELPER: SetReg, GetReg */
/*********************************************/
void
2005-09-10 00:04:45 +04:00
SiS_SetReg ( SISIOADDRESS port , unsigned short index , unsigned short data )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
OutPortByte ( port , index ) ;
OutPortByte ( port + 1 , data ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_SetRegByte ( SISIOADDRESS port , unsigned short data )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
OutPortByte ( port , data ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_SetRegShort ( SISIOADDRESS port , unsigned short data )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
OutPortWord ( port , data ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_SetRegLong ( SISIOADDRESS port , unsigned int data )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
OutPortLong ( port , data ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
unsigned char
SiS_GetReg ( SISIOADDRESS port , unsigned short index )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
OutPortByte ( port , index ) ;
2005-04-17 02:20:36 +04:00
return ( InPortByte ( port + 1 ) ) ;
}
2005-09-10 00:04:45 +04:00
unsigned char
2005-04-17 02:20:36 +04:00
SiS_GetRegByte ( SISIOADDRESS port )
{
return ( InPortByte ( port ) ) ;
}
2005-09-10 00:04:45 +04:00
unsigned short
2005-04-17 02:20:36 +04:00
SiS_GetRegShort ( SISIOADDRESS port )
{
return ( InPortWord ( port ) ) ;
}
2005-09-10 00:04:45 +04:00
unsigned int
2005-04-17 02:20:36 +04:00
SiS_GetRegLong ( SISIOADDRESS port )
{
return ( InPortLong ( port ) ) ;
}
void
2005-09-10 00:04:45 +04:00
SiS_SetRegANDOR ( SISIOADDRESS Port , unsigned short Index , unsigned short DataAND , unsigned short DataOR )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
temp = SiS_GetReg ( Port , Index ) ;
temp = ( temp & ( DataAND ) ) | DataOR ;
SiS_SetReg ( Port , Index , temp ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_SetRegAND ( SISIOADDRESS Port , unsigned short Index , unsigned short DataAND )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
temp = SiS_GetReg ( Port , Index ) ;
temp & = DataAND ;
SiS_SetReg ( Port , Index , temp ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_SetRegOR ( SISIOADDRESS Port , unsigned short Index , unsigned short DataOR )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
temp = SiS_GetReg ( Port , Index ) ;
temp | = DataOR ;
SiS_SetReg ( Port , Index , temp ) ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* HELPER: DisplayOn, DisplayOff */
/*********************************************/
void
2005-09-10 00:04:45 +04:00
SiS_DisplayOn ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x01 , 0xDF ) ;
}
void
2005-09-10 00:04:45 +04:00
SiS_DisplayOff ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x01 , 0x20 ) ;
}
/*********************************************/
/* HELPER: Init Port Addresses */
/*********************************************/
void
2005-09-10 00:04:45 +04:00
SiSRegInit ( struct SiS_Private * SiS_Pr , SISIOADDRESS BaseAddr )
2005-04-17 02:20:36 +04:00
{
SiS_Pr - > SiS_P3c4 = BaseAddr + 0x14 ;
SiS_Pr - > SiS_P3d4 = BaseAddr + 0x24 ;
SiS_Pr - > SiS_P3c0 = BaseAddr + 0x10 ;
SiS_Pr - > SiS_P3ce = BaseAddr + 0x1e ;
SiS_Pr - > SiS_P3c2 = BaseAddr + 0x12 ;
SiS_Pr - > SiS_P3ca = BaseAddr + 0x1a ;
SiS_Pr - > SiS_P3c6 = BaseAddr + 0x16 ;
SiS_Pr - > SiS_P3c7 = BaseAddr + 0x17 ;
SiS_Pr - > SiS_P3c8 = BaseAddr + 0x18 ;
SiS_Pr - > SiS_P3c9 = BaseAddr + 0x19 ;
SiS_Pr - > SiS_P3cb = BaseAddr + 0x1b ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_P3cc = BaseAddr + 0x1c ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_P3cd = BaseAddr + 0x1d ;
SiS_Pr - > SiS_P3da = BaseAddr + 0x2a ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04 ;
SiS_Pr - > SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10 ;
SiS_Pr - > SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12 ;
SiS_Pr - > SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14 ;
SiS_Pr - > SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2 ;
SiS_Pr - > SiS_DDC_Port = BaseAddr + 0x14 ;
SiS_Pr - > SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE ;
SiS_Pr - > SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* HELPER: GetSysFlags */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_GetSysFlags ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
unsigned char cr5f , temp1 , temp2 ;
/* 661 and newer: NEVER write non-zero to SR11[7:4] */
/* (SR11 is used for DDC and in enable/disablebridge) */
2007-02-12 11:55:06 +03:00
SiS_Pr - > SiS_SensibleSR11 = false ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_MyCR63 = 0x63 ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_330 ) {
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_MyCR63 = 0x53 ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_661 ) {
2007-02-12 11:55:06 +03:00
SiS_Pr - > SiS_SensibleSR11 = true ;
2005-04-17 02:20:36 +04:00
}
}
/* You should use the macros, not these flags directly */
SiS_Pr - > SiS_SysFlags = 0 ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType = = SIS_650 ) {
2005-04-17 02:20:36 +04:00
cr5f = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x5f ) & 0xf0 ;
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x5c , 0x07 ) ;
temp1 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x5c ) & 0xf8 ;
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x5c , 0xf8 ) ;
temp2 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x5c ) & 0xf8 ;
if ( ( ! temp1 ) | | ( temp2 ) ) {
2005-09-10 00:04:45 +04:00
switch ( cr5f ) {
2005-04-17 02:20:36 +04:00
case 0x80 :
case 0x90 :
case 0xc0 :
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_SysFlags | = SF_IsM650 ;
break ;
2005-04-17 02:20:36 +04:00
case 0xa0 :
case 0xb0 :
case 0xe0 :
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_SysFlags | = SF_Is651 ;
break ;
2005-04-17 02:20:36 +04:00
}
} else {
2005-09-10 00:04:45 +04:00
switch ( cr5f ) {
2005-04-17 02:20:36 +04:00
case 0x90 :
temp1 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x5c ) & 0xf8 ;
switch ( temp1 ) {
2005-09-10 00:04:45 +04:00
case 0x00 : SiS_Pr - > SiS_SysFlags | = SF_IsM652 ; break ;
2005-04-17 02:20:36 +04:00
case 0x40 : SiS_Pr - > SiS_SysFlags | = SF_IsM653 ; break ;
default : SiS_Pr - > SiS_SysFlags | = SF_IsM650 ; break ;
}
break ;
case 0xb0 :
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_SysFlags | = SF_Is652 ;
break ;
2005-04-17 02:20:36 +04:00
default :
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_SysFlags | = SF_IsM650 ;
break ;
2005-04-17 02:20:36 +04:00
}
}
}
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_760 & & SiS_Pr - > ChipType < = SIS_761 ) {
if ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x78 ) & 0x30 ) {
SiS_Pr - > SiS_SysFlags | = SF_760LFB ;
}
if ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x79 ) & 0xf0 ) {
SiS_Pr - > SiS_SysFlags | = SF_760UMA ;
}
2005-04-17 02:20:36 +04:00
}
}
/*********************************************/
/* HELPER: Init PCI & Engines */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiSInitPCIetc ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
switch ( SiS_Pr - > ChipType ) {
# ifdef SIS300
2005-04-17 02:20:36 +04:00
case SIS_300 :
case SIS_540 :
case SIS_630 :
case SIS_730 :
/* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
2005-09-10 00:04:45 +04:00
* - RELOCATED VGA IO ENABLED ( 0x20 )
* - MMIO ENABLED ( 0x01 )
* Leave other bits untouched .
2005-04-17 02:20:36 +04:00
*/
2005-09-10 00:04:45 +04:00
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x20 , 0xa1 ) ;
2005-04-17 02:20:36 +04:00
/* - Enable 2D (0x40)
* - Enable 3 D ( 0x02 )
* - Enable 3 D Vertex command fetch ( 0x10 ) ?
* - Enable 3 D command parser ( 0x08 ) ?
*/
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x1E , 0x5A ) ;
break ;
2005-09-10 00:04:45 +04:00
# endif
# ifdef SIS315H
2005-04-17 02:20:36 +04:00
case SIS_315H :
case SIS_315 :
case SIS_315PRO :
case SIS_650 :
case SIS_740 :
case SIS_330 :
case SIS_661 :
case SIS_741 :
case SIS_660 :
case SIS_760 :
case SIS_761 :
case SIS_340 :
2005-09-10 00:04:45 +04:00
case XGI_40 :
/* See above */
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x20 , 0xa1 ) ;
/* - Enable 3D G/L transformation engine (0x80)
* - Enable 2 D ( 0x40 )
2005-04-17 02:20:36 +04:00
* - Enable 3 D vertex command fetch ( 0x10 )
* - Enable 3 D command parser ( 0x08 )
2005-09-10 00:04:45 +04:00
* - Enable 3 D ( 0x02 )
2005-04-17 02:20:36 +04:00
*/
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x1E , 0xDA ) ;
break ;
2005-09-10 00:04:45 +04:00
case XGI_20 :
2005-04-17 02:20:36 +04:00
case SIS_550 :
2005-09-10 00:04:45 +04:00
/* See above */
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x20 , 0xa1 ) ;
2005-04-17 02:20:36 +04:00
/* No 3D engine ! */
/* - Enable 2D (0x40)
2005-09-10 00:04:45 +04:00
* - disable 3 D
2005-04-17 02:20:36 +04:00
*/
2005-09-10 00:04:45 +04:00
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x1E , 0x60 , 0x40 ) ;
break ;
# endif
default :
break ;
2005-04-17 02:20:36 +04:00
}
}
/*********************************************/
/* HELPER: SetLVDSetc */
/*********************************************/
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
static
# endif
void
SiSSetLVDSetc ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_IF_DEF_LVDS = 0 ;
SiS_Pr - > SiS_IF_DEF_TRUMPION = 0 ;
SiS_Pr - > SiS_IF_DEF_CH70xx = 0 ;
SiS_Pr - > SiS_IF_DEF_CONEX = 0 ;
SiS_Pr - > SiS_ChrontelInit = 0 ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType = = XGI_20 ) return ;
2005-04-17 02:20:36 +04:00
/* Check for SiS30x first */
temp = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x00 ) ;
if ( ( temp = = 1 ) | | ( temp = = 2 ) ) return ;
2005-09-10 00:04:45 +04:00
switch ( SiS_Pr - > ChipType ) {
2005-04-17 02:20:36 +04:00
# ifdef SIS300
case SIS_540 :
case SIS_630 :
case SIS_730 :
2005-09-10 00:04:45 +04:00
temp = ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x37 ) & 0x0e ) > > 1 ;
if ( ( temp > = 2 ) & & ( temp < = 5 ) ) SiS_Pr - > SiS_IF_DEF_LVDS = 1 ;
if ( temp = = 3 ) SiS_Pr - > SiS_IF_DEF_TRUMPION = 1 ;
if ( ( temp = = 4 ) | | ( temp = = 5 ) ) {
2005-04-17 02:20:36 +04:00
/* Save power status (and error check) - UNUSED */
SiS_Pr - > SiS_Backup70xx = SiS_GetCH700x ( SiS_Pr , 0x0e ) ;
SiS_Pr - > SiS_IF_DEF_CH70xx = 1 ;
2005-09-10 00:04:45 +04:00
}
2005-04-17 02:20:36 +04:00
break ;
# endif
# ifdef SIS315H
case SIS_550 :
case SIS_650 :
case SIS_740 :
case SIS_330 :
2005-09-10 00:04:45 +04:00
temp = ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x37 ) & 0x0e ) > > 1 ;
if ( ( temp > = 2 ) & & ( temp < = 3 ) ) SiS_Pr - > SiS_IF_DEF_LVDS = 1 ;
if ( temp = = 3 ) SiS_Pr - > SiS_IF_DEF_CH70xx = 2 ;
break ;
2005-04-17 02:20:36 +04:00
case SIS_661 :
case SIS_741 :
case SIS_660 :
case SIS_760 :
case SIS_761 :
case SIS_340 :
2005-09-10 00:04:45 +04:00
case XGI_20 :
case XGI_40 :
temp = ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x38 ) & 0xe0 ) > > 5 ;
if ( ( temp > = 2 ) & & ( temp < = 3 ) ) SiS_Pr - > SiS_IF_DEF_LVDS = 1 ;
if ( temp = = 3 ) SiS_Pr - > SiS_IF_DEF_CH70xx = 2 ;
if ( temp = = 4 ) SiS_Pr - > SiS_IF_DEF_CONEX = 1 ; /* Not yet supported */
break ;
2005-04-17 02:20:36 +04:00
# endif
default :
2005-09-10 00:04:45 +04:00
break ;
2005-04-17 02:20:36 +04:00
}
}
/*********************************************/
/* HELPER: Enable DSTN/FSTN */
/*********************************************/
void
2005-09-10 00:04:45 +04:00
SiS_SetEnableDstn ( struct SiS_Private * SiS_Pr , int enable )
2005-04-17 02:20:36 +04:00
{
SiS_Pr - > SiS_IF_DEF_DSTN = enable ? 1 : 0 ;
}
void
2005-09-10 00:04:45 +04:00
SiS_SetEnableFstn ( struct SiS_Private * SiS_Pr , int enable )
2005-04-17 02:20:36 +04:00
{
SiS_Pr - > SiS_IF_DEF_FSTN = enable ? 1 : 0 ;
}
2005-09-10 00:04:45 +04:00
/*********************************************/
/* HELPER: Get modeflag */
/*********************************************/
unsigned short
SiS_GetModeFlag ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex )
{
if ( SiS_Pr - > UseCustomMode ) {
return SiS_Pr - > CModeFlag ;
} else if ( ModeNo < = 0x13 ) {
return SiS_Pr - > SiS_SModeIDTable [ ModeIdIndex ] . St_ModeFlag ;
} else {
return SiS_Pr - > SiS_EModeIDTable [ ModeIdIndex ] . Ext_ModeFlag ;
}
}
2005-04-17 02:20:36 +04:00
/*********************************************/
/* HELPER: Determine ROM usage */
/*********************************************/
2007-02-12 11:55:06 +03:00
bool
2005-09-10 00:04:45 +04:00
SiSDetermineROMLayout661 ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char * ROMAddr = SiS_Pr - > VirtualRomBase ;
unsigned short romversoffs , romvmaj = 1 , romvmin = 0 ;
if ( SiS_Pr - > ChipType > = XGI_20 ) {
/* XGI ROMs don't qualify */
2007-02-12 11:55:06 +03:00
return false ;
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType > = SIS_761 ) {
/* I very much assume 761, 340 and newer will use new layout */
2007-02-12 11:55:06 +03:00
return true ;
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType > = SIS_661 ) {
2005-04-17 02:20:36 +04:00
if ( ( ROMAddr [ 0x1a ] = = ' N ' ) & &
2005-09-10 00:04:45 +04:00
( ROMAddr [ 0x1b ] = = ' e ' ) & &
( ROMAddr [ 0x1c ] = = ' w ' ) & &
( ROMAddr [ 0x1d ] = = ' V ' ) ) {
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
romversoffs = ROMAddr [ 0x16 ] | ( ROMAddr [ 0x17 ] < < 8 ) ;
if ( romversoffs ) {
if ( ( ROMAddr [ romversoffs + 1 ] = = ' . ' ) | | ( ROMAddr [ romversoffs + 4 ] = = ' . ' ) ) {
romvmaj = ROMAddr [ romversoffs ] - ' 0 ' ;
romvmin = ( ( ROMAddr [ romversoffs + 2 ] - ' 0 ' ) * 10 ) + ( ROMAddr [ romversoffs + 3 ] - ' 0 ' ) ;
}
}
if ( ( romvmaj ! = 0 ) | | ( romvmin > = 92 ) ) {
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
} else if ( IS_SIS650740 ) {
if ( ( ROMAddr [ 0x1a ] = = ' N ' ) & &
2005-09-10 00:04:45 +04:00
( ROMAddr [ 0x1b ] = = ' e ' ) & &
( ROMAddr [ 0x1c ] = = ' w ' ) & &
( ROMAddr [ 0x1d ] = = ' V ' ) ) {
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
}
2007-02-12 11:55:06 +03:00
return false ;
2005-04-17 02:20:36 +04:00
}
static void
2005-09-10 00:04:45 +04:00
SiSDetermineROMUsage ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char * ROMAddr = SiS_Pr - > VirtualRomBase ;
unsigned short romptr = 0 ;
2005-04-17 02:20:36 +04:00
2007-02-12 11:55:06 +03:00
SiS_Pr - > SiS_UseROM = false ;
SiS_Pr - > SiS_ROMNew = false ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_PWDOffset = 0 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = XGI_20 ) return ;
if ( ( ROMAddr ) & & ( SiS_Pr - > UseROM ) ) {
if ( SiS_Pr - > ChipType = = SIS_300 ) {
/* 300: We check if the code starts below 0x220 by
2005-04-17 02:20:36 +04:00
* checking the jmp instruction at the beginning
* of the BIOS image .
*/
if ( ( ROMAddr [ 3 ] = = 0xe9 ) & & ( ( ROMAddr [ 5 ] < < 8 ) | ROMAddr [ 4 ] ) > 0x21a )
2007-02-12 11:55:06 +03:00
SiS_Pr - > SiS_UseROM = true ;
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType < SIS_315H ) {
2005-04-17 02:20:36 +04:00
/* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
* the others do as well
*/
2007-02-12 11:55:06 +03:00
SiS_Pr - > SiS_UseROM = true ;
2005-04-17 02:20:36 +04:00
} else {
2005-09-10 00:04:45 +04:00
/* 315/330 series stick to the standard(s) */
2007-02-12 11:55:06 +03:00
SiS_Pr - > SiS_UseROM = true ;
2005-09-10 00:04:45 +04:00
if ( ( SiS_Pr - > SiS_ROMNew = SiSDetermineROMLayout661 ( SiS_Pr ) ) ) {
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_EMIOffset = 14 ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_PWDOffset = 17 ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS661LCD2TableSize = 36 ;
/* Find out about LCD data table entry size */
if ( ( romptr = SISGETROMW ( 0x0102 ) ) ) {
if ( ROMAddr [ romptr + ( 32 * 16 ) ] = = 0xff )
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS661LCD2TableSize = 32 ;
2005-04-17 02:20:36 +04:00
else if ( ROMAddr [ romptr + ( 34 * 16 ) ] = = 0xff )
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS661LCD2TableSize = 34 ;
else if ( ROMAddr [ romptr + ( 36 * 16 ) ] = = 0xff ) /* 0.94, 2.05.00+ */
SiS_Pr - > SiS661LCD2TableSize = 36 ;
2005-04-17 02:20:36 +04:00
else if ( ( ROMAddr [ romptr + ( 38 * 16 ) ] = = 0xff ) | | /* 2.00.00 - 2.02.00 */
2005-09-10 00:04:45 +04:00
( ROMAddr [ 0x6F ] & 0x01 ) ) { /* 2.03.00 - <2.05.00 */
SiS_Pr - > SiS661LCD2TableSize = 38 ; /* UMC data layout abandoned at 2.05.00 */
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_EMIOffset = 16 ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_PWDOffset = 19 ;
2005-04-17 02:20:36 +04:00
}
}
}
}
}
}
/*********************************************/
/* HELPER: SET SEGMENT REGISTERS */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetSegRegLower ( struct SiS_Private * SiS_Pr , unsigned short value )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp ;
2005-04-17 02:20:36 +04:00
value & = 0x00ff ;
temp = SiS_GetRegByte ( SiS_Pr - > SiS_P3cb ) & 0xf0 ;
temp | = ( value > > 4 ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3cb , temp ) ;
temp = SiS_GetRegByte ( SiS_Pr - > SiS_P3cd ) & 0xf0 ;
temp | = ( value & 0x0f ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3cd , temp ) ;
}
static void
2005-09-10 00:04:45 +04:00
SiS_SetSegRegUpper ( struct SiS_Private * SiS_Pr , unsigned short value )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp ;
2005-04-17 02:20:36 +04:00
value & = 0x00ff ;
temp = SiS_GetRegByte ( SiS_Pr - > SiS_P3cb ) & 0x0f ;
temp | = ( value & 0xf0 ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3cb , temp ) ;
temp = SiS_GetRegByte ( SiS_Pr - > SiS_P3cd ) & 0x0f ;
temp | = ( value < < 4 ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3cd , temp ) ;
}
static void
2005-09-10 00:04:45 +04:00
SiS_SetSegmentReg ( struct SiS_Private * SiS_Pr , unsigned short value )
2005-04-17 02:20:36 +04:00
{
SiS_SetSegRegLower ( SiS_Pr , value ) ;
SiS_SetSegRegUpper ( SiS_Pr , value ) ;
}
static void
2005-09-10 00:04:45 +04:00
SiS_ResetSegmentReg ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
SiS_SetSegmentReg ( SiS_Pr , 0 ) ;
}
static void
2005-09-10 00:04:45 +04:00
SiS_SetSegmentRegOver ( struct SiS_Private * SiS_Pr , unsigned short value )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp = value > > 8 ;
2005-04-17 02:20:36 +04:00
temp & = 0x07 ;
temp | = ( temp < < 4 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x1d , temp ) ;
SiS_SetSegmentReg ( SiS_Pr , value ) ;
}
static void
2005-09-10 00:04:45 +04:00
SiS_ResetSegmentRegOver ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
SiS_SetSegmentRegOver ( SiS_Pr , 0 ) ;
}
static void
2005-09-10 00:04:45 +04:00
SiS_ResetSegmentRegisters ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
if ( ( IS_SIS65x ) | | ( SiS_Pr - > ChipType > = SIS_661 ) ) {
2005-04-17 02:20:36 +04:00
SiS_ResetSegmentReg ( SiS_Pr ) ;
SiS_ResetSegmentRegOver ( SiS_Pr ) ;
}
}
/*********************************************/
/* HELPER: GetVBType */
/*********************************************/
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
static
# endif
void
SiS_GetVBType ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short flag = 0 , rev = 0 , nolcd = 0 ;
unsigned short p4_0f , p4_25 , p4_27 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_VBType = 0 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( ( SiS_Pr - > SiS_IF_DEF_LVDS ) | | ( SiS_Pr - > SiS_IF_DEF_CONEX ) )
return ;
if ( SiS_Pr - > ChipType = = XGI_20 )
return ;
flag = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x00 ) ;
if ( flag > 3 )
return ;
rev = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x01 ) ;
if ( flag > = 2 ) {
SiS_Pr - > SiS_VBType = VB_SIS302B ;
} else if ( flag = = 1 ) {
if ( rev > = 0xC0 ) {
SiS_Pr - > SiS_VBType = VB_SIS301C ;
} else if ( rev > = 0xB0 ) {
SiS_Pr - > SiS_VBType = VB_SIS301B ;
/* Check if 30xB DH version (no LCD support, use Panel Link instead) */
nolcd = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x23 ) ;
if ( ! ( nolcd & 0x02 ) ) SiS_Pr - > SiS_VBType | = VB_NoLCD ;
} else {
SiS_Pr - > SiS_VBType = VB_SIS301 ;
}
}
if ( SiS_Pr - > SiS_VBType & ( VB_SIS301B | VB_SIS301C | VB_SIS302B ) ) {
if ( rev > = 0xE0 ) {
flag = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x39 ) ;
if ( flag = = 0xff ) SiS_Pr - > SiS_VBType = VB_SIS302LV ;
else SiS_Pr - > SiS_VBType = VB_SIS301C ; /* VB_SIS302ELV; */
} else if ( rev > = 0xD0 ) {
SiS_Pr - > SiS_VBType = VB_SIS301LV ;
}
}
if ( SiS_Pr - > SiS_VBType & ( VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV ) ) {
p4_0f = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x0f ) ;
p4_25 = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x25 ) ;
p4_27 = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x27 ) ;
SiS_SetRegAND ( SiS_Pr - > SiS_Part4Port , 0x0f , 0x7f ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_Part4Port , 0x25 , 0x08 ) ;
SiS_SetRegAND ( SiS_Pr - > SiS_Part4Port , 0x27 , 0xfd ) ;
if ( SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x26 ) & 0x08 ) {
SiS_Pr - > SiS_VBType | = VB_UMC ;
}
SiS_SetReg ( SiS_Pr - > SiS_Part4Port , 0x27 , p4_27 ) ;
SiS_SetReg ( SiS_Pr - > SiS_Part4Port , 0x25 , p4_25 ) ;
SiS_SetReg ( SiS_Pr - > SiS_Part4Port , 0x0f , p4_0f ) ;
}
}
/*********************************************/
/* HELPER: Check RAM size */
/*********************************************/
# ifdef SIS_LINUX_KERNEL
2007-02-12 11:55:06 +03:00
static bool
2005-09-10 00:04:45 +04:00
SiS_CheckMemorySize ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex )
{
unsigned short AdapterMemSize = SiS_Pr - > VideoMemorySize / ( 1024 * 1024 ) ;
unsigned short modeflag = SiS_GetModeFlag ( SiS_Pr , ModeNo , ModeIdIndex ) ;
unsigned short memorysize = ( ( modeflag & MemoryInfoFlag ) > > MemorySizeShift ) + 1 ;
2007-02-12 11:55:06 +03:00
if ( ! AdapterMemSize ) return true ;
2005-09-10 00:04:45 +04:00
2007-02-12 11:55:06 +03:00
if ( AdapterMemSize < memorysize ) return false ;
return true ;
2005-09-10 00:04:45 +04:00
}
# endif
2005-04-17 02:20:36 +04:00
/*********************************************/
/* HELPER: Get DRAM type */
/*********************************************/
# ifdef SIS315H
2005-09-10 00:04:45 +04:00
static unsigned char
SiS_Get310DRAMType ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char data ;
2005-04-17 02:20:36 +04:00
if ( ( * SiS_Pr - > pSiS_SoftSetting ) & SoftDRAMType ) {
2005-09-10 00:04:45 +04:00
data = ( * SiS_Pr - > pSiS_SoftSetting ) & 0x03 ;
2005-04-17 02:20:36 +04:00
} else {
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = XGI_20 ) {
/* Do I need this? SR17 seems to be zero anyway... */
data = 0 ;
} else if ( SiS_Pr - > ChipType > = SIS_340 ) {
/* TODO */
data = 0 ;
} if ( SiS_Pr - > ChipType > = SIS_661 ) {
if ( SiS_Pr - > SiS_ROMNew ) {
data = ( ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x78 ) & 0xc0 ) > > 6 ) ;
} else {
data = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x78 ) & 0x07 ;
}
} else if ( IS_SIS550650740 ) {
data = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x13 ) & 0x07 ;
} else { /* 315, 330 */
data = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x3a ) & 0x03 ;
if ( SiS_Pr - > ChipType = = SIS_330 ) {
if ( data > 1 ) {
switch ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x5f ) & 0x30 ) {
case 0x00 : data = 1 ; break ;
case 0x10 : data = 3 ; break ;
case 0x20 : data = 3 ; break ;
case 0x30 : data = 2 ; break ;
}
} else {
data = 0 ;
}
}
}
2005-04-17 02:20:36 +04:00
}
return data ;
}
2005-09-10 00:04:45 +04:00
static unsigned short
SiS_GetMCLK ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char * ROMAddr = SiS_Pr - > VirtualRomBase ;
unsigned short index ;
index = SiS_Get310DRAMType ( SiS_Pr ) ;
if ( SiS_Pr - > ChipType > = SIS_661 ) {
if ( SiS_Pr - > SiS_ROMNew ) {
return ( ( unsigned short ) ( SISGETROMW ( ( 0x90 + ( index * 5 ) + 3 ) ) ) ) ;
}
return ( SiS_Pr - > SiS_MCLKData_0 [ index ] . CLOCK ) ;
} else if ( index > = 4 ) {
return ( SiS_Pr - > SiS_MCLKData_1 [ index - 4 ] . CLOCK ) ;
} else {
return ( SiS_Pr - > SiS_MCLKData_0 [ index ] . CLOCK ) ;
}
2005-04-17 02:20:36 +04:00
}
# endif
/*********************************************/
/* HELPER: ClearBuffer */
/*********************************************/
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
2005-04-17 02:20:36 +04:00
static void
2005-09-10 00:04:45 +04:00
SiS_ClearBuffer ( struct SiS_Private * SiS_Pr , unsigned short ModeNo )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char SISIOMEMTYPE * memaddr = SiS_Pr - > VideoMemoryAddress ;
unsigned int memsize = SiS_Pr - > VideoMemorySize ;
unsigned short SISIOMEMTYPE * pBuffer ;
int i ;
if ( ! memaddr | | ! memsize ) return ;
if ( SiS_Pr - > SiS_ModeType > = ModeEGA ) {
if ( ModeNo > 0x13 ) {
SiS_SetMemory ( memaddr , memsize , 0 ) ;
} else {
pBuffer = ( unsigned short SISIOMEMTYPE * ) memaddr ;
for ( i = 0 ; i < 0x4000 ; i + + ) writew ( 0x0000 , & pBuffer [ i ] ) ;
}
} else if ( SiS_Pr - > SiS_ModeType < ModeCGA ) {
pBuffer = ( unsigned short SISIOMEMTYPE * ) memaddr ;
for ( i = 0 ; i < 0x4000 ; i + + ) writew ( 0x0720 , & pBuffer [ i ] ) ;
} else {
SiS_SetMemory ( memaddr , 0x8000 , 0 ) ;
}
2005-04-17 02:20:36 +04:00
}
# endif
/*********************************************/
/* HELPER: SearchModeID */
/*********************************************/
2007-02-12 11:55:06 +03:00
bool
2005-09-10 00:04:45 +04:00
SiS_SearchModeID ( struct SiS_Private * SiS_Pr , unsigned short * ModeNo ,
unsigned short * ModeIdIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char VGAINFO = SiS_Pr - > SiS_VGAINFO ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( ( * ModeNo ) < = 0x13 ) {
2005-04-17 02:20:36 +04:00
if ( ( * ModeNo ) < = 0x05 ) ( * ModeNo ) | = 0x01 ;
2005-09-10 00:04:45 +04:00
for ( ( * ModeIdIndex ) = 0 ; ; ( * ModeIdIndex ) + + ) {
if ( SiS_Pr - > SiS_SModeIDTable [ ( * ModeIdIndex ) ] . St_ModeID = = ( * ModeNo ) ) break ;
2007-02-12 11:55:06 +03:00
if ( SiS_Pr - > SiS_SModeIDTable [ ( * ModeIdIndex ) ] . St_ModeID = = 0xFF ) return false ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
if ( ( * ModeNo ) = = 0x07 ) {
if ( VGAINFO & 0x10 ) ( * ModeIdIndex ) + + ; /* 400 lines */
/* else 350 lines */
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
if ( ( * ModeNo ) < = 0x03 ) {
if ( ! ( VGAINFO & 0x80 ) ) ( * ModeIdIndex ) + + ;
if ( VGAINFO & 0x10 ) ( * ModeIdIndex ) + + ; /* 400 lines */
/* else 350 lines */
2005-04-17 02:20:36 +04:00
}
/* else 200 lines */
} else {
2005-09-10 00:04:45 +04:00
for ( ( * ModeIdIndex ) = 0 ; ; ( * ModeIdIndex ) + + ) {
if ( SiS_Pr - > SiS_EModeIDTable [ ( * ModeIdIndex ) ] . Ext_ModeID = = ( * ModeNo ) ) break ;
2007-02-12 11:55:06 +03:00
if ( SiS_Pr - > SiS_EModeIDTable [ ( * ModeIdIndex ) ] . Ext_ModeID = = 0xFF ) return false ;
2005-04-17 02:20:36 +04:00
}
}
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* HELPER: GetModePtr */
/*********************************************/
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetModePtr ( struct SiS_Private * SiS_Pr , unsigned short ModeNo , unsigned short ModeIdIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short index ;
2005-04-17 02:20:36 +04:00
if ( ModeNo < = 0x13 ) {
index = SiS_Pr - > SiS_SModeIDTable [ ModeIdIndex ] . St_StTableIndex ;
} else {
if ( SiS_Pr - > SiS_ModeType < = ModeEGA ) index = 0x1B ;
else index = 0x0F ;
}
return index ;
}
2005-09-10 00:04:45 +04:00
/*********************************************/
/* HELPERS: Get some indices */
/*********************************************/
unsigned short
SiS_GetRefCRTVCLK ( struct SiS_Private * SiS_Pr , unsigned short Index , int UseWide )
{
if ( SiS_Pr - > SiS_RefIndex [ Index ] . Ext_InfoFlag & HaveWideTiming ) {
if ( UseWide = = 1 ) {
return SiS_Pr - > SiS_RefIndex [ Index ] . Ext_CRTVCLK_WIDE ;
} else {
return SiS_Pr - > SiS_RefIndex [ Index ] . Ext_CRTVCLK_NORM ;
}
} else {
return SiS_Pr - > SiS_RefIndex [ Index ] . Ext_CRTVCLK ;
}
}
unsigned short
SiS_GetRefCRT1CRTC ( struct SiS_Private * SiS_Pr , unsigned short Index , int UseWide )
{
if ( SiS_Pr - > SiS_RefIndex [ Index ] . Ext_InfoFlag & HaveWideTiming ) {
if ( UseWide = = 1 ) {
return SiS_Pr - > SiS_RefIndex [ Index ] . Ext_CRT1CRTC_WIDE ;
} else {
return SiS_Pr - > SiS_RefIndex [ Index ] . Ext_CRT1CRTC_NORM ;
}
} else {
return SiS_Pr - > SiS_RefIndex [ Index ] . Ext_CRT1CRTC ;
}
}
2005-04-17 02:20:36 +04:00
/*********************************************/
/* HELPER: LowModeTests */
/*********************************************/
2007-02-12 11:55:06 +03:00
static bool
2005-09-10 00:04:45 +04:00
SiS_DoLowModeTest ( struct SiS_Private * SiS_Pr , unsigned short ModeNo )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp , temp1 , temp2 ;
if ( ( ModeNo ! = 0x03 ) & & ( ModeNo ! = 0x10 ) & & ( ModeNo ! = 0x12 ) )
2007-02-12 11:55:06 +03:00
return true ;
2005-09-10 00:04:45 +04:00
temp = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x11 ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x11 , 0x80 ) ;
temp1 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x00 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x00 , 0x55 ) ;
temp2 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x00 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x00 , temp1 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x11 , temp ) ;
if ( ( SiS_Pr - > ChipType > = SIS_315H ) | |
( SiS_Pr - > ChipType = = SIS_300 ) ) {
2007-02-12 11:55:06 +03:00
if ( temp2 = = 0x55 ) return false ;
else return true ;
2005-09-10 00:04:45 +04:00
} else {
2007-02-12 11:55:06 +03:00
if ( temp2 ! = 0x55 ) return true ;
2005-09-10 00:04:45 +04:00
else {
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x35 , 0x01 ) ;
2007-02-12 11:55:06 +03:00
return false ;
2005-09-10 00:04:45 +04:00
}
}
2005-04-17 02:20:36 +04:00
}
static void
2005-09-10 00:04:45 +04:00
SiS_SetLowModeTest ( struct SiS_Private * SiS_Pr , unsigned short ModeNo )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
if ( SiS_DoLowModeTest ( SiS_Pr , ModeNo ) ) {
SiS_Pr - > SiS_SetFlag | = LowModeTests ;
}
2005-04-17 02:20:36 +04:00
}
/*********************************************/
2005-09-10 00:04:45 +04:00
/* HELPER: OPEN/CLOSE CRT1 CRTC */
2005-04-17 02:20:36 +04:00
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_OpenCRTC ( struct SiS_Private * SiS_Pr )
{
if ( IS_SIS650 ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x51 , 0x1f ) ;
if ( IS_SIS651 ) SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x51 , 0x20 ) ;
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x56 , 0xe7 ) ;
} else if ( IS_SIS661741660760 ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x61 , 0xf7 ) ;
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x51 , 0x1f ) ;
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x56 , 0xe7 ) ;
if ( ! SiS_Pr - > SiS_ROMNew ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x3a , 0xef ) ;
}
}
}
static void
SiS_CloseCRTC ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
#if 0 /* This locks some CRTC registers. We don't want that. */
unsigned short temp1 = 0 , temp2 = 0 ;
if ( IS_SIS661741660760 ) {
if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) {
temp1 = 0xa0 ; temp2 = 0x08 ;
}
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3d4 , 0x51 , 0x1f , temp1 ) ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3d4 , 0x56 , 0xe7 , temp2 ) ;
}
# endif
2005-04-17 02:20:36 +04:00
}
static void
2005-09-10 00:04:45 +04:00
SiS_HandleCRT1 ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
/* Enable CRT1 gating */
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , SiS_Pr - > SiS_MyCR63 , 0xbf ) ;
2005-04-17 02:20:36 +04:00
#if 0
2005-09-10 00:04:45 +04:00
if ( ! ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x15 ) & 0x01 ) ) {
if ( ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x15 ) & 0x0a ) | |
( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x16 ) & 0x01 ) ) {
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , SiS_Pr - > SiS_MyCR63 , 0x40 ) ;
}
}
2005-04-17 02:20:36 +04:00
# endif
}
/*********************************************/
/* HELPER: GetColorDepth */
/*********************************************/
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetColorDepth ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
static const unsigned short ColorDepth [ 6 ] = { 1 , 2 , 4 , 4 , 6 , 8 } ;
unsigned short modeflag ;
short index ;
/* Do NOT check UseCustomMode, will skrew up FIFO */
if ( ModeNo = = 0xfe ) {
modeflag = SiS_Pr - > CModeFlag ;
} else if ( ModeNo < = 0x13 ) {
modeflag = SiS_Pr - > SiS_SModeIDTable [ ModeIdIndex ] . St_ModeFlag ;
} else {
modeflag = SiS_Pr - > SiS_EModeIDTable [ ModeIdIndex ] . Ext_ModeFlag ;
}
index = ( modeflag & ModeTypeMask ) - ModeEGA ;
if ( index < 0 ) index = 0 ;
return ColorDepth [ index ] ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* HELPER: GetOffset */
/*********************************************/
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetOffset ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex , unsigned short RRTI )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short xres , temp , colordepth , infoflag ;
if ( SiS_Pr - > UseCustomMode ) {
infoflag = SiS_Pr - > CInfoFlag ;
xres = SiS_Pr - > CHDisplay ;
} else {
infoflag = SiS_Pr - > SiS_RefIndex [ RRTI ] . Ext_InfoFlag ;
xres = SiS_Pr - > SiS_RefIndex [ RRTI ] . XRes ;
}
colordepth = SiS_GetColorDepth ( SiS_Pr , ModeNo , ModeIdIndex ) ;
temp = xres / 16 ;
if ( infoflag & InterlaceMode ) temp < < = 1 ;
temp * = colordepth ;
if ( xres % 16 ) temp + = ( colordepth > > 1 ) ;
return temp ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* SEQ */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetSeqRegs ( struct SiS_Private * SiS_Pr , unsigned short StandTableIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char SRdata ;
int i ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x00 , 0x03 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* or "display off" */
SRdata = SiS_Pr - > SiS_StandTable [ StandTableIndex ] . SR [ 0 ] | 0x20 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* determine whether to force x8 dotclock */
if ( ( SiS_Pr - > SiS_VBType & VB_SISVB ) | | ( SiS_Pr - > SiS_IF_DEF_LVDS ) ) {
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV ) ) {
if ( SiS_Pr - > SiS_VBInfo & SetInSlaveMode ) SRdata | = 0x01 ;
} else if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) SRdata | = 0x01 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
}
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x01 , SRdata ) ;
for ( i = 2 ; i < = 4 ; i + + ) {
2005-09-10 00:04:45 +04:00
SRdata = SiS_Pr - > SiS_StandTable [ StandTableIndex ] . SR [ i - 1 ] ;
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , i , SRdata ) ;
}
}
/*********************************************/
/* MISC */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetMiscRegs ( struct SiS_Private * SiS_Pr , unsigned short StandTableIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char Miscdata ;
2005-04-17 02:20:36 +04:00
Miscdata = SiS_Pr - > SiS_StandTable [ StandTableIndex ] . MISC ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType < SIS_661 ) {
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) {
Miscdata | = 0x0C ;
}
2005-04-17 02:20:36 +04:00
}
}
SiS_SetRegByte ( SiS_Pr - > SiS_P3c2 , Miscdata ) ;
}
/*********************************************/
/* CRTC */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetCRTCRegs ( struct SiS_Private * SiS_Pr , unsigned short StandTableIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char CRTCdata ;
unsigned short i ;
/* Unlock CRTC */
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x11 , 0x7f ) ;
for ( i = 0 ; i < = 0x18 ; i + + ) {
CRTCdata = SiS_Pr - > SiS_StandTable [ StandTableIndex ] . CRTC [ i ] ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , i , CRTCdata ) ;
}
if ( SiS_Pr - > ChipType > = SIS_661 ) {
SiS_OpenCRTC ( SiS_Pr ) ;
for ( i = 0x13 ; i < = 0x14 ; i + + ) {
CRTCdata = SiS_Pr - > SiS_StandTable [ StandTableIndex ] . CRTC [ i ] ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , i , CRTCdata ) ;
}
} else if ( ( ( SiS_Pr - > ChipType = = SIS_630 ) | |
( SiS_Pr - > ChipType = = SIS_730 ) ) & &
( SiS_Pr - > ChipRevision > = 0x30 ) ) {
if ( SiS_Pr - > SiS_VBInfo & SetInSlaveMode ) {
if ( SiS_Pr - > SiS_VBInfo & ( SetCRT2ToLCD | SetCRT2ToTV ) ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x18 , 0xFE ) ;
}
}
}
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* ATT */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetATTRegs ( struct SiS_Private * SiS_Pr , unsigned short StandTableIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char ARdata ;
unsigned short i ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < = 0x13 ; i + + ) {
ARdata = SiS_Pr - > SiS_StandTable [ StandTableIndex ] . ATTR [ i ] ;
2005-09-10 00:04:45 +04:00
2005-04-17 02:20:36 +04:00
if ( i = = 0x13 ) {
2005-09-10 00:04:45 +04:00
/* Pixel shift. If screen on LCD or TV is shifted left or right,
* this might be the cause .
*/
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) ARdata = 0 ;
}
if ( SiS_Pr - > SiS_IF_DEF_LVDS = = 1 ) {
if ( SiS_Pr - > SiS_IF_DEF_CH70xx ! = 0 ) {
if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToTV ) {
if ( SiS_Pr - > SiS_VBInfo & SetInSlaveMode ) ARdata = 0 ;
}
}
}
if ( SiS_Pr - > ChipType > = SIS_661 ) {
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > SiS_VBInfo & ( SetCRT2ToTV | SetCRT2ToLCD ) ) {
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBInfo & SetInSlaveMode ) ARdata = 0 ;
2005-04-17 02:20:36 +04:00
}
} else if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCD ) {
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_315H ) {
2005-04-17 02:20:36 +04:00
if ( IS_SIS550650740660 ) {
2005-09-10 00:04:45 +04:00
/* 315, 330 don't do this */
if ( SiS_Pr - > SiS_VBType & VB_SIS30xB ) {
if ( SiS_Pr - > SiS_VBInfo & SetInSlaveMode ) ARdata = 0 ;
} else {
ARdata = 0 ;
}
2005-04-17 02:20:36 +04:00
}
} else {
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBInfo & SetInSlaveMode ) ARdata = 0 ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
}
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
SiS_GetRegByte ( SiS_Pr - > SiS_P3da ) ; /* reset 3da */
SiS_SetRegByte ( SiS_Pr - > SiS_P3c0 , i ) ; /* set index */
SiS_SetRegByte ( SiS_Pr - > SiS_P3c0 , ARdata ) ; /* set data */
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
SiS_GetRegByte ( SiS_Pr - > SiS_P3da ) ; /* reset 3da */
SiS_SetRegByte ( SiS_Pr - > SiS_P3c0 , 0x14 ) ; /* set index */
SiS_SetRegByte ( SiS_Pr - > SiS_P3c0 , 0x00 ) ; /* set data */
2005-04-17 02:20:36 +04:00
SiS_GetRegByte ( SiS_Pr - > SiS_P3da ) ;
2005-09-10 00:04:45 +04:00
SiS_SetRegByte ( SiS_Pr - > SiS_P3c0 , 0x20 ) ; /* Enable Attribute */
2005-04-17 02:20:36 +04:00
SiS_GetRegByte ( SiS_Pr - > SiS_P3da ) ;
}
/*********************************************/
/* GRC */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetGRCRegs ( struct SiS_Private * SiS_Pr , unsigned short StandTableIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned char GRdata ;
unsigned short i ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < = 0x08 ; i + + ) {
GRdata = SiS_Pr - > SiS_StandTable [ StandTableIndex ] . GRC [ i ] ;
SiS_SetReg ( SiS_Pr - > SiS_P3ce , i , GRdata ) ;
}
if ( SiS_Pr - > SiS_ModeType > ModeVGA ) {
/* 256 color disable */
SiS_SetRegAND ( SiS_Pr - > SiS_P3ce , 0x05 , 0xBF ) ;
}
}
/*********************************************/
/* CLEAR EXTENDED REGISTERS */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_ClearExt1Regs ( struct SiS_Private * SiS_Pr , unsigned short ModeNo )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short i ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
for ( i = 0x0A ; i < = 0x0E ; i + + ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , i , 0x00 ) ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_315H ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x37 , 0xFE ) ;
if ( ModeNo < = 0x13 ) {
if ( ModeNo = = 0x06 | | ModeNo > = 0x0e ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x0e , 0x20 ) ;
}
}
}
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* RESET VCLK */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_ResetCRT1VCLK ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_315H ) {
if ( SiS_Pr - > ChipType < SIS_661 ) {
if ( SiS_Pr - > SiS_IF_DEF_LVDS = = 0 ) return ;
2005-04-17 02:20:36 +04:00
}
} else {
if ( ( SiS_Pr - > SiS_IF_DEF_LVDS = = 0 ) & &
2005-09-10 00:04:45 +04:00
( ! ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) ) ) {
2005-04-17 02:20:36 +04:00
return ;
}
}
2005-09-10 00:04:45 +04:00
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x31 , 0xcf , 0x20 ) ;
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2B , SiS_Pr - > SiS_VCLKData [ 1 ] . SR2B ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2C , SiS_Pr - > SiS_VCLKData [ 1 ] . SR2C ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2D , 0x80 ) ;
2005-09-10 00:04:45 +04:00
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x31 , 0xcf , 0x10 ) ;
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2B , SiS_Pr - > SiS_VCLKData [ 0 ] . SR2B ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2C , SiS_Pr - > SiS_VCLKData [ 0 ] . SR2C ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2D , 0x80 ) ;
}
/*********************************************/
/* SYNC */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetCRT1Sync ( struct SiS_Private * SiS_Pr , unsigned short RRTI )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short sync ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > UseCustomMode ) {
sync = SiS_Pr - > CInfoFlag > > 8 ;
} else {
sync = SiS_Pr - > SiS_RefIndex [ RRTI ] . Ext_InfoFlag > > 8 ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
sync & = 0xC0 ;
sync | = 0x2f ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3c2 , sync ) ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* CRTC/2 */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetCRT1CRTC ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex , unsigned short RRTI )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp , i , j , modeflag ;
unsigned char * crt1data = NULL ;
modeflag = SiS_GetModeFlag ( SiS_Pr , ModeNo , ModeIdIndex ) ;
if ( SiS_Pr - > UseCustomMode ) {
crt1data = & SiS_Pr - > CCRT1CRTC [ 0 ] ;
} else {
temp = SiS_GetRefCRT1CRTC ( SiS_Pr , RRTI , SiS_Pr - > SiS_UseWide ) ;
/* Alternate for 1600x1200 LCDA */
if ( ( temp = = 0x20 ) & & ( SiS_Pr - > Alternate1600x1200 ) ) temp = 0x57 ;
crt1data = ( unsigned char * ) & SiS_Pr - > SiS_CRT1Table [ temp ] . CR [ 0 ] ;
}
/* unlock cr0-7 */
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x11 , 0x7f ) ;
for ( i = 0 , j = 0 ; i < = 7 ; i + + , j + + ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , j , crt1data [ i ] ) ;
}
for ( j = 0x10 ; i < = 10 ; i + + , j + + ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , j , crt1data [ i ] ) ;
}
for ( j = 0x15 ; i < = 12 ; i + + , j + + ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , j , crt1data [ i ] ) ;
}
for ( j = 0x0A ; i < = 15 ; i + + , j + + ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , j , crt1data [ i ] ) ;
}
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x0E , crt1data [ 16 ] & 0xE0 ) ;
temp = ( crt1data [ 16 ] & 0x01 ) < < 5 ;
if ( modeflag & DoubleScanMode ) temp | = 0x80 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3d4 , 0x09 , 0x5F , temp ) ;
if ( SiS_Pr - > SiS_ModeType > ModeVGA ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x14 , 0x4F ) ;
}
# ifdef SIS315H
if ( SiS_Pr - > ChipType = = XGI_20 ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x04 , crt1data [ 4 ] - 1 ) ;
if ( ! ( temp = crt1data [ 5 ] & 0x1f ) ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x0c , 0xfb ) ;
}
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3d4 , 0x05 , 0xe0 , ( ( temp - 1 ) & 0x1f ) ) ;
temp = ( crt1data [ 16 ] > > 5 ) + 3 ;
if ( temp > 7 ) temp - = 7 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0e , 0x1f , ( temp < < 5 ) ) ;
}
# endif
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* OFFSET & PITCH */
/*********************************************/
/* (partly overruled by SetPitch() in XF86) */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetCRT1Offset ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex , unsigned short RRTI )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp , DisplayUnit , infoflag ;
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > UseCustomMode ) {
infoflag = SiS_Pr - > CInfoFlag ;
} else {
2005-09-10 00:04:45 +04:00
infoflag = SiS_Pr - > SiS_RefIndex [ RRTI ] . Ext_InfoFlag ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
DisplayUnit = SiS_GetOffset ( SiS_Pr , ModeNo , ModeIdIndex , RRTI ) ;
2005-04-17 02:20:36 +04:00
temp = ( DisplayUnit > > 8 ) & 0x0f ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0E , 0xF0 , temp ) ;
2005-09-10 00:04:45 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x13 , DisplayUnit & 0xFF ) ;
2005-04-17 02:20:36 +04:00
if ( infoflag & InterlaceMode ) DisplayUnit > > = 1 ;
DisplayUnit < < = 5 ;
2005-09-10 00:04:45 +04:00
temp = ( DisplayUnit > > 8 ) + 1 ;
2005-04-17 02:20:36 +04:00
if ( DisplayUnit & 0xff ) temp + + ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType = = XGI_20 ) {
if ( ModeNo = = 0x4a | | ModeNo = = 0x49 ) temp - - ;
}
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x10 , temp ) ;
}
/*********************************************/
/* VCLK */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetCRT1VCLK ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex , unsigned short RRTI )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short index = 0 , clka , clkb ;
if ( SiS_Pr - > UseCustomMode ) {
clka = SiS_Pr - > CSR2B ;
clkb = SiS_Pr - > CSR2C ;
} else {
index = SiS_GetVCLK2Ptr ( SiS_Pr , ModeNo , ModeIdIndex , RRTI ) ;
if ( ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) & &
( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) ) {
/* Alternate for 1600x1200 LCDA */
if ( ( index = = 0x21 ) & & ( SiS_Pr - > Alternate1600x1200 ) ) index = 0x72 ;
clka = SiS_Pr - > SiS_VBVCLKData [ index ] . Part4_A ;
clkb = SiS_Pr - > SiS_VBVCLKData [ index ] . Part4_B ;
} else {
clka = SiS_Pr - > SiS_VCLKData [ index ] . SR2B ;
clkb = SiS_Pr - > SiS_VCLKData [ index ] . SR2C ;
}
}
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x31 , 0xCF ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2b , clka ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2c , clkb ) ;
if ( SiS_Pr - > ChipType > = SIS_315H ) {
# ifdef SIS315H
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2D , 0x01 ) ;
if ( SiS_Pr - > ChipType = = XGI_20 ) {
unsigned short mf = SiS_GetModeFlag ( SiS_Pr , ModeNo , ModeIdIndex ) ;
if ( mf & HalfDCLK ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2b , SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x2b ) ) ;
clkb = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x2c ) ;
clkb = ( ( ( clkb & 0x1f ) < < 1 ) + 1 ) | ( clkb & 0xe0 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2c , clkb ) ;
}
}
# endif
} else {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2D , 0x80 ) ;
}
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* FIFO */
/*********************************************/
# ifdef SIS300
2005-09-10 00:04:45 +04:00
void
SiS_GetFIFOThresholdIndex300 ( struct SiS_Private * SiS_Pr , unsigned short * idx1 ,
unsigned short * idx2 )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short temp1 , temp2 ;
static const unsigned char ThTiming [ 8 ] = {
1 , 2 , 2 , 3 , 0 , 1 , 1 , 2
} ;
temp1 = temp2 = ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x18 ) & 0x62 ) > > 1 ;
( * idx2 ) = ( unsigned short ) ( ThTiming [ ( ( temp2 > > 3 ) | temp1 ) & 0x07 ] ) ;
( * idx1 ) = ( unsigned short ) ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x16 ) > > 6 ) & 0x03 ;
( * idx1 ) | = ( unsigned short ) ( ( ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x14 ) > > 4 ) & 0x0c ) ) ;
( * idx1 ) < < = 1 ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
static unsigned short
SiS_GetFIFOThresholdA300 ( unsigned short idx1 , unsigned short idx2 )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
static const unsigned char ThLowA [ 8 * 3 ] = {
61 , 3 , 52 , 5 , 68 , 7 , 100 , 11 ,
43 , 3 , 42 , 5 , 54 , 7 , 78 , 11 ,
34 , 3 , 37 , 5 , 47 , 7 , 67 , 11
} ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
return ( unsigned short ) ( ( ThLowA [ idx1 + 1 ] * idx2 ) + ThLowA [ idx1 ] ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetFIFOThresholdB300 ( unsigned short idx1 , unsigned short idx2 )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
static const unsigned char ThLowB [ 8 * 3 ] = {
81 , 4 , 72 , 6 , 88 , 8 , 120 , 12 ,
55 , 4 , 54 , 6 , 66 , 8 , 90 , 12 ,
42 , 4 , 45 , 6 , 55 , 8 , 75 , 12
} ;
return ( unsigned short ) ( ( ThLowB [ idx1 + 1 ] * idx2 ) + ThLowB [ idx1 ] ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
static unsigned short
SiS_DoCalcDelay ( struct SiS_Private * SiS_Pr , unsigned short MCLK , unsigned short VCLK ,
unsigned short colordepth , unsigned short key )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short idx1 , idx2 ;
unsigned int longtemp = VCLK * colordepth ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_GetFIFOThresholdIndex300 ( SiS_Pr , & idx1 , & idx2 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( key = = 0 ) {
longtemp * = SiS_GetFIFOThresholdA300 ( idx1 , idx2 ) ;
} else {
longtemp * = SiS_GetFIFOThresholdB300 ( idx1 , idx2 ) ;
}
idx1 = longtemp % ( MCLK * 16 ) ;
longtemp / = ( MCLK * 16 ) ;
if ( idx1 ) longtemp + + ;
return ( unsigned short ) longtemp ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
static unsigned short
SiS_CalcDelay ( struct SiS_Private * SiS_Pr , unsigned short VCLK ,
unsigned short colordepth , unsigned short MCLK )
{
unsigned short temp1 , temp2 ;
temp2 = SiS_DoCalcDelay ( SiS_Pr , MCLK , VCLK , colordepth , 0 ) ;
temp1 = SiS_DoCalcDelay ( SiS_Pr , MCLK , VCLK , colordepth , 1 ) ;
if ( temp1 < 4 ) temp1 = 4 ;
temp1 - = 4 ;
if ( temp2 < temp1 ) temp2 = temp1 ;
return temp2 ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
static void
SiS_SetCRT1FIFO_300 ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short RefreshRateTableIndex )
{
unsigned short ThresholdLow = 0 ;
unsigned short temp , index , VCLK , MCLK , colorth ;
static const unsigned short colortharray [ 6 ] = { 1 , 1 , 2 , 2 , 3 , 4 } ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( ModeNo > 0x13 ) {
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Get VCLK */
if ( SiS_Pr - > UseCustomMode ) {
VCLK = SiS_Pr - > CSRClock ;
} else {
index = SiS_GetRefCRTVCLK ( SiS_Pr , RefreshRateTableIndex , SiS_Pr - > SiS_UseWide ) ;
VCLK = SiS_Pr - > SiS_VCLKData [ index ] . CLOCK ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Get half colordepth */
colorth = colortharray [ ( SiS_Pr - > SiS_ModeType - ModeEGA ) ] ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Get MCLK */
index = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x3A ) & 0x07 ;
MCLK = SiS_Pr - > SiS_MCLKData_0 [ index ] . CLOCK ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
temp = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x35 ) & 0xc3 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x16 , 0x3c , temp ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
do {
ThresholdLow = SiS_CalcDelay ( SiS_Pr , VCLK , colorth , MCLK ) + 1 ;
if ( ThresholdLow < 0x13 ) break ;
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x16 , 0xfc ) ;
ThresholdLow = 0x13 ;
temp = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x16 ) > > 6 ;
if ( ! temp ) break ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x16 , 0x3f , ( ( temp - 1 ) < < 6 ) ) ;
} while ( 0 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
} else ThresholdLow = 2 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Write CRT/CPU threshold low, CRT/Engine threshold high */
temp = ( ThresholdLow < < 4 ) | 0x0f ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x08 , temp ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
temp = ( ThresholdLow & 0x10 ) < < 1 ;
if ( ModeNo > 0x13 ) temp | = 0x40 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0f , 0x9f , temp ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* What is this? */
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x3B , 0x09 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Write CRT/CPU threshold high */
temp = ThresholdLow + 3 ;
if ( temp > 0x0f ) temp = 0x0f ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x09 , temp ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
unsigned short
SiS_GetLatencyFactor630 ( struct SiS_Private * SiS_Pr , unsigned short index )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
static const unsigned char LatencyFactor [ ] = {
97 , 88 , 86 , 79 , 77 , 0 , /* 64 bit BQ=2 */
0 , 87 , 85 , 78 , 76 , 54 , /* 64 bit BQ=1 */
97 , 88 , 86 , 79 , 77 , 0 , /* 128 bit BQ=2 */
0 , 79 , 77 , 70 , 68 , 48 , /* 128 bit BQ=1 */
80 , 72 , 69 , 63 , 61 , 0 , /* 64 bit BQ=2 */
0 , 70 , 68 , 61 , 59 , 37 , /* 64 bit BQ=1 */
86 , 77 , 75 , 68 , 66 , 0 , /* 128 bit BQ=2 */
0 , 68 , 66 , 59 , 57 , 37 /* 128 bit BQ=1 */
} ;
static const unsigned char LatencyFactor730 [ ] = {
69 , 63 , 61 ,
86 , 79 , 77 ,
103 , 96 , 94 ,
120 , 113 , 111 ,
137 , 130 , 128
} ;
if ( SiS_Pr - > ChipType = = SIS_730 ) {
return ( unsigned short ) LatencyFactor730 [ index ] ;
} else {
return ( unsigned short ) LatencyFactor [ index ] ;
}
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
static unsigned short
SiS_CalcDelay2 ( struct SiS_Private * SiS_Pr , unsigned char key )
{
unsigned short index ;
if ( SiS_Pr - > ChipType = = SIS_730 ) {
index = ( ( key & 0x0f ) * 3 ) + ( ( key & 0xc0 ) > > 6 ) ;
} else {
index = ( key & 0xe0 ) > > 5 ;
if ( key & 0x10 ) index + = 6 ;
if ( ! ( key & 0x01 ) ) index + = 24 ;
if ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x14 ) & 0x80 ) index + = 12 ;
}
return SiS_GetLatencyFactor630 ( SiS_Pr , index ) ;
}
2005-04-17 02:20:36 +04:00
static void
2005-09-10 00:04:45 +04:00
SiS_SetCRT1FIFO_630 ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short RefreshRateTableIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short ThresholdLow = 0 ;
unsigned short i , data , VCLK , MCLK16 , colorth = 0 ;
unsigned int templ , datal ;
const unsigned char * queuedata = NULL ;
static const unsigned char FQBQData [ 21 ] = {
0x01 , 0x21 , 0x41 , 0x61 , 0x81 ,
0x31 , 0x51 , 0x71 , 0x91 , 0xb1 ,
0x00 , 0x20 , 0x40 , 0x60 , 0x80 ,
0x30 , 0x50 , 0x70 , 0x90 , 0xb0 ,
0xff
} ;
static const unsigned char FQBQData730 [ 16 ] = {
0x34 , 0x74 , 0xb4 ,
0x23 , 0x63 , 0xa3 ,
0x12 , 0x52 , 0x92 ,
0x01 , 0x41 , 0x81 ,
0x00 , 0x40 , 0x80 ,
0xff
} ;
static const unsigned short colortharray [ 6 ] = {
1 , 1 , 2 , 2 , 3 , 4
} ;
i = 0 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( ModeNo > 0x13 ) {
/* Get VCLK */
if ( SiS_Pr - > UseCustomMode ) {
VCLK = SiS_Pr - > CSRClock ;
} else {
data = SiS_GetRefCRTVCLK ( SiS_Pr , RefreshRateTableIndex , SiS_Pr - > SiS_UseWide ) ;
VCLK = SiS_Pr - > SiS_VCLKData [ data ] . CLOCK ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Get MCLK * 16 */
data = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x1A ) & 0x07 ;
MCLK16 = SiS_Pr - > SiS_MCLKData_0 [ data ] . CLOCK * 16 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Get half colordepth */
colorth = colortharray [ ( SiS_Pr - > SiS_ModeType - ModeEGA ) ] ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType = = SIS_730 ) {
queuedata = & FQBQData730 [ 0 ] ;
} else {
queuedata = & FQBQData [ 0 ] ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
do {
templ = SiS_CalcDelay2 ( SiS_Pr , queuedata [ i ] ) * VCLK * colorth ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
datal = templ % MCLK16 ;
templ = ( templ / MCLK16 ) + 1 ;
if ( datal ) templ + + ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( templ > 0x13 ) {
if ( queuedata [ i + 1 ] = = 0xFF ) {
ThresholdLow = 0x13 ;
break ;
}
i + + ;
} else {
ThresholdLow = templ ;
break ;
}
} while ( queuedata [ i ] ! = 0xFF ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
} else {
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType ! = SIS_730 ) i = 9 ;
ThresholdLow = 0x02 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Write CRT/CPU threshold low, CRT/Engine threshold high */
data = ( ( ThresholdLow & 0x0f ) < < 4 ) | 0x0f ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x08 , data ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
data = ( ThresholdLow & 0x10 ) < < 1 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0F , 0xDF , data ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* What is this? */
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x3B , 0x09 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Write CRT/CPU threshold high (gap = 3) */
data = ThresholdLow + 3 ;
if ( data > 0x0f ) data = 0x0f ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x09 , 0x80 , data ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Write foreground and background queue */
# ifdef SIS_LINUX_KERNEL
templ = sisfb_read_nbridge_pci_dword ( SiS_Pr , 0x50 ) ;
# else
templ = pciReadLong ( 0x00000000 , 0x50 ) ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType = = SIS_730 ) {
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
templ & = 0xfffff9ff ;
templ | = ( ( queuedata [ i ] & 0xc0 ) < < 3 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
} else {
templ & = 0xf0ffffff ;
if ( ( ModeNo < = 0x13 ) & &
( SiS_Pr - > ChipType = = SIS_630 ) & &
( SiS_Pr - > ChipRevision > = 0x30 ) ) {
templ | = 0x0b000000 ;
} else {
templ | = ( ( queuedata [ i ] & 0xf0 ) < < 20 ) ;
}
}
# ifdef SIS_LINUX_KERNEL
sisfb_write_nbridge_pci_dword ( SiS_Pr , 0x50 , templ ) ;
templ = sisfb_read_nbridge_pci_dword ( SiS_Pr , 0xA0 ) ;
# else
pciWriteLong ( 0x00000000 , 0x50 , templ ) ;
templ = pciReadLong ( 0x00000000 , 0xA0 ) ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
/* GUI grant timer (PCI config 0xA3) */
if ( SiS_Pr - > ChipType = = SIS_730 ) {
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
templ & = 0x00ffffff ;
datal = queuedata [ i ] < < 8 ;
templ | = ( ( ( datal & 0x0f00 ) | ( ( datal & 0x3000 ) > > 8 ) ) < < 20 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
} else {
templ & = 0xf0ffffff ;
templ | = ( ( queuedata [ i ] & 0x0f ) < < 24 ) ;
}
# ifdef SIS_LINUX_KERNEL
sisfb_write_nbridge_pci_dword ( SiS_Pr , 0xA0 , templ ) ;
# else
pciWriteLong ( 0x00000000 , 0xA0 , templ ) ;
2005-04-17 02:20:36 +04:00
# endif
}
2005-09-10 00:04:45 +04:00
# endif /* SIS300 */
# ifdef SIS315H
static void
SiS_SetCRT1FIFO_310 ( struct SiS_Private * SiS_Pr , unsigned short ModeNo , unsigned short ModeIdIndex )
{
unsigned short modeflag ;
/* disable auto-threshold */
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x3D , 0xFE ) ;
modeflag = SiS_GetModeFlag ( SiS_Pr , ModeNo , ModeIdIndex ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x08 , 0xAE ) ;
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x09 , 0xF0 ) ;
if ( ModeNo > 0x13 ) {
if ( SiS_Pr - > ChipType > = XGI_20 ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x08 , 0x34 ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x3D , 0x01 ) ;
} else if ( SiS_Pr - > ChipType > = SIS_661 ) {
if ( ! ( modeflag & HalfDCLK ) ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x08 , 0x34 ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x3D , 0x01 ) ;
}
} else {
if ( ( ! ( modeflag & DoubleScanMode ) ) | | ( ! ( modeflag & HalfDCLK ) ) ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x08 , 0x34 ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x3D , 0x01 ) ;
}
}
}
}
# endif
2005-04-17 02:20:36 +04:00
/*********************************************/
2005-09-10 00:04:45 +04:00
/* MODE REGISTERS */
2005-04-17 02:20:36 +04:00
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetVCLKState ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short RefreshRateTableIndex , unsigned short ModeIdIndex )
{
unsigned short data = 0 , VCLK = 0 , index = 0 ;
if ( ModeNo > 0x13 ) {
if ( SiS_Pr - > UseCustomMode ) {
VCLK = SiS_Pr - > CSRClock ;
} else {
index = SiS_GetVCLK2Ptr ( SiS_Pr , ModeNo , ModeIdIndex , RefreshRateTableIndex ) ;
VCLK = SiS_Pr - > SiS_VCLKData [ index ] . CLOCK ;
}
}
if ( SiS_Pr - > ChipType < SIS_315H ) {
# ifdef SIS300
if ( VCLK > 150 ) data | = 0x80 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x07 , 0x7B , data ) ;
data = 0x00 ;
if ( VCLK > = 150 ) data | = 0x08 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x32 , 0xF7 , data ) ;
# endif
} else if ( SiS_Pr - > ChipType < XGI_20 ) {
# ifdef SIS315H
if ( VCLK > = 166 ) data | = 0x0c ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x32 , 0xf3 , data ) ;
if ( VCLK > = 166 ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x1f , 0xe7 ) ;
}
# endif
} else {
# ifdef SIS315H
if ( VCLK > = 200 ) data | = 0x0c ;
if ( SiS_Pr - > ChipType = = XGI_20 ) data & = ~ 0x04 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x32 , 0xf3 , data ) ;
if ( SiS_Pr - > ChipType ! = XGI_20 ) {
data = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x1f ) & 0xe7 ;
if ( VCLK < 200 ) data | = 0x10 ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x1f , data ) ;
}
# endif
}
/* DAC speed */
if ( SiS_Pr - > ChipType > = SIS_661 ) {
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x07 , 0xE8 , 0x10 ) ;
} else {
data = 0x03 ;
if ( VCLK > = 260 ) data = 0x00 ;
else if ( VCLK > = 160 ) data = 0x01 ;
else if ( VCLK > = 135 ) data = 0x02 ;
if ( SiS_Pr - > ChipType = = SIS_540 ) {
if ( ( VCLK = = 203 ) | | ( VCLK < 234 ) ) data = 0x02 ;
}
if ( SiS_Pr - > ChipType < SIS_315H ) {
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x07 , 0xFC , data ) ;
} else {
if ( SiS_Pr - > ChipType > SIS_315PRO ) {
if ( ModeNo > 0x13 ) data & = 0xfc ;
}
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x07 , 0xF8 , data ) ;
}
}
}
static void
SiS_SetCRT1ModeRegs ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex , unsigned short RRTI )
{
unsigned short data , infoflag = 0 , modeflag , resindex ;
# ifdef SIS315H
unsigned char * ROMAddr = SiS_Pr - > VirtualRomBase ;
unsigned short data2 , data3 ;
# endif
modeflag = SiS_GetModeFlag ( SiS_Pr , ModeNo , ModeIdIndex ) ;
if ( SiS_Pr - > UseCustomMode ) {
infoflag = SiS_Pr - > CInfoFlag ;
} else {
resindex = SiS_GetResInfo ( SiS_Pr , ModeNo , ModeIdIndex ) ;
if ( ModeNo > 0x13 ) {
infoflag = SiS_Pr - > SiS_RefIndex [ RRTI ] . Ext_InfoFlag ;
}
}
/* Disable DPMS */
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x1F , 0x3F ) ;
data = 0 ;
if ( ModeNo > 0x13 ) {
if ( SiS_Pr - > SiS_ModeType > ModeEGA ) {
data | = 0x02 ;
data | = ( ( SiS_Pr - > SiS_ModeType - ModeVGA ) < < 2 ) ;
}
if ( infoflag & InterlaceMode ) data | = 0x20 ;
}
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x06 , 0xC0 , data ) ;
if ( SiS_Pr - > ChipType ! = SIS_300 ) {
data = 0 ;
if ( infoflag & InterlaceMode ) {
/* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
int hrs = ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x04 ) |
( ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x0b ) & 0xc0 ) < < 2 ) ) - 3 ;
int hto = ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x00 ) |
( ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x0b ) & 0x03 ) < < 8 ) ) + 5 ;
data = hrs - ( hto > > 1 ) + 3 ;
}
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x19 , data ) ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3d4 , 0x1a , 0xFC , ( ( data > > 8 ) & 0x03 ) ) ;
}
if ( modeflag & HalfDCLK ) {
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x01 , 0x08 ) ;
}
data = 0 ;
if ( modeflag & LineCompareOff ) data = 0x08 ;
if ( SiS_Pr - > ChipType = = SIS_300 ) {
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0F , 0xF7 , data ) ;
} else {
if ( SiS_Pr - > ChipType > = XGI_20 ) data | = 0x20 ;
if ( SiS_Pr - > SiS_ModeType = = ModeEGA ) {
if ( ModeNo > 0x13 ) {
data | = 0x40 ;
}
}
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0F , 0xB7 , data ) ;
}
# ifdef SIS315H
if ( SiS_Pr - > ChipType > = SIS_315H ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3c4 , 0x31 , 0xfb ) ;
}
if ( SiS_Pr - > ChipType = = SIS_315PRO ) {
data = SiS_Pr - > SiS_SR15 [ ( 2 * 4 ) + SiS_Get310DRAMType ( SiS_Pr ) ] ;
if ( SiS_Pr - > SiS_ModeType = = ModeText ) {
data & = 0xc7 ;
} else {
data2 = SiS_GetOffset ( SiS_Pr , ModeNo , ModeIdIndex , RRTI ) > > 1 ;
if ( infoflag & InterlaceMode ) data2 > > = 1 ;
data3 = SiS_GetColorDepth ( SiS_Pr , ModeNo , ModeIdIndex ) > > 1 ;
if ( data3 ) data2 / = data3 ;
if ( data2 > = 0x50 ) {
data & = 0x0f ;
data | = 0x50 ;
}
}
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x17 , data ) ;
} else if ( ( SiS_Pr - > ChipType = = SIS_330 ) | | ( SiS_Pr - > SiS_SysFlags & SF_760LFB ) ) {
data = SiS_Get310DRAMType ( SiS_Pr ) ;
if ( SiS_Pr - > ChipType = = SIS_330 ) {
data = SiS_Pr - > SiS_SR15 [ ( 2 * 4 ) + data ] ;
} else {
if ( SiS_Pr - > SiS_ROMNew ) data = ROMAddr [ 0xf6 ] ;
else if ( SiS_Pr - > SiS_UseROM ) data = ROMAddr [ 0x100 + data ] ;
else data = 0xba ;
}
if ( SiS_Pr - > SiS_ModeType < = ModeEGA ) {
data & = 0xc7 ;
} else {
if ( SiS_Pr - > UseCustomMode ) {
data2 = SiS_Pr - > CSRClock ;
} else {
data2 = SiS_GetVCLK2Ptr ( SiS_Pr , ModeNo , ModeIdIndex , RRTI ) ;
data2 = SiS_Pr - > SiS_VCLKData [ data2 ] . CLOCK ;
}
data3 = SiS_GetColorDepth ( SiS_Pr , ModeNo , ModeIdIndex ) > > 1 ;
if ( data3 ) data2 * = data3 ;
data2 = ( ( unsigned int ) ( SiS_GetMCLK ( SiS_Pr ) * 1024 ) ) / data2 ;
if ( SiS_Pr - > ChipType = = SIS_330 ) {
if ( SiS_Pr - > SiS_ModeType ! = Mode16Bpp ) {
if ( data2 > = 0x19c ) data = 0xba ;
else if ( data2 > = 0x140 ) data = 0x7a ;
else if ( data2 > = 0x101 ) data = 0x3a ;
else if ( data2 > = 0xf5 ) data = 0x32 ;
else if ( data2 > = 0xe2 ) data = 0x2a ;
else if ( data2 > = 0xc4 ) data = 0x22 ;
else if ( data2 > = 0xac ) data = 0x1a ;
else if ( data2 > = 0x9e ) data = 0x12 ;
else if ( data2 > = 0x8e ) data = 0x0a ;
else data = 0x02 ;
} else {
if ( data2 > = 0x127 ) data = 0xba ;
else data = 0x7a ;
}
} else { /* 76x+LFB */
if ( data2 > = 0x190 ) data = 0xba ;
else if ( data2 > = 0xff ) data = 0x7a ;
else if ( data2 > = 0xd3 ) data = 0x3a ;
else if ( data2 > = 0xa9 ) data = 0x1a ;
else if ( data2 > = 0x93 ) data = 0x0a ;
else data = 0x02 ;
}
}
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x17 , data ) ;
}
/* XGI: Nothing. */
/* TODO: Check SiS340 */
# endif
data = 0x60 ;
if ( SiS_Pr - > SiS_ModeType ! = ModeText ) {
data ^ = 0x60 ;
if ( SiS_Pr - > SiS_ModeType ! = ModeEGA ) {
data ^ = 0xA0 ;
}
}
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x21 , 0x1F , data ) ;
SiS_SetVCLKState ( SiS_Pr , ModeNo , RRTI , ModeIdIndex ) ;
# ifdef SIS315H
if ( ( ( SiS_Pr - > ChipType > = SIS_315H ) & & ( SiS_Pr - > ChipType < SIS_661 ) ) | |
( SiS_Pr - > ChipType = = XGI_40 ) ) {
if ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x31 ) & 0x40 ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x52 , 0x2c ) ;
} else {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x52 , 0x6c ) ;
}
} else if ( SiS_Pr - > ChipType = = XGI_20 ) {
if ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x31 ) & 0x40 ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x52 , 0x33 ) ;
} else {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x52 , 0x73 ) ;
}
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x51 , 0x02 ) ;
}
# endif
}
# ifdef SIS315H
static void
SiS_SetupDualChip ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
#if 0
/* TODO: Find out about IOAddress2 */
SISIOADDRESS P2_3c2 = SiS_Pr - > IOAddress2 + 0x12 ;
SISIOADDRESS P2_3c4 = SiS_Pr - > IOAddress2 + 0x14 ;
SISIOADDRESS P2_3ce = SiS_Pr - > IOAddress2 + 0x1e ;
2005-04-17 02:20:36 +04:00
int i ;
2005-09-10 00:04:45 +04:00
if ( ( SiS_Pr - > ChipRevision ! = 0 ) | |
( ! ( SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x3a ) & 0x04 ) ) )
return ;
for ( i = 0 ; i < = 4 ; i + + ) { /* SR00 - SR04 */
SiS_SetReg ( P2_3c4 , i , SiS_GetReg ( SiS_Pr - > SiS_P3c4 , i ) ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
for ( i = 0 ; i < = 8 ; i + + ) { /* GR00 - GR08 */
SiS_SetReg ( P2_3ce , i , SiS_GetReg ( SiS_Pr - > SiS_P3ce , i ) ) ;
}
SiS_SetReg ( P2_3c4 , 0x05 , 0x86 ) ;
SiS_SetReg ( P2_3c4 , 0x06 , SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x06 ) ) ; /* SR06 */
SiS_SetReg ( P2_3c4 , 0x21 , SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x21 ) ) ; /* SR21 */
SiS_SetRegByte ( P2_3c2 , SiS_GetRegByte ( SiS_Pr - > SiS_P3cc ) ) ; /* MISC */
SiS_SetReg ( P2_3c4 , 0x05 , 0x00 ) ;
# endif
2005-04-17 02:20:36 +04:00
}
# endif
2005-09-10 00:04:45 +04:00
/*********************************************/
/* LOAD DAC */
/*********************************************/
2005-04-17 02:20:36 +04:00
static void
2005-09-10 00:04:45 +04:00
SiS_WriteDAC ( struct SiS_Private * SiS_Pr , SISIOADDRESS DACData , unsigned short shiftflag ,
unsigned short dl , unsigned short ah , unsigned short al , unsigned short dh )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short d1 , d2 , d3 ;
switch ( dl ) {
case 0 : d1 = dh ; d2 = ah ; d3 = al ; break ;
case 1 : d1 = ah ; d2 = al ; d3 = dh ; break ;
default : d1 = al ; d2 = dh ; d3 = ah ;
}
SiS_SetRegByte ( DACData , ( d1 < < shiftflag ) ) ;
SiS_SetRegByte ( DACData , ( d2 < < shiftflag ) ) ;
SiS_SetRegByte ( DACData , ( d3 < < shiftflag ) ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_LoadDAC ( struct SiS_Private * SiS_Pr , unsigned short ModeNo , unsigned short ModeIdIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short data , data2 , time , i , j , k , m , n , o ;
unsigned short si , di , bx , sf ;
2005-04-17 02:20:36 +04:00
SISIOADDRESS DACAddr , DACData ;
2005-09-10 00:04:45 +04:00
const unsigned char * table = NULL ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
data = SiS_GetModeFlag ( SiS_Pr , ModeNo , ModeIdIndex ) & DACInfoFlag ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
j = time = 64 ;
if ( data = = 0x00 ) table = SiS_MDA_DAC ;
else if ( data = = 0x08 ) table = SiS_CGA_DAC ;
else if ( data = = 0x10 ) table = SiS_EGA_DAC ;
else if ( data = = 0x18 ) {
j = 16 ;
2005-04-17 02:20:36 +04:00
time = 256 ;
table = SiS_VGA_DAC ;
}
if ( ( ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCD ) & & /* 301B-DH LCD */
( SiS_Pr - > SiS_VBType & VB_NoLCD ) ) | |
( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) | | /* LCDA */
( ! ( SiS_Pr - > SiS_SetFlag & ProgrammingCRT2 ) ) ) { /* Programming CRT1 */
2005-09-10 00:04:45 +04:00
SiS_SetRegByte ( SiS_Pr - > SiS_P3c6 , 0xFF ) ;
2005-04-17 02:20:36 +04:00
DACAddr = SiS_Pr - > SiS_P3c8 ;
DACData = SiS_Pr - > SiS_P3c9 ;
2005-09-10 00:04:45 +04:00
sf = 0 ;
2005-04-17 02:20:36 +04:00
} else {
DACAddr = SiS_Pr - > SiS_Part5Port ;
DACData = SiS_Pr - > SiS_Part5Port + 1 ;
2005-09-10 00:04:45 +04:00
sf = 2 ;
2005-04-17 02:20:36 +04:00
}
SiS_SetRegByte ( DACAddr , 0x00 ) ;
2005-09-10 00:04:45 +04:00
for ( i = 0 ; i < j ; i + + ) {
2005-04-17 02:20:36 +04:00
data = table [ i ] ;
2005-09-10 00:04:45 +04:00
for ( k = 0 ; k < 3 ; k + + ) {
2005-04-17 02:20:36 +04:00
data2 = 0 ;
2005-09-10 00:04:45 +04:00
if ( data & 0x01 ) data2 + = 0x2A ;
2005-04-17 02:20:36 +04:00
if ( data & 0x02 ) data2 + = 0x15 ;
2005-09-10 00:04:45 +04:00
SiS_SetRegByte ( DACData , ( data2 < < sf ) ) ;
2005-04-17 02:20:36 +04:00
data > > = 2 ;
}
}
if ( time = = 256 ) {
for ( i = 16 ; i < 32 ; i + + ) {
2005-09-10 00:04:45 +04:00
data = table [ i ] < < sf ;
2005-04-17 02:20:36 +04:00
for ( k = 0 ; k < 3 ; k + + ) SiS_SetRegByte ( DACData , data ) ;
}
si = 32 ;
for ( m = 0 ; m < 9 ; m + + ) {
2005-09-10 00:04:45 +04:00
di = si ;
bx = si + 4 ;
for ( n = 0 ; n < 3 ; n + + ) {
for ( o = 0 ; o < 5 ; o + + ) {
SiS_WriteDAC ( SiS_Pr , DACData , sf , n , table [ di ] , table [ bx ] , table [ si ] ) ;
2005-04-17 02:20:36 +04:00
si + + ;
}
si - = 2 ;
for ( o = 0 ; o < 3 ; o + + ) {
2005-09-10 00:04:45 +04:00
SiS_WriteDAC ( SiS_Pr , DACData , sf , n , table [ di ] , table [ si ] , table [ bx ] ) ;
2005-04-17 02:20:36 +04:00
si - - ;
}
} /* for n < 3 */
si + = 5 ;
} /* for m < 9 */
}
}
/*********************************************/
/* SET CRT1 REGISTER GROUP */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_SetCRT1Group ( struct SiS_Private * SiS_Pr , unsigned short ModeNo , unsigned short ModeIdIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short StandTableIndex , RefreshRateTableIndex ;
SiS_Pr - > SiS_CRT1Mode = ModeNo ;
StandTableIndex = SiS_GetModePtr ( SiS_Pr , ModeNo , ModeIdIndex ) ;
if ( SiS_Pr - > SiS_SetFlag & LowModeTests ) {
if ( SiS_Pr - > SiS_VBInfo & ( SetSimuScanMode | SwitchCRT2 ) ) {
SiS_DisableBridge ( SiS_Pr ) ;
}
}
SiS_ResetSegmentRegisters ( SiS_Pr ) ;
SiS_SetSeqRegs ( SiS_Pr , StandTableIndex ) ;
SiS_SetMiscRegs ( SiS_Pr , StandTableIndex ) ;
SiS_SetCRTCRegs ( SiS_Pr , StandTableIndex ) ;
SiS_SetATTRegs ( SiS_Pr , StandTableIndex ) ;
SiS_SetGRCRegs ( SiS_Pr , StandTableIndex ) ;
SiS_ClearExt1Regs ( SiS_Pr , ModeNo ) ;
SiS_ResetCRT1VCLK ( SiS_Pr ) ;
SiS_Pr - > SiS_SelectCRT2Rate = 0 ;
SiS_Pr - > SiS_SetFlag & = ( ~ ProgrammingCRT2 ) ;
# ifdef SIS_XORG_XF86
xf86DrvMsgVerb ( 0 , X_PROBED , 4 , " (init: VBType=0x%04x, VBInfo=0x%04x) \n " ,
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_VBType , SiS_Pr - > SiS_VBInfo ) ;
# endif
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBInfo & SetSimuScanMode ) {
if ( SiS_Pr - > SiS_VBInfo & SetInSlaveMode ) {
SiS_Pr - > SiS_SetFlag | = ProgrammingCRT2 ;
}
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) {
SiS_Pr - > SiS_SetFlag | = ProgrammingCRT2 ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
RefreshRateTableIndex = SiS_GetRatePtr ( SiS_Pr , ModeNo , ModeIdIndex ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( ! ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) ) {
SiS_Pr - > SiS_SetFlag & = ~ ProgrammingCRT2 ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( RefreshRateTableIndex ! = 0xFFFF ) {
SiS_SetCRT1Sync ( SiS_Pr , RefreshRateTableIndex ) ;
SiS_SetCRT1CRTC ( SiS_Pr , ModeNo , ModeIdIndex , RefreshRateTableIndex ) ;
SiS_SetCRT1Offset ( SiS_Pr , ModeNo , ModeIdIndex , RefreshRateTableIndex ) ;
SiS_SetCRT1VCLK ( SiS_Pr , ModeNo , ModeIdIndex , RefreshRateTableIndex ) ;
}
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
switch ( SiS_Pr - > ChipType ) {
2005-04-17 02:20:36 +04:00
# ifdef SIS300
2005-09-10 00:04:45 +04:00
case SIS_300 :
SiS_SetCRT1FIFO_300 ( SiS_Pr , ModeNo , RefreshRateTableIndex ) ;
break ;
case SIS_540 :
case SIS_630 :
case SIS_730 :
SiS_SetCRT1FIFO_630 ( SiS_Pr , ModeNo , RefreshRateTableIndex ) ;
break ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
default :
2005-04-17 02:20:36 +04:00
# ifdef SIS315H
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType = = XGI_20 ) {
unsigned char sr2b = 0 , sr2c = 0 ;
switch ( ModeNo ) {
case 0x00 :
case 0x01 : sr2b = 0x4e ; sr2c = 0xe9 ; break ;
case 0x04 :
case 0x05 :
case 0x0d : sr2b = 0x1b ; sr2c = 0xe3 ; break ;
}
if ( sr2b ) {
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2b , sr2b ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x2c , sr2c ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3c2 , ( SiS_GetRegByte ( SiS_Pr - > SiS_P3cc ) | 0x0c ) ) ;
}
}
SiS_SetCRT1FIFO_310 ( SiS_Pr , ModeNo , ModeIdIndex ) ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
break ;
}
SiS_SetCRT1ModeRegs ( SiS_Pr , ModeNo , ModeIdIndex , RefreshRateTableIndex ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
# ifdef SIS315H
if ( SiS_Pr - > ChipType = = XGI_40 ) {
SiS_SetupDualChip ( SiS_Pr ) ;
}
# endif
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_LoadDAC ( SiS_Pr , ModeNo , ModeIdIndex ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
if ( SiS_Pr - > SiS_flag_clearbuffer ) {
SiS_ClearBuffer ( SiS_Pr , ModeNo ) ;
}
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
if ( ! ( SiS_Pr - > SiS_VBInfo & ( SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA ) ) ) {
SiS_WaitRetrace1 ( SiS_Pr ) ;
SiS_DisplayOn ( SiS_Pr ) ;
}
2005-04-17 02:20:36 +04:00
}
/*********************************************/
/* HELPER: VIDEO BRIDGE PROG CLK */
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_InitVB ( struct SiS_Private * SiS_Pr )
{
unsigned char * ROMAddr = SiS_Pr - > VirtualRomBase ;
SiS_Pr - > Init_P4_0E = 0 ;
if ( SiS_Pr - > SiS_ROMNew ) {
SiS_Pr - > Init_P4_0E = ROMAddr [ 0x82 ] ;
} else if ( SiS_Pr - > ChipType > = XGI_40 ) {
if ( SiS_Pr - > SiS_XGIROM ) {
SiS_Pr - > Init_P4_0E = ROMAddr [ 0x80 ] ;
}
}
}
static void
SiS_ResetVB ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
# ifdef SIS315H
unsigned char * ROMAddr = SiS_Pr - > VirtualRomBase ;
unsigned short temp ;
2005-04-17 02:20:36 +04:00
/* VB programming clock */
if ( SiS_Pr - > SiS_UseROM ) {
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType < SIS_330 ) {
temp = ROMAddr [ VB310Data_1_2_Offset ] | 0x40 ;
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > SiS_ROMNew ) temp = ROMAddr [ 0x80 ] | 0x40 ;
SiS_SetReg ( SiS_Pr - > SiS_Part1Port , 0x02 , temp ) ;
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType > = SIS_661 & & SiS_Pr - > ChipType < XGI_20 ) {
temp = ROMAddr [ 0x7e ] | 0x40 ;
if ( SiS_Pr - > SiS_ROMNew ) temp = ROMAddr [ 0x80 ] | 0x40 ;
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_Part1Port , 0x02 , temp ) ;
}
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType > = XGI_40 ) {
temp = 0x40 ;
if ( SiS_Pr - > SiS_XGIROM ) temp | = ROMAddr [ 0x7e ] ;
/* Can we do this on any chipset? */
SiS_SetReg ( SiS_Pr - > SiS_Part1Port , 0x02 , temp ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
# endif
2005-04-17 02:20:36 +04:00
}
/*********************************************/
2005-09-10 00:04:45 +04:00
/* HELPER: SET VIDEO/CAPTURE REGISTERS */
2005-04-17 02:20:36 +04:00
/*********************************************/
static void
2005-09-10 00:04:45 +04:00
SiS_StrangeStuff ( struct SiS_Private * SiS_Pr )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
/* SiS65x and XGI set up some sort of "lock mode" for text
* which locks CRT2 in some way to CRT1 timing . Disable
* this here .
*/
# ifdef SIS315H
if ( ( IS_SIS651 ) | | ( IS_SISM650 ) | |
SiS_Pr - > ChipType = = SIS_340 | |
SiS_Pr - > ChipType = = XGI_40 ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_VidCapt , 0x3f , 0x00 ) ; /* Fiddle with capture regs */
SiS_SetReg ( SiS_Pr - > SiS_VidCapt , 0x00 , 0x00 ) ;
SiS_SetReg ( SiS_Pr - > SiS_VidPlay , 0x00 , 0x86 ) ; /* (BIOS does NOT unlock) */
SiS_SetRegAND ( SiS_Pr - > SiS_VidPlay , 0x30 , 0xfe ) ; /* Fiddle with video regs */
SiS_SetRegAND ( SiS_Pr - > SiS_VidPlay , 0x3f , 0xef ) ;
}
/* !!! This does not support modes < 0x13 !!! */
2005-09-10 00:04:45 +04:00
# endif
}
/*********************************************/
/* HELPER: SET AGP TIMING FOR SiS760 */
/*********************************************/
static void
SiS_Handle760 ( struct SiS_Private * SiS_Pr )
{
# ifdef SIS315H
unsigned int somebase ;
unsigned char temp1 , temp2 , temp3 ;
if ( ( SiS_Pr - > ChipType ! = SIS_760 ) | |
( ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x5c ) & 0xf8 ) ! = 0x80 ) | |
( ! ( SiS_Pr - > SiS_SysFlags & SF_760LFB ) ) | |
( ! ( SiS_Pr - > SiS_SysFlags & SF_760UMA ) ) )
return ;
# ifdef SIS_LINUX_KERNEL
somebase = sisfb_read_mio_pci_word ( SiS_Pr , 0x74 ) ;
# else
somebase = pciReadWord ( 0x00001000 , 0x74 ) ;
# endif
somebase & = 0xffff ;
if ( somebase = = 0 ) return ;
temp3 = SiS_GetRegByte ( ( somebase + 0x85 ) ) & 0xb7 ;
if ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x31 ) & 0x40 ) {
temp1 = 0x21 ;
temp2 = 0x03 ;
temp3 | = 0x08 ;
} else {
temp1 = 0x25 ;
temp2 = 0x0b ;
}
# ifdef SIS_LINUX_KERNEL
sisfb_write_nbridge_pci_byte ( SiS_Pr , 0x7e , temp1 ) ;
sisfb_write_nbridge_pci_byte ( SiS_Pr , 0x8d , temp2 ) ;
# else
pciWriteByte ( 0x00000000 , 0x7e , temp1 ) ;
pciWriteByte ( 0x00000000 , 0x8d , temp2 ) ;
# endif
SiS_SetRegByte ( ( somebase + 0x85 ) , temp3 ) ;
# endif
2005-04-17 02:20:36 +04:00
}
/*********************************************/
2005-09-10 00:04:45 +04:00
/* X.org/XFree86: SET SCREEN PITCH */
2005-04-17 02:20:36 +04:00
/*********************************************/
2005-09-10 00:04:45 +04:00
# ifdef SIS_XORG_XF86
2005-04-17 02:20:36 +04:00
static void
2005-09-10 00:04:45 +04:00
SiS_SetPitchCRT1 ( struct SiS_Private * SiS_Pr , ScrnInfoPtr pScrn )
2005-04-17 02:20:36 +04:00
{
SISPtr pSiS = SISPTR ( pScrn ) ;
2005-09-10 00:04:45 +04:00
unsigned short HDisplay = pSiS - > scrnPitch > > 3 ;
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x13 , ( HDisplay & 0xFF ) ) ;
2005-09-10 00:04:45 +04:00
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0E , 0xF0 , ( HDisplay > > 8 ) ) ;
2005-04-17 02:20:36 +04:00
}
static void
2005-09-10 00:04:45 +04:00
SiS_SetPitchCRT2 ( struct SiS_Private * SiS_Pr , ScrnInfoPtr pScrn )
2005-04-17 02:20:36 +04:00
{
SISPtr pSiS = SISPTR ( pScrn ) ;
2005-09-10 00:04:45 +04:00
unsigned short HDisplay = pSiS - > scrnPitch2 > > 3 ;
2005-04-17 02:20:36 +04:00
/* Unlock CRT2 */
if ( pSiS - > VGAEngine = = SIS_315_VGA )
2005-09-10 00:04:45 +04:00
SiS_SetRegOR ( SiS_Pr - > SiS_Part1Port , 0x2F , 0x01 ) ;
2005-04-17 02:20:36 +04:00
else
2005-09-10 00:04:45 +04:00
SiS_SetRegOR ( SiS_Pr - > SiS_Part1Port , 0x24 , 0x01 ) ;
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_Part1Port , 0x07 , ( HDisplay & 0xFF ) ) ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_Part1Port , 0x09 , 0xF0 , ( HDisplay > > 8 ) ) ;
}
static void
2005-09-10 00:04:45 +04:00
SiS_SetPitch ( struct SiS_Private * SiS_Pr , ScrnInfoPtr pScrn )
2005-04-17 02:20:36 +04:00
{
SISPtr pSiS = SISPTR ( pScrn ) ;
2007-02-12 11:55:06 +03:00
bool isslavemode = false ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( ( pSiS - > VBFlags2 & VB2_VIDEOBRIDGE ) & &
2005-04-17 02:20:36 +04:00
( ( ( pSiS - > VGAEngine = = SIS_300_VGA ) & &
2005-09-10 00:04:45 +04:00
( SiS_GetReg ( SiS_Pr - > SiS_Part1Port , 0x00 ) & 0xa0 ) = = 0x20 ) | |
( ( pSiS - > VGAEngine = = SIS_315_VGA ) & &
2005-04-17 02:20:36 +04:00
( SiS_GetReg ( SiS_Pr - > SiS_Part1Port , 0x00 ) & 0x50 ) = = 0x10 ) ) ) {
2007-02-12 11:55:06 +03:00
isslavemode = true ;
2005-04-17 02:20:36 +04:00
}
/* We need to set pitch for CRT1 if bridge is in slave mode, too */
if ( ( pSiS - > VBFlags & DISPTYPE_DISP1 ) | | ( isslavemode ) ) {
SiS_SetPitchCRT1 ( SiS_Pr , pScrn ) ;
}
/* We must not set the pitch for CRT2 if bridge is in slave mode */
if ( ( pSiS - > VBFlags & DISPTYPE_DISP2 ) & & ( ! isslavemode ) ) {
SiS_SetPitchCRT2 ( SiS_Pr , pScrn ) ;
}
}
# endif
/*********************************************/
/* SiSSetMode() */
/*********************************************/
2005-09-10 00:04:45 +04:00
# ifdef SIS_XORG_XF86
2005-04-17 02:20:36 +04:00
/* We need pScrn for setting the pitch correctly */
2007-02-12 11:55:06 +03:00
bool
SiSSetMode ( struct SiS_Private * SiS_Pr , ScrnInfoPtr pScrn , unsigned short ModeNo , bool dosetpitch )
2005-04-17 02:20:36 +04:00
# else
2007-02-12 11:55:06 +03:00
bool
2005-09-10 00:04:45 +04:00
SiSSetMode ( struct SiS_Private * SiS_Pr , unsigned short ModeNo )
2005-04-17 02:20:36 +04:00
# endif
{
2005-09-10 00:04:45 +04:00
SISIOADDRESS BaseAddr = SiS_Pr - > IOAddress ;
unsigned short RealModeNo , ModeIdIndex ;
unsigned char backupreg = 0 ;
# ifdef SIS_LINUX_KERNEL
unsigned short KeepLockReg ;
2005-04-17 02:20:36 +04:00
2007-02-12 11:55:06 +03:00
SiS_Pr - > UseCustomMode = false ;
SiS_Pr - > CRT1UsesCustomMode = false ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_flag_clearbuffer = 0 ;
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > UseCustomMode ) {
ModeNo = 0xfe ;
2005-09-10 00:04:45 +04:00
} else {
# ifdef SIS_LINUX_KERNEL
if ( ! ( ModeNo & 0x80 ) ) SiS_Pr - > SiS_flag_clearbuffer = 1 ;
# endif
ModeNo & = 0x7f ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
/* Don't use FSTN mode for CRT1 */
RealModeNo = ModeNo ;
if ( ModeNo = = 0x5b ) ModeNo = 0x56 ;
SiSInitPtr ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiSRegInit ( SiS_Pr , BaseAddr ) ;
2005-09-10 00:04:45 +04:00
SiS_GetSysFlags ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_Pr - > SiS_VGAINFO = 0x11 ;
# if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__))
2005-04-17 02:20:36 +04:00
if ( pScrn ) SiS_Pr - > SiS_VGAINFO = SiS_GetSetBIOSScratch ( pScrn , 0x489 , 0xff ) ;
# endif
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
2005-04-17 02:20:36 +04:00
KeepLockReg = SiS_GetReg ( SiS_Pr - > SiS_P3c4 , 0x05 ) ;
# endif
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x05 , 0x86 ) ;
2005-09-10 00:04:45 +04:00
SiSInitPCIetc ( SiS_Pr ) ;
SiSSetLVDSetc ( SiS_Pr ) ;
SiSDetermineROMUsage ( SiS_Pr ) ;
SiS_UnLockCRT2 ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
if ( ! SiS_Pr - > UseCustomMode ) {
2007-02-12 11:55:06 +03:00
if ( ! ( SiS_SearchModeID ( SiS_Pr , & ModeNo , & ModeIdIndex ) ) ) return false ;
2005-04-17 02:20:36 +04:00
} else {
ModeIdIndex = 0 ;
}
2005-09-10 00:04:45 +04:00
SiS_GetVBType ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
/* Init/restore some VB registers */
2005-09-10 00:04:45 +04:00
SiS_InitVB ( SiS_Pr ) ;
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > ChipType > = SIS_315H ) {
SiS_ResetVB ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x32 , 0x10 ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_Part2Port , 0x00 , 0x0c ) ;
backupreg = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x38 ) ;
} else {
backupreg = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x35 ) ;
}
}
/* Get VB information (connectors, connected devices) */
2005-09-10 00:04:45 +04:00
SiS_GetVBInfo ( SiS_Pr , ModeNo , ModeIdIndex , ( SiS_Pr - > UseCustomMode ) ? 0 : 1 ) ;
SiS_SetYPbPr ( SiS_Pr ) ;
SiS_SetTVMode ( SiS_Pr , ModeNo , ModeIdIndex ) ;
SiS_GetLCDResInfo ( SiS_Pr , ModeNo , ModeIdIndex ) ;
SiS_SetLowModeTest ( SiS_Pr , ModeNo ) ;
# ifdef SIS_LINUX_KERNEL
/* Check memory size (kernel framebuffer driver only) */
if ( ! SiS_CheckMemorySize ( SiS_Pr , ModeNo , ModeIdIndex ) ) {
2007-02-12 11:55:06 +03:00
return false ;
2005-09-10 00:04:45 +04:00
}
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
SiS_OpenCRTC ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > UseCustomMode ) {
2007-02-12 11:55:06 +03:00
SiS_Pr - > CRT1UsesCustomMode = true ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > CSRClock_CRT1 = SiS_Pr - > CSRClock ;
SiS_Pr - > CModeFlag_CRT1 = SiS_Pr - > CModeFlag ;
} else {
2007-02-12 11:55:06 +03:00
SiS_Pr - > CRT1UsesCustomMode = false ;
2005-04-17 02:20:36 +04:00
}
/* Set mode on CRT1 */
if ( ( SiS_Pr - > SiS_VBInfo & ( SetSimuScanMode | SetCRT2ToLCDA ) ) | |
( ! ( SiS_Pr - > SiS_VBInfo & SwitchCRT2 ) ) ) {
2005-09-10 00:04:45 +04:00
SiS_SetCRT1Group ( SiS_Pr , ModeNo , ModeIdIndex ) ;
2005-04-17 02:20:36 +04:00
}
/* Set mode on CRT2 */
if ( SiS_Pr - > SiS_VBInfo & ( SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA ) ) {
if ( ( SiS_Pr - > SiS_VBType & VB_SISVB ) | |
2005-09-10 00:04:45 +04:00
( SiS_Pr - > SiS_IF_DEF_LVDS = = 1 ) | |
( SiS_Pr - > SiS_IF_DEF_CH70xx ! = 0 ) | |
( SiS_Pr - > SiS_IF_DEF_TRUMPION ! = 0 ) ) {
SiS_SetCRT2Group ( SiS_Pr , RealModeNo ) ;
2005-04-17 02:20:36 +04:00
}
}
SiS_HandleCRT1 ( SiS_Pr ) ;
2005-09-10 00:04:45 +04:00
SiS_StrangeStuff ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiS_DisplayOn ( SiS_Pr ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3c6 , 0xFF ) ;
2005-09-10 00:04:45 +04:00
# ifdef SIS315H
if ( SiS_Pr - > ChipType > = SIS_315H ) {
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > SiS_IF_DEF_LVDS = = 1 ) {
2005-09-10 00:04:45 +04:00
if ( ! ( SiS_IsDualEdge ( SiS_Pr ) ) ) {
2005-04-17 02:20:36 +04:00
SiS_SetRegAND ( SiS_Pr - > SiS_Part1Port , 0x13 , 0xfb ) ;
}
}
}
2005-09-10 00:04:45 +04:00
# endif
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > ChipType > = SIS_315H ) {
# ifdef SIS315H
if ( ! SiS_Pr - > SiS_ROMNew ) {
if ( SiS_IsVAMode ( SiS_Pr ) ) {
2005-04-17 02:20:36 +04:00
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x35 , 0x01 ) ;
} else {
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x35 , 0xFE ) ;
}
}
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x38 , backupreg ) ;
if ( ( IS_SIS650 ) & & ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x30 ) & 0xfc ) ) {
if ( ( ModeNo = = 0x03 ) | | ( ModeNo = = 0x10 ) ) {
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x51 , 0x80 ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x56 , 0x08 ) ;
2005-09-10 00:04:45 +04:00
}
2005-04-17 02:20:36 +04:00
}
if ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x30 ) & SetCRT2ToLCD ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x38 , 0xfc ) ;
}
2005-09-10 00:04:45 +04:00
# endif
} else if ( ( SiS_Pr - > ChipType = = SIS_630 ) | |
( SiS_Pr - > ChipType = = SIS_730 ) ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x35 , backupreg ) ;
2005-04-17 02:20:36 +04:00
}
}
2005-09-10 00:04:45 +04:00
# ifdef SIS_XORG_XF86
2005-04-17 02:20:36 +04:00
if ( pScrn ) {
/* SetPitch: Adapt to virtual size & position */
if ( ( ModeNo > 0x13 ) & & ( dosetpitch ) ) {
2005-09-10 00:04:45 +04:00
SiS_SetPitch ( SiS_Pr , pScrn ) ;
2005-04-17 02:20:36 +04:00
}
/* Backup/Set ModeNo in BIOS scratch area */
SiS_GetSetModeID ( pScrn , ModeNo ) ;
}
# endif
2005-09-10 00:04:45 +04:00
SiS_CloseCRTC ( SiS_Pr ) ;
SiS_Handle760 ( SiS_Pr ) ;
# ifdef SIS_LINUX_KERNEL
/* We never lock registers in XF86 */
if ( KeepLockReg ! = 0xA1 ) SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x05 , 0x00 ) ;
2005-04-17 02:20:36 +04:00
# endif
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
2005-09-10 00:04:45 +04:00
/* X.org/XFree86: SiSBIOSSetMode() */
2005-04-17 02:20:36 +04:00
/* for non-Dual-Head mode */
/*********************************************/
2005-09-10 00:04:45 +04:00
# ifdef SIS_XORG_XF86
2007-02-12 11:55:06 +03:00
bool
2005-09-10 00:04:45 +04:00
SiSBIOSSetMode ( struct SiS_Private * SiS_Pr , ScrnInfoPtr pScrn ,
2007-02-12 11:55:06 +03:00
DisplayModePtr mode , bool IsCustom )
2005-04-17 02:20:36 +04:00
{
SISPtr pSiS = SISPTR ( pScrn ) ;
2005-09-10 00:04:45 +04:00
unsigned short ModeNo = 0 ;
2005-04-17 02:20:36 +04:00
2007-02-12 11:55:06 +03:00
SiS_Pr - > UseCustomMode = false ;
2005-04-17 02:20:36 +04:00
if ( ( IsCustom ) & & ( SiS_CheckBuildCustomMode ( pScrn , mode , pSiS - > VBFlags ) ) ) {
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 , " Setting custom mode %dx%d \n " ,
2005-09-10 00:04:45 +04:00
SiS_Pr - > CHDisplay ,
2005-04-17 02:20:36 +04:00
( mode - > Flags & V_INTERLACE ? SiS_Pr - > CVDisplay * 2 :
( mode - > Flags & V_DBLSCAN ? SiS_Pr - > CVDisplay / 2 :
SiS_Pr - > CVDisplay ) ) ) ;
} else {
/* Don't need vbflags here; checks done earlier */
2005-09-10 00:04:45 +04:00
ModeNo = SiS_GetModeNumber ( pScrn , mode , pSiS - > VBFlags ) ;
2007-02-12 11:55:06 +03:00
if ( ! ModeNo ) return false ;
2005-04-17 02:20:36 +04:00
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 , " Setting standard mode 0x%x \n " , ModeNo ) ;
}
2007-02-12 11:55:06 +03:00
return ( SiSSetMode ( SiS_Pr , pScrn , ModeNo , true ) ) ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
2005-09-10 00:04:45 +04:00
/* X.org/XFree86: SiSBIOSSetModeCRT2() */
2005-04-17 02:20:36 +04:00
/* for Dual-Head modes */
/*********************************************/
2005-09-10 00:04:45 +04:00
2007-02-12 11:55:06 +03:00
bool
2005-09-10 00:04:45 +04:00
SiSBIOSSetModeCRT2 ( struct SiS_Private * SiS_Pr , ScrnInfoPtr pScrn ,
2007-02-12 11:55:06 +03:00
DisplayModePtr mode , bool IsCustom )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
SISIOADDRESS BaseAddr = SiS_Pr - > IOAddress ;
SISPtr pSiS = SISPTR ( pScrn ) ;
2005-04-17 02:20:36 +04:00
# ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS - > entityPrivate ;
# endif
2005-09-10 00:04:45 +04:00
unsigned short ModeIdIndex ;
unsigned short ModeNo = 0 ;
unsigned char backupreg = 0 ;
2005-04-17 02:20:36 +04:00
2007-02-12 11:55:06 +03:00
SiS_Pr - > UseCustomMode = false ;
2005-04-17 02:20:36 +04:00
/* Remember: Custom modes for CRT2 are ONLY supported
* - ) on the 30 x / B / C , and
* - ) if CRT2 is LCD or VGA , or CRT1 is LCDA
*/
if ( ( IsCustom ) & & ( SiS_CheckBuildCustomMode ( pScrn , mode , pSiS - > VBFlags ) ) ) {
ModeNo = 0xfe ;
} else {
2005-09-10 00:04:45 +04:00
ModeNo = SiS_GetModeNumber ( pScrn , mode , pSiS - > VBFlags ) ;
2007-02-12 11:55:06 +03:00
if ( ! ModeNo ) return false ;
2005-04-17 02:20:36 +04:00
}
SiSRegInit ( SiS_Pr , BaseAddr ) ;
2005-09-10 00:04:45 +04:00
SiSInitPtr ( SiS_Pr ) ;
SiS_GetSysFlags ( SiS_Pr ) ;
# if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_VGAINFO = SiS_GetSetBIOSScratch ( pScrn , 0x489 , 0xff ) ;
# else
SiS_Pr - > SiS_VGAINFO = 0x11 ;
# endif
2005-09-10 00:04:45 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x05 , 0x86 ) ;
SiSInitPCIetc ( SiS_Pr ) ;
SiSSetLVDSetc ( SiS_Pr ) ;
SiSDetermineROMUsage ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
/* Save mode info so we can set it from within SetMode for CRT1 */
# ifdef SISDUALHEAD
if ( pSiS - > DualHeadMode ) {
pSiSEnt - > CRT2ModeNo = ModeNo ;
pSiSEnt - > CRT2DMode = mode ;
pSiSEnt - > CRT2IsCustom = IsCustom ;
pSiSEnt - > CRT2CR30 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x30 ) ;
pSiSEnt - > CRT2CR31 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x31 ) ;
pSiSEnt - > CRT2CR35 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x35 ) ;
pSiSEnt - > CRT2CR38 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x38 ) ;
#if 0
2005-09-10 00:04:45 +04:00
/* We can't set CRT2 mode before CRT1 mode is set - says who...? */
2005-04-17 02:20:36 +04:00
if ( pSiSEnt - > CRT1ModeNo = = - 1 ) {
2005-09-10 00:04:45 +04:00
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 ,
2005-04-17 02:20:36 +04:00
" Setting CRT2 mode delayed until after setting CRT1 mode \n " ) ;
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
# endif
2007-02-12 11:55:06 +03:00
pSiSEnt - > CRT2ModeSet = true ;
2005-04-17 02:20:36 +04:00
}
# endif
if ( SiS_Pr - > UseCustomMode ) {
2005-09-10 00:04:45 +04:00
unsigned short temptemp = SiS_Pr - > CVDisplay ;
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > CModeFlag & DoubleScanMode ) temptemp > > = 1 ;
else if ( SiS_Pr - > CInfoFlag & InterlaceMode ) temptemp < < = 1 ;
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 ,
" Setting custom mode %dx%d on CRT2 \n " ,
SiS_Pr - > CHDisplay , temptemp ) ;
} else {
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 ,
2005-09-10 00:04:45 +04:00
" Setting standard mode 0x%x on CRT2 \n " , ModeNo ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
SiS_UnLockCRT2 ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
if ( ! SiS_Pr - > UseCustomMode ) {
2007-02-12 11:55:06 +03:00
if ( ! ( SiS_SearchModeID ( SiS_Pr , & ModeNo , & ModeIdIndex ) ) ) return false ;
2005-04-17 02:20:36 +04:00
} else {
ModeIdIndex = 0 ;
}
2005-09-10 00:04:45 +04:00
SiS_GetVBType ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_InitVB ( SiS_Pr ) ;
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > ChipType > = SIS_315H ) {
SiS_ResetVB ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiS_SetRegOR ( SiS_Pr - > SiS_P3c4 , 0x32 , 0x10 ) ;
SiS_SetRegOR ( SiS_Pr - > SiS_Part2Port , 0x00 , 0x0c ) ;
2005-09-10 00:04:45 +04:00
backupreg = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x38 ) ;
2005-04-17 02:20:36 +04:00
} else {
2005-09-10 00:04:45 +04:00
backupreg = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x35 ) ;
2005-04-17 02:20:36 +04:00
}
}
/* Get VB information (connectors, connected devices) */
if ( ! SiS_Pr - > UseCustomMode ) {
2005-09-10 00:04:45 +04:00
SiS_GetVBInfo ( SiS_Pr , ModeNo , ModeIdIndex , 1 ) ;
2005-04-17 02:20:36 +04:00
} else {
/* If this is a custom mode, we don't check the modeflag for CRT2Mode */
2005-09-10 00:04:45 +04:00
SiS_GetVBInfo ( SiS_Pr , ModeNo , ModeIdIndex , 0 ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
SiS_SetYPbPr ( SiS_Pr ) ;
SiS_SetTVMode ( SiS_Pr , ModeNo , ModeIdIndex ) ;
SiS_GetLCDResInfo ( SiS_Pr , ModeNo , ModeIdIndex ) ;
SiS_SetLowModeTest ( SiS_Pr , ModeNo ) ;
SiS_ResetSegmentRegisters ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
/* Set mode on CRT2 */
if ( ( SiS_Pr - > SiS_VBType & VB_SISVB ) | |
( SiS_Pr - > SiS_IF_DEF_LVDS = = 1 ) | |
( SiS_Pr - > SiS_IF_DEF_CH70xx ! = 0 ) | |
( SiS_Pr - > SiS_IF_DEF_TRUMPION ! = 0 ) ) {
2005-09-10 00:04:45 +04:00
SiS_SetCRT2Group ( SiS_Pr , ModeNo ) ;
2005-04-17 02:20:36 +04:00
}
2005-09-10 00:04:45 +04:00
SiS_StrangeStuff ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiS_DisplayOn ( SiS_Pr ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3c6 , 0xFF ) ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType > = SIS_315H ) {
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > SiS_IF_DEF_LVDS = = 1 ) {
2005-09-10 00:04:45 +04:00
if ( ! ( SiS_IsDualEdge ( SiS_Pr ) ) ) {
2005-04-17 02:20:36 +04:00
SiS_SetRegAND ( SiS_Pr - > SiS_Part1Port , 0x13 , 0xfb ) ;
}
}
}
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > ChipType > = SIS_315H ) {
if ( ! SiS_Pr - > SiS_ROMNew ) {
if ( SiS_IsVAMode ( SiS_Pr ) ) {
2005-04-17 02:20:36 +04:00
SiS_SetRegOR ( SiS_Pr - > SiS_P3d4 , 0x35 , 0x01 ) ;
} else {
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x35 , 0xFE ) ;
}
}
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x38 , backupreg ) ;
if ( SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x30 ) & SetCRT2ToLCD ) {
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x38 , 0xfc ) ;
}
2005-09-10 00:04:45 +04:00
} else if ( ( SiS_Pr - > ChipType = = SIS_630 ) | |
( SiS_Pr - > ChipType = = SIS_730 ) ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x35 , backupreg ) ;
}
}
/* SetPitch: Adapt to virtual size & position */
SiS_SetPitchCRT2 ( SiS_Pr , pScrn ) ;
2005-09-10 00:04:45 +04:00
SiS_Handle760 ( SiS_Pr ) ;
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
/*********************************************/
2005-09-10 00:04:45 +04:00
/* X.org/XFree86: SiSBIOSSetModeCRT1() */
2005-04-17 02:20:36 +04:00
/* for Dual-Head modes */
/*********************************************/
2007-02-12 11:55:06 +03:00
bool
2005-09-10 00:04:45 +04:00
SiSBIOSSetModeCRT1 ( struct SiS_Private * SiS_Pr , ScrnInfoPtr pScrn ,
2007-02-12 11:55:06 +03:00
DisplayModePtr mode , bool IsCustom )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
SISIOADDRESS BaseAddr = SiS_Pr - > IOAddress ;
2005-04-17 02:20:36 +04:00
SISPtr pSiS = SISPTR ( pScrn ) ;
2005-09-10 00:04:45 +04:00
unsigned short ModeIdIndex , ModeNo = 0 ;
unsigned char backupreg = 0 ;
2005-04-17 02:20:36 +04:00
# ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS - > entityPrivate ;
2005-09-10 00:04:45 +04:00
unsigned char backupcr30 , backupcr31 , backupcr38 , backupcr35 , backupp40d = 0 ;
2007-02-12 11:55:06 +03:00
bool backupcustom ;
2005-04-17 02:20:36 +04:00
# endif
2007-02-12 11:55:06 +03:00
SiS_Pr - > UseCustomMode = false ;
2005-04-17 02:20:36 +04:00
if ( ( IsCustom ) & & ( SiS_CheckBuildCustomMode ( pScrn , mode , pSiS - > VBFlags ) ) ) {
2005-09-10 00:04:45 +04:00
unsigned short temptemp = SiS_Pr - > CVDisplay ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > CModeFlag & DoubleScanMode ) temptemp > > = 1 ;
else if ( SiS_Pr - > CInfoFlag & InterlaceMode ) temptemp < < = 1 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 ,
2005-04-17 02:20:36 +04:00
" Setting custom mode %dx%d on CRT1 \n " ,
SiS_Pr - > CHDisplay , temptemp ) ;
ModeNo = 0xfe ;
} else {
2005-09-10 00:04:45 +04:00
ModeNo = SiS_GetModeNumber ( pScrn , mode , 0 ) ; /* don't give VBFlags */
2007-02-12 11:55:06 +03:00
if ( ! ModeNo ) return false ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 ,
2005-04-17 02:20:36 +04:00
" Setting standard mode 0x%x on CRT1 \n " , ModeNo ) ;
}
2005-09-10 00:04:45 +04:00
SiSInitPtr ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
SiSRegInit ( SiS_Pr , BaseAddr ) ;
2005-09-10 00:04:45 +04:00
SiS_GetSysFlags ( SiS_Pr ) ;
# if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
2005-04-17 02:20:36 +04:00
SiS_Pr - > SiS_VGAINFO = SiS_GetSetBIOSScratch ( pScrn , 0x489 , 0xff ) ;
# else
SiS_Pr - > SiS_VGAINFO = 0x11 ;
# endif
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , 0x05 , 0x86 ) ;
2005-09-10 00:04:45 +04:00
SiSInitPCIetc ( SiS_Pr ) ;
SiSSetLVDSetc ( SiS_Pr ) ;
SiSDetermineROMUsage ( SiS_Pr ) ;
SiS_UnLockCRT2 ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
if ( ! SiS_Pr - > UseCustomMode ) {
2007-02-12 11:55:06 +03:00
if ( ! ( SiS_SearchModeID ( SiS_Pr , & ModeNo , & ModeIdIndex ) ) ) return false ;
2005-04-17 02:20:36 +04:00
} else {
ModeIdIndex = 0 ;
}
/* Determine VBType */
2005-09-10 00:04:45 +04:00
SiS_GetVBType ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_InitVB ( SiS_Pr ) ;
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > ChipType > = SIS_315H ) {
2005-04-17 02:20:36 +04:00
backupreg = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x38 ) ;
} else {
backupreg = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x35 ) ;
}
}
/* Get VB information (connectors, connected devices) */
/* (We don't care if the current mode is a CRT2 mode) */
2005-09-10 00:04:45 +04:00
SiS_GetVBInfo ( SiS_Pr , ModeNo , ModeIdIndex , 0 ) ;
SiS_SetYPbPr ( SiS_Pr ) ;
SiS_SetTVMode ( SiS_Pr , ModeNo , ModeIdIndex ) ;
SiS_GetLCDResInfo ( SiS_Pr , ModeNo , ModeIdIndex ) ;
SiS_SetLowModeTest ( SiS_Pr , ModeNo ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_OpenCRTC ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
/* Set mode on CRT1 */
2005-09-10 00:04:45 +04:00
SiS_SetCRT1Group ( SiS_Pr , ModeNo , ModeIdIndex ) ;
2005-04-17 02:20:36 +04:00
if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) {
2005-09-10 00:04:45 +04:00
SiS_SetCRT2Group ( SiS_Pr , ModeNo ) ;
2005-04-17 02:20:36 +04:00
}
/* SetPitch: Adapt to virtual size & position */
SiS_SetPitchCRT1 ( SiS_Pr , pScrn ) ;
2005-09-10 00:04:45 +04:00
SiS_HandleCRT1 ( SiS_Pr ) ;
SiS_StrangeStuff ( SiS_Pr ) ;
SiS_CloseCRTC ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
# ifdef SISDUALHEAD
if ( pSiS - > DualHeadMode ) {
pSiSEnt - > CRT1ModeNo = ModeNo ;
pSiSEnt - > CRT1DMode = mode ;
}
# endif
if ( SiS_Pr - > UseCustomMode ) {
2007-02-12 11:55:06 +03:00
SiS_Pr - > CRT1UsesCustomMode = true ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > CSRClock_CRT1 = SiS_Pr - > CSRClock ;
SiS_Pr - > CModeFlag_CRT1 = SiS_Pr - > CModeFlag ;
} else {
2007-02-12 11:55:06 +03:00
SiS_Pr - > CRT1UsesCustomMode = false ;
2005-04-17 02:20:36 +04:00
}
/* Reset CRT2 if changing mode on CRT1 */
# ifdef SISDUALHEAD
if ( pSiS - > DualHeadMode ) {
if ( pSiSEnt - > CRT2ModeNo ! = - 1 ) {
2005-09-10 00:04:45 +04:00
xf86DrvMsgVerb ( pScrn - > scrnIndex , X_INFO , 3 ,
2005-04-17 02:20:36 +04:00
" (Re-)Setting mode for CRT2 \n " ) ;
backupcustom = SiS_Pr - > UseCustomMode ;
backupcr30 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x30 ) ;
backupcr31 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x31 ) ;
backupcr35 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x35 ) ;
backupcr38 = SiS_GetReg ( SiS_Pr - > SiS_P3d4 , 0x38 ) ;
if ( SiS_Pr - > SiS_VBType & VB_SISVB ) {
/* Backup LUT-enable */
if ( pSiSEnt - > CRT2ModeSet ) {
backupp40d = SiS_GetReg ( SiS_Pr - > SiS_Part4Port , 0x0d ) & 0x08 ;
}
}
if ( SiS_Pr - > SiS_VBInfo & SetCRT2ToLCDA ) {
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x30 , pSiSEnt - > CRT2CR30 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x31 , pSiSEnt - > CRT2CR31 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x35 , pSiSEnt - > CRT2CR35 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x38 , pSiSEnt - > CRT2CR38 ) ;
}
2005-09-10 00:04:45 +04:00
SiSBIOSSetModeCRT2 ( SiS_Pr , pSiSEnt - > pScrn_1 ,
2005-04-17 02:20:36 +04:00
pSiSEnt - > CRT2DMode , pSiSEnt - > CRT2IsCustom ) ;
2005-09-10 00:04:45 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x30 , backupcr30 ) ;
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x31 , backupcr31 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x35 , backupcr35 ) ;
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x38 , backupcr38 ) ;
if ( SiS_Pr - > SiS_VBType & VB_SISVB ) {
SiS_SetRegANDOR ( SiS_Pr - > SiS_Part4Port , 0x0d , ~ 0x08 , backupp40d ) ;
}
SiS_Pr - > UseCustomMode = backupcustom ;
}
}
# endif
/* Warning: From here, the custom mode entries in SiS_Pr are
* possibly overwritten
*/
SiS_DisplayOn ( SiS_Pr ) ;
SiS_SetRegByte ( SiS_Pr - > SiS_P3c6 , 0xFF ) ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > SiS_VBType & VB_SIS30xBLV ) {
if ( SiS_Pr - > ChipType > = SIS_315H ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x38 , backupreg ) ;
2005-09-10 00:04:45 +04:00
} else if ( ( SiS_Pr - > ChipType = = SIS_630 ) | |
( SiS_Pr - > ChipType = = SIS_730 ) ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , 0x35 , backupreg ) ;
}
}
2005-09-10 00:04:45 +04:00
SiS_Handle760 ( SiS_Pr ) ;
2005-04-17 02:20:36 +04:00
/* Backup/Set ModeNo in BIOS scratch area */
SiS_GetSetModeID ( pScrn , ModeNo ) ;
2007-02-12 11:55:06 +03:00
return true ;
2005-04-17 02:20:36 +04:00
}
# endif /* Linux_XF86 */
# ifndef GETBITSTR
# define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
# define GENMASK(mask) BITMASK(1?mask,0?mask)
# define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask))
# define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
# endif
2005-09-10 00:04:45 +04:00
void
SiS_CalcCRRegisters ( struct SiS_Private * SiS_Pr , int depth )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
int x = 1 ; /* Fix sync */
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 0 ] = ( ( SiS_Pr - > CHTotal > > 3 ) - 5 ) & 0xff ; /* CR0 */
SiS_Pr - > CCRT1CRTC [ 1 ] = ( SiS_Pr - > CHDisplay > > 3 ) - 1 ; /* CR1 */
SiS_Pr - > CCRT1CRTC [ 2 ] = ( SiS_Pr - > CHBlankStart > > 3 ) - 1 ; /* CR2 */
SiS_Pr - > CCRT1CRTC [ 3 ] = ( ( ( SiS_Pr - > CHBlankEnd > > 3 ) - 1 ) & 0x1F ) | 0x80 ; /* CR3 */
SiS_Pr - > CCRT1CRTC [ 4 ] = ( SiS_Pr - > CHSyncStart > > 3 ) + 3 ; /* CR4 */
SiS_Pr - > CCRT1CRTC [ 5 ] = ( ( ( ( SiS_Pr - > CHBlankEnd > > 3 ) - 1 ) & 0x20 ) < < 2 ) | /* CR5 */
2005-09-10 00:04:45 +04:00
( ( ( SiS_Pr - > CHSyncEnd > > 3 ) + 3 ) & 0x1F ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
SiS_Pr - > CCRT1CRTC [ 6 ] = ( SiS_Pr - > CVTotal - 2 ) & 0xFF ; /* CR6 */
SiS_Pr - > CCRT1CRTC [ 7 ] = ( ( ( SiS_Pr - > CVTotal - 2 ) & 0x100 ) > > 8 ) /* CR7 */
| ( ( ( SiS_Pr - > CVDisplay - 1 ) & 0x100 ) > > 7 )
| ( ( ( SiS_Pr - > CVSyncStart - x ) & 0x100 ) > > 6 )
| ( ( ( SiS_Pr - > CVBlankStart - 1 ) & 0x100 ) > > 5 )
2005-04-17 02:20:36 +04:00
| 0x10
2005-09-10 00:04:45 +04:00
| ( ( ( SiS_Pr - > CVTotal - 2 ) & 0x200 ) > > 4 )
| ( ( ( SiS_Pr - > CVDisplay - 1 ) & 0x200 ) > > 3 )
| ( ( ( SiS_Pr - > CVSyncStart - x ) & 0x200 ) > > 2 ) ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 16 ] = ( ( ( ( SiS_Pr - > CVBlankStart - 1 ) & 0x200 ) > > 4 ) > > 5 ) ; /* CR9 */
if ( depth ! = 8 ) {
if ( SiS_Pr - > CHDisplay > = 1600 ) SiS_Pr - > CCRT1CRTC [ 16 ] | = 0x60 ; /* SRE */
else if ( SiS_Pr - > CHDisplay > = 640 ) SiS_Pr - > CCRT1CRTC [ 16 ] | = 0x40 ;
}
2005-09-10 00:04:45 +04:00
SiS_Pr - > CCRT1CRTC [ 8 ] = ( SiS_Pr - > CVSyncStart - x ) & 0xFF ; /* CR10 */
SiS_Pr - > CCRT1CRTC [ 9 ] = ( ( SiS_Pr - > CVSyncEnd - x ) & 0x0F ) | 0x80 ; /* CR11 */
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 10 ] = ( SiS_Pr - > CVDisplay - 1 ) & 0xFF ; /* CR12 */
SiS_Pr - > CCRT1CRTC [ 11 ] = ( SiS_Pr - > CVBlankStart - 1 ) & 0xFF ; /* CR15 */
SiS_Pr - > CCRT1CRTC [ 12 ] = ( SiS_Pr - > CVBlankEnd - 1 ) & 0xFF ; /* CR16 */
SiS_Pr - > CCRT1CRTC [ 13 ] = /* SRA */
2005-09-10 00:04:45 +04:00
GETBITSTR ( ( SiS_Pr - > CVTotal - 2 ) , 10 : 10 , 0 : 0 ) |
GETBITSTR ( ( SiS_Pr - > CVDisplay - 1 ) , 10 : 10 , 1 : 1 ) |
GETBITSTR ( ( SiS_Pr - > CVBlankStart - 1 ) , 10 : 10 , 2 : 2 ) |
GETBITSTR ( ( SiS_Pr - > CVSyncStart - x ) , 10 : 10 , 3 : 3 ) |
GETBITSTR ( ( SiS_Pr - > CVBlankEnd - 1 ) , 8 : 8 , 4 : 4 ) |
GETBITSTR ( ( SiS_Pr - > CVSyncEnd ) , 4 : 4 , 5 : 5 ) ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 14 ] = /* SRB */
2005-09-10 00:04:45 +04:00
GETBITSTR ( ( SiS_Pr - > CHTotal > > 3 ) - 5 , 9 : 8 , 1 : 0 ) |
GETBITSTR ( ( SiS_Pr - > CHDisplay > > 3 ) - 1 , 9 : 8 , 3 : 2 ) |
GETBITSTR ( ( SiS_Pr - > CHBlankStart > > 3 ) - 1 , 9 : 8 , 5 : 4 ) |
GETBITSTR ( ( SiS_Pr - > CHSyncStart > > 3 ) + 3 , 9 : 8 , 7 : 6 ) ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 15 ] = /* SRC */
2005-09-10 00:04:45 +04:00
GETBITSTR ( ( SiS_Pr - > CHBlankEnd > > 3 ) - 1 , 7 : 6 , 1 : 0 ) |
GETBITSTR ( ( SiS_Pr - > CHSyncEnd > > 3 ) + 3 , 5 : 5 , 2 : 2 ) ;
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_CalcLCDACRT1Timing ( struct SiS_Private * SiS_Pr , unsigned short ModeNo ,
unsigned short ModeIdIndex )
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short modeflag , tempax , tempbx = 0 , remaining = 0 ;
unsigned short VGAHDE = SiS_Pr - > SiS_VGAHDE ;
int i , j ;
2005-04-17 02:20:36 +04:00
/* 1:1 data: use data set by setcrt1crtc() */
if ( SiS_Pr - > SiS_LCDInfo & LCDPass11 ) return ;
2005-09-10 00:04:45 +04:00
modeflag = SiS_GetModeFlag ( SiS_Pr , ModeNo , ModeIdIndex ) ;
2005-04-17 02:20:36 +04:00
if ( modeflag & HalfDCLK ) VGAHDE > > = 1 ;
SiS_Pr - > CHDisplay = VGAHDE ;
SiS_Pr - > CHBlankStart = VGAHDE ;
SiS_Pr - > CVDisplay = SiS_Pr - > SiS_VGAVDE ;
SiS_Pr - > CVBlankStart = SiS_Pr - > SiS_VGAVDE ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType < SIS_315H ) {
# ifdef SIS300
tempbx = SiS_Pr - > SiS_VGAHT ;
if ( SiS_Pr - > SiS_LCDInfo & DontExpandLCD ) {
tempbx = SiS_Pr - > PanelHT ;
}
if ( modeflag & HalfDCLK ) tempbx > > = 1 ;
remaining = tempbx % 8 ;
# endif
} else {
# ifdef SIS315H
/* OK for LCDA, LVDS */
tempbx = SiS_Pr - > PanelHT - SiS_Pr - > PanelXRes ;
tempax = SiS_Pr - > SiS_VGAHDE ; /* not /2 ! */
if ( SiS_Pr - > SiS_LCDInfo & DontExpandLCD ) {
tempax = SiS_Pr - > PanelXRes ;
}
tempbx + = tempax ;
if ( modeflag & HalfDCLK ) tempbx - = VGAHDE ;
# endif
2005-04-17 02:20:36 +04:00
}
SiS_Pr - > CHTotal = SiS_Pr - > CHBlankEnd = tempbx ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType < SIS_315H ) {
# ifdef SIS300
if ( SiS_Pr - > SiS_VGAHDE = = SiS_Pr - > PanelXRes ) {
SiS_Pr - > CHSyncStart = SiS_Pr - > SiS_VGAHDE + ( ( SiS_Pr - > PanelHRS + 1 ) & ~ 1 ) ;
SiS_Pr - > CHSyncEnd = SiS_Pr - > CHSyncStart + SiS_Pr - > PanelHRE ;
if ( modeflag & HalfDCLK ) {
SiS_Pr - > CHSyncStart > > = 1 ;
SiS_Pr - > CHSyncEnd > > = 1 ;
}
} else if ( SiS_Pr - > SiS_LCDInfo & DontExpandLCD ) {
tempax = ( SiS_Pr - > PanelXRes - SiS_Pr - > SiS_VGAHDE ) > > 1 ;
tempbx = ( SiS_Pr - > PanelHRS + 1 ) & ~ 1 ;
if ( modeflag & HalfDCLK ) {
tempax > > = 1 ;
tempbx > > = 1 ;
}
SiS_Pr - > CHSyncStart = ( VGAHDE + tempax + tempbx + 7 ) & ~ 7 ;
tempax = SiS_Pr - > PanelHRE + 7 ;
if ( modeflag & HalfDCLK ) tempax > > = 1 ;
SiS_Pr - > CHSyncEnd = ( SiS_Pr - > CHSyncStart + tempax ) & ~ 7 ;
} else {
SiS_Pr - > CHSyncStart = SiS_Pr - > SiS_VGAHDE ;
if ( modeflag & HalfDCLK ) {
SiS_Pr - > CHSyncStart > > = 1 ;
tempax = ( ( SiS_Pr - > CHTotal - SiS_Pr - > CHSyncStart ) / 3 ) < < 1 ;
SiS_Pr - > CHSyncEnd = SiS_Pr - > CHSyncStart + tempax ;
} else {
SiS_Pr - > CHSyncEnd = ( SiS_Pr - > CHSyncStart + ( SiS_Pr - > CHTotal / 10 ) + 7 ) & ~ 7 ;
SiS_Pr - > CHSyncStart + = 8 ;
}
}
# endif
} else {
# ifdef SIS315H
tempax = VGAHDE ;
if ( SiS_Pr - > SiS_LCDInfo & DontExpandLCD ) {
tempbx = SiS_Pr - > PanelXRes ;
if ( modeflag & HalfDCLK ) tempbx > > = 1 ;
tempax + = ( ( tempbx - tempax ) > > 1 ) ;
}
tempax + = SiS_Pr - > PanelHRS ;
SiS_Pr - > CHSyncStart = tempax ;
tempax + = SiS_Pr - > PanelHRE ;
SiS_Pr - > CHSyncEnd = tempax ;
# endif
2005-04-17 02:20:36 +04:00
}
tempbx = SiS_Pr - > PanelVT - SiS_Pr - > PanelYRes ;
tempax = SiS_Pr - > SiS_VGAVDE ;
if ( SiS_Pr - > SiS_LCDInfo & DontExpandLCD ) {
tempax = SiS_Pr - > PanelYRes ;
2005-09-10 00:04:45 +04:00
} else if ( SiS_Pr - > ChipType < SIS_315H ) {
# ifdef SIS300
/* Stupid hack for 640x400/320x200 */
if ( SiS_Pr - > SiS_LCDResInfo = = Panel_1024x768 ) {
if ( ( tempax + tempbx ) = = 438 ) tempbx + = 16 ;
} else if ( ( SiS_Pr - > SiS_LCDResInfo = = Panel_800x600 ) | |
( SiS_Pr - > SiS_LCDResInfo = = Panel_1024x600 ) ) {
tempax = 0 ;
tempbx = SiS_Pr - > SiS_VGAVT ;
}
# endif
2005-04-17 02:20:36 +04:00
}
SiS_Pr - > CVTotal = SiS_Pr - > CVBlankEnd = tempbx + tempax ;
tempax = SiS_Pr - > SiS_VGAVDE ;
if ( SiS_Pr - > SiS_LCDInfo & DontExpandLCD ) {
tempax + = ( SiS_Pr - > PanelYRes - tempax ) > > 1 ;
}
tempax + = SiS_Pr - > PanelVRS ;
SiS_Pr - > CVSyncStart = tempax ;
tempax + = SiS_Pr - > PanelVRE ;
SiS_Pr - > CVSyncEnd = tempax ;
2005-09-10 00:04:45 +04:00
if ( SiS_Pr - > ChipType < SIS_315H ) {
SiS_Pr - > CVSyncStart - - ;
SiS_Pr - > CVSyncEnd - - ;
}
2005-04-17 02:20:36 +04:00
SiS_CalcCRRegisters ( SiS_Pr , 8 ) ;
2005-09-10 00:04:45 +04:00
SiS_Pr - > CCRT1CRTC [ 15 ] & = ~ 0xF8 ;
SiS_Pr - > CCRT1CRTC [ 15 ] | = ( remaining < < 4 ) ;
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 16 ] & = ~ 0xE0 ;
SiS_SetRegAND ( SiS_Pr - > SiS_P3d4 , 0x11 , 0x7f ) ;
2005-09-10 00:04:45 +04:00
for ( i = 0 , j = 0 ; i < = 7 ; i + + , j + + ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , j , SiS_Pr - > CCRT1CRTC [ i ] ) ;
}
2005-09-10 00:04:45 +04:00
for ( j = 0x10 ; i < = 10 ; i + + , j + + ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , j , SiS_Pr - > CCRT1CRTC [ i ] ) ;
}
2005-09-10 00:04:45 +04:00
for ( j = 0x15 ; i < = 12 ; i + + , j + + ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3d4 , j , SiS_Pr - > CCRT1CRTC [ i ] ) ;
}
2005-09-10 00:04:45 +04:00
for ( j = 0x0A ; i < = 15 ; i + + , j + + ) {
2005-04-17 02:20:36 +04:00
SiS_SetReg ( SiS_Pr - > SiS_P3c4 , j , SiS_Pr - > CCRT1CRTC [ i ] ) ;
}
tempax = SiS_Pr - > CCRT1CRTC [ 16 ] & 0xE0 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3c4 , 0x0E , 0x1F , tempax ) ;
tempax = ( SiS_Pr - > CCRT1CRTC [ 16 ] & 0x01 ) < < 5 ;
if ( modeflag & DoubleScanMode ) tempax | = 0x80 ;
SiS_SetRegANDOR ( SiS_Pr - > SiS_P3d4 , 0x09 , 0x5F , tempax ) ;
2005-09-10 00:04:45 +04:00
# ifdef SIS_XORG_XF86
2005-04-17 02:20:36 +04:00
# ifdef TWDEBUG
xf86DrvMsg ( 0 , X_INFO , " %d %d %d %d %d %d %d %d (%d %d %d %d) \n " ,
2005-09-10 00:04:45 +04:00
SiS_Pr - > CHDisplay , SiS_Pr - > CHSyncStart , SiS_Pr - > CHSyncEnd , SiS_Pr - > CHTotal ,
2005-04-17 02:20:36 +04:00
SiS_Pr - > CVDisplay , SiS_Pr - > CVSyncStart , SiS_Pr - > CVSyncEnd , SiS_Pr - > CVTotal ,
SiS_Pr - > CHBlankStart , SiS_Pr - > CHBlankEnd , SiS_Pr - > CVBlankStart , SiS_Pr - > CVBlankEnd ) ;
xf86DrvMsg ( 0 , X_INFO , " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x, \n " ,
2005-09-10 00:04:45 +04:00
SiS_Pr - > CCRT1CRTC [ 0 ] , SiS_Pr - > CCRT1CRTC [ 1 ] ,
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 2 ] , SiS_Pr - > CCRT1CRTC [ 3 ] ,
SiS_Pr - > CCRT1CRTC [ 4 ] , SiS_Pr - > CCRT1CRTC [ 5 ] ,
SiS_Pr - > CCRT1CRTC [ 6 ] , SiS_Pr - > CCRT1CRTC [ 7 ] ) ;
xf86DrvMsg ( 0 , X_INFO , " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x, \n " ,
2005-09-10 00:04:45 +04:00
SiS_Pr - > CCRT1CRTC [ 8 ] , SiS_Pr - > CCRT1CRTC [ 9 ] ,
2005-04-17 02:20:36 +04:00
SiS_Pr - > CCRT1CRTC [ 10 ] , SiS_Pr - > CCRT1CRTC [ 11 ] ,
SiS_Pr - > CCRT1CRTC [ 12 ] , SiS_Pr - > CCRT1CRTC [ 13 ] ,
SiS_Pr - > CCRT1CRTC [ 14 ] , SiS_Pr - > CCRT1CRTC [ 15 ] ) ;
xf86DrvMsg ( 0 , X_INFO , " 0x%02x}}, \n " , SiS_Pr - > CCRT1CRTC [ 16 ] ) ;
# endif
2005-09-10 00:04:45 +04:00
# endif
2005-04-17 02:20:36 +04:00
}
void
2005-09-10 00:04:45 +04:00
SiS_Generic_ConvertCRData ( struct SiS_Private * SiS_Pr , unsigned char * crdata ,
int xres , int yres ,
# ifdef SIS_XORG_XF86
DisplayModePtr current
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
2007-02-12 11:55:06 +03:00
struct fb_var_screeninfo * var , bool writeres
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
)
2005-04-17 02:20:36 +04:00
{
2005-09-10 00:04:45 +04:00
unsigned short HRE , HBE , HRS , HBS , HDE , HT ;
unsigned short VRE , VBE , VRS , VBS , VDE , VT ;
unsigned char sr_data , cr_data , cr_data2 ;
int A , B , C , D , E , F , temp ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
sr_data = crdata [ 14 ] ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Horizontal total */
HT = crdata [ 0 ] | ( ( unsigned short ) ( sr_data & 0x03 ) < < 8 ) ;
A = HT + 5 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Horizontal display enable end */
HDE = crdata [ 1 ] | ( ( unsigned short ) ( sr_data & 0x0C ) < < 6 ) ;
E = HDE + 1 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Horizontal retrace (=sync) start */
HRS = crdata [ 4 ] | ( ( unsigned short ) ( sr_data & 0xC0 ) < < 2 ) ;
F = HRS - E - 3 ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Horizontal blank start */
HBS = crdata [ 2 ] | ( ( unsigned short ) ( sr_data & 0x30 ) < < 4 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
sr_data = crdata [ 15 ] ;
cr_data = crdata [ 5 ] ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Horizontal blank end */
HBE = ( crdata [ 3 ] & 0x1f ) |
( ( unsigned short ) ( cr_data & 0x80 ) > > 2 ) |
( ( unsigned short ) ( sr_data & 0x03 ) < < 6 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
/* Horizontal retrace (=sync) end */
HRE = ( cr_data & 0x1f ) | ( ( sr_data & 0x04 ) < < 3 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
temp = HBE - ( ( E - 1 ) & 255 ) ;
B = ( temp > 0 ) ? temp : ( temp + 256 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
temp = HRE - ( ( E + F + 3 ) & 63 ) ;
C = ( temp > 0 ) ? temp : ( temp + 64 ) ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
D = B - F - C ;
2005-04-17 02:20:36 +04:00
2005-09-10 00:04:45 +04:00
# ifdef SIS_XORG_XF86
current - > HDisplay = ( E * 8 ) ;
current - > HSyncStart = ( E * 8 ) + ( F * 8 ) ;
current - > HSyncEnd = ( E * 8 ) + ( F * 8 ) + ( C * 8 ) ;
current - > HTotal = ( E * 8 ) + ( F * 8 ) + ( C * 8 ) + ( D * 8 ) ;
2005-04-17 02:20:36 +04:00
# ifdef TWDEBUG
2005-09-10 00:04:45 +04:00
xf86DrvMsg ( 0 , X_INFO ,
" H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d \n " ,
A , B , C , D , E , F , HT , HDE , HRS , HBS , HBE , HRE ) ;
2005-04-17 02:20:36 +04:00
# else
2005-09-10 00:04:45 +04:00
( void ) VBS ; ( void ) HBS ; ( void ) A ;
2005-04-17 02:20:36 +04:00
# endif
# endif
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
if ( writeres ) var - > xres = xres = E * 8 ;
var - > left_margin = D * 8 ;
var - > right_margin = F * 8 ;
var - > hsync_len = C * 8 ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
/* Vertical */
sr_data = crdata [ 13 ] ;
cr_data = crdata [ 7 ] ;
/* Vertical total */
VT = crdata [ 6 ] |
( ( unsigned short ) ( cr_data & 0x01 ) < < 8 ) |
( ( unsigned short ) ( cr_data & 0x20 ) < < 4 ) |
( ( unsigned short ) ( sr_data & 0x01 ) < < 10 ) ;
A = VT + 2 ;
/* Vertical display enable end */
VDE = crdata [ 10 ] |
( ( unsigned short ) ( cr_data & 0x02 ) < < 7 ) |
( ( unsigned short ) ( cr_data & 0x40 ) < < 3 ) |
( ( unsigned short ) ( sr_data & 0x02 ) < < 9 ) ;
E = VDE + 1 ;
/* Vertical retrace (=sync) start */
VRS = crdata [ 8 ] |
( ( unsigned short ) ( cr_data & 0x04 ) < < 6 ) |
( ( unsigned short ) ( cr_data & 0x80 ) < < 2 ) |
( ( unsigned short ) ( sr_data & 0x08 ) < < 7 ) ;
F = VRS + 1 - E ;
cr_data2 = ( crdata [ 16 ] & 0x01 ) < < 5 ;
/* Vertical blank start */
VBS = crdata [ 11 ] |
( ( unsigned short ) ( cr_data & 0x08 ) < < 5 ) |
( ( unsigned short ) ( cr_data2 & 0x20 ) < < 4 ) |
( ( unsigned short ) ( sr_data & 0x04 ) < < 8 ) ;
/* Vertical blank end */
VBE = crdata [ 12 ] | ( ( unsigned short ) ( sr_data & 0x10 ) < < 4 ) ;
temp = VBE - ( ( E - 1 ) & 511 ) ;
B = ( temp > 0 ) ? temp : ( temp + 512 ) ;
/* Vertical retrace (=sync) end */
VRE = ( crdata [ 9 ] & 0x0f ) | ( ( sr_data & 0x20 ) > > 1 ) ;
temp = VRE - ( ( E + F - 1 ) & 31 ) ;
C = ( temp > 0 ) ? temp : ( temp + 32 ) ;
D = B - F - C ;
# ifdef SIS_XORG_XF86
current - > VDisplay = VDE + 1 ;
current - > VSyncStart = VRS + 1 ;
current - > VSyncEnd = ( ( VRS & ~ 0x1f ) | VRE ) + 1 ;
if ( VRE < = ( VRS & 0x1f ) ) current - > VSyncEnd + = 32 ;
current - > VTotal = E + D + C + F ;
2005-04-17 02:20:36 +04:00
#if 0
2005-09-10 00:04:45 +04:00
current - > VDisplay = E ;
current - > VSyncStart = E + D ;
current - > VSyncEnd = E + D + C ;
current - > VTotal = E + D + C + F ;
2005-04-17 02:20:36 +04:00
# endif
# ifdef TWDEBUG
2005-09-10 00:04:45 +04:00
xf86DrvMsg ( 0 , X_INFO ,
" V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d \n " ,
A , B , C , D , E , F , VT , VDE , VRS , VBS , VBE , VRE ) ;
2005-04-17 02:20:36 +04:00
# endif
# endif
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
if ( writeres ) var - > yres = yres = E ;
var - > upper_margin = D ;
var - > lower_margin = F ;
var - > vsync_len = C ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
if ( ( xres = = 320 ) & & ( ( yres = = 200 ) | | ( yres = = 240 ) ) ) {
/* Terrible hack, but correct CRTC data for
* these modes only produces a black screen . . .
* ( HRE is 0 , leading into a too large C and
* a negative D . The CRT controller does not
* seem to like correcting HRE to 50 )
*/
# ifdef SIS_XORG_XF86
current - > HDisplay = 320 ;
current - > HSyncStart = 328 ;
current - > HSyncEnd = 376 ;
current - > HTotal = 400 ;
2005-04-17 02:20:36 +04:00
# endif
2005-09-10 00:04:45 +04:00
# ifdef SIS_LINUX_KERNEL
var - > left_margin = ( 400 - 376 ) ;
var - > right_margin = ( 328 - 320 ) ;
var - > hsync_len = ( 376 - 328 ) ;
2005-04-17 02:20:36 +04:00
# endif
}
}