172b676d7Smrg/* 272b676d7Smrg * Mode initializing code (CRT1 section) for 372b676d7Smrg * for SiS 300/305/540/630/730, 472b676d7Smrg * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX], 572b676d7Smrg * XGI Volari V3XT/V5/V8, Z7 672b676d7Smrg * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x) 772b676d7Smrg * 872b676d7Smrg * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 972b676d7Smrg * 1072b676d7Smrg * If distributed as part of the Linux kernel, the following license terms 1172b676d7Smrg * apply: 1272b676d7Smrg * 1372b676d7Smrg * * This program is free software; you can redistribute it and/or modify 1472b676d7Smrg * * it under the terms of the GNU General Public License as published by 1572b676d7Smrg * * the Free Software Foundation; either version 2 of the named License, 1672b676d7Smrg * * or any later version. 1772b676d7Smrg * * 1872b676d7Smrg * * This program is distributed in the hope that it will be useful, 1972b676d7Smrg * * but WITHOUT ANY WARRANTY; without even the implied warranty of 2072b676d7Smrg * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2172b676d7Smrg * * GNU General Public License for more details. 2272b676d7Smrg * * 2372b676d7Smrg * * You should have received a copy of the GNU General Public License 2472b676d7Smrg * * along with this program; if not, write to the Free Software 2572b676d7Smrg * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 2672b676d7Smrg * 2772b676d7Smrg * Otherwise, the following license terms apply: 2872b676d7Smrg * 2972b676d7Smrg * * Redistribution and use in source and binary forms, with or without 3072b676d7Smrg * * modification, are permitted provided that the following conditions 3172b676d7Smrg * * are met: 3272b676d7Smrg * * 1) Redistributions of source code must retain the above copyright 3372b676d7Smrg * * notice, this list of conditions and the following disclaimer. 3472b676d7Smrg * * 2) Redistributions in binary form must reproduce the above copyright 3572b676d7Smrg * * notice, this list of conditions and the following disclaimer in the 3672b676d7Smrg * * documentation and/or other materials provided with the distribution. 3772b676d7Smrg * * 3) The name of the author may not be used to endorse or promote products 3872b676d7Smrg * * derived from this software without specific prior written permission. 3972b676d7Smrg * * 4072b676d7Smrg * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 4172b676d7Smrg * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 4272b676d7Smrg * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 4372b676d7Smrg * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 4472b676d7Smrg * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4572b676d7Smrg * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 4672b676d7Smrg * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 4772b676d7Smrg * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 4872b676d7Smrg * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 4972b676d7Smrg * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5072b676d7Smrg * 5172b676d7Smrg * Author: Thomas Winischhofer <thomas@winischhofer.net> 5272b676d7Smrg * 5372b676d7Smrg * Formerly based on non-functional code-fragements for 300 series by SiS, Inc. 5472b676d7Smrg * Used by permission. 5572b676d7Smrg */ 5672b676d7Smrg 5772b676d7Smrg#ifdef HAVE_CONFIG_H 5872b676d7Smrg#include "config.h" 5972b676d7Smrg#endif 6072b676d7Smrg 6172b676d7Smrg#include "init.h" 6274c14cd6Smrg#include "sis_dac.h" 6372b676d7Smrg 6472b676d7Smrg#ifdef SIS300 6572b676d7Smrg#include "300vtbl.h" 6672b676d7Smrg#endif 6772b676d7Smrg 6872b676d7Smrg#ifdef SIS315H 6972b676d7Smrg#include "310vtbl.h" 7072b676d7Smrg#endif 7172b676d7Smrg 7272b676d7Smrg#if defined(ALLOC_PRAGMA) 7372b676d7Smrg#pragma alloc_text(PAGE,SiSSetMode) 7472b676d7Smrg#endif 7572b676d7Smrg 7672b676d7Smrg/*********************************************/ 7772b676d7Smrg/* POINTER INITIALIZATION */ 7872b676d7Smrg/*********************************************/ 7972b676d7Smrg 8072b676d7Smrg#if defined(SIS300) || defined(SIS315H) 8172b676d7Smrgstatic void 8272b676d7SmrgInitCommonPointer(struct SiS_Private *SiS_Pr) 8372b676d7Smrg{ 8472b676d7Smrg SiS_Pr->SiS_SModeIDTable = SiS_SModeIDTable; 8572b676d7Smrg SiS_Pr->SiS_StResInfo = SiS_StResInfo; 8672b676d7Smrg SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo; 8772b676d7Smrg SiS_Pr->SiS_StandTable = SiS_StandTable; 8872b676d7Smrg 8972b676d7Smrg SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming; 9072b676d7Smrg SiS_Pr->SiS_PALTiming = SiS_PALTiming; 9172b676d7Smrg SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing; 9272b676d7Smrg SiS_Pr->SiS_HiTVSt2Timing = SiS_HiTVSt2Timing; 9372b676d7Smrg 9472b676d7Smrg SiS_Pr->SiS_HiTVExtTiming = SiS_HiTVExtTiming; 9572b676d7Smrg SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data; 9672b676d7Smrg SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu; 9772b676d7Smrg#if 0 9872b676d7Smrg SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming; 9972b676d7Smrg SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text; 10072b676d7Smrg#endif 10172b676d7Smrg 10272b676d7Smrg SiS_Pr->SiS_StPALData = SiS_StPALData; 10372b676d7Smrg SiS_Pr->SiS_ExtPALData = SiS_ExtPALData; 10472b676d7Smrg SiS_Pr->SiS_StNTSCData = SiS_StNTSCData; 10572b676d7Smrg SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData; 10672b676d7Smrg SiS_Pr->SiS_St1HiTVData = SiS_StHiTVData; 10772b676d7Smrg SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData; 10872b676d7Smrg SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData; 10972b676d7Smrg SiS_Pr->SiS_St525iData = SiS_StNTSCData; 11072b676d7Smrg SiS_Pr->SiS_St525pData = SiS_St525pData; 11172b676d7Smrg SiS_Pr->SiS_St625iData = SiS_StPALData; 11272b676d7Smrg SiS_Pr->SiS_St625pData = SiS_StPALData; 11372b676d7Smrg SiS_Pr->SiS_St750pData = SiS_St750pData; 11472b676d7Smrg SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData; 11572b676d7Smrg SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData; 11672b676d7Smrg SiS_Pr->SiS_Ext625iData = SiS_ExtPALData; 11772b676d7Smrg SiS_Pr->SiS_Ext625pData = SiS_ExtPALData; 11872b676d7Smrg SiS_Pr->SiS_Ext750pData = SiS_Ext750pData; 11972b676d7Smrg 12072b676d7Smrg SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect; 12172b676d7Smrg SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting; 12272b676d7Smrg 12372b676d7Smrg SiS_Pr->SiS_LCD1280x720Data = SiS_LCD1280x720Data; 12472b676d7Smrg SiS_Pr->SiS_StLCD1280x768_2Data = SiS_StLCD1280x768_2Data; 12572b676d7Smrg SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data; 12672b676d7Smrg SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data; 12772b676d7Smrg SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data; 12872b676d7Smrg SiS_Pr->SiS_LCD1280x854Data = SiS_LCD1280x854Data; 12972b676d7Smrg SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data; 13072b676d7Smrg SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data; 13172b676d7Smrg SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data; 13272b676d7Smrg SiS_Pr->SiS_LCD1680x1050Data = SiS_LCD1680x1050Data; 13372b676d7Smrg SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data; 13472b676d7Smrg SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data; 13572b676d7Smrg SiS_Pr->SiS_NoScaleData = SiS_NoScaleData; 13672b676d7Smrg 13772b676d7Smrg SiS_Pr->SiS_LVDS320x240Data_1 = SiS_LVDS320x240Data_1; 13872b676d7Smrg SiS_Pr->SiS_LVDS320x240Data_2 = SiS_LVDS320x240Data_2; 13972b676d7Smrg SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1; 14072b676d7Smrg SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1; 14172b676d7Smrg SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1; 14272b676d7Smrg SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1; 14372b676d7Smrg 14472b676d7Smrg SiS_Pr->SiS_LVDSCRT1320x240_1 = SiS_LVDSCRT1320x240_1; 14572b676d7Smrg SiS_Pr->SiS_LVDSCRT1320x240_2 = SiS_LVDSCRT1320x240_2; 14672b676d7Smrg SiS_Pr->SiS_LVDSCRT1320x240_2_H = SiS_LVDSCRT1320x240_2_H; 14772b676d7Smrg SiS_Pr->SiS_LVDSCRT1320x240_3 = SiS_LVDSCRT1320x240_3; 14872b676d7Smrg SiS_Pr->SiS_LVDSCRT1320x240_3_H = SiS_LVDSCRT1320x240_3_H; 14972b676d7Smrg SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1; 15072b676d7Smrg SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H; 15172b676d7Smrg#if 0 15272b676d7Smrg SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1; 15372b676d7Smrg SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H; 15472b676d7Smrg SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2; 15572b676d7Smrg SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H; 15672b676d7Smrg#endif 15772b676d7Smrg 15872b676d7Smrg SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData; 15972b676d7Smrg SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData; 16072b676d7Smrg 16172b676d7Smrg SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */ 16272b676d7Smrg SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */ 16372b676d7Smrg} 16472b676d7Smrg#endif 16572b676d7Smrg 16672b676d7Smrg#ifdef SIS300 16772b676d7Smrgstatic void 16872b676d7SmrgInitTo300Pointer(struct SiS_Private *SiS_Pr) 16972b676d7Smrg{ 17072b676d7Smrg InitCommonPointer(SiS_Pr); 17172b676d7Smrg 17272b676d7Smrg SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable; 17372b676d7Smrg SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable; 17472b676d7Smrg SiS_Pr->SiS_RefIndex = SiS300_RefIndex; 17572b676d7Smrg SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table; 17672b676d7Smrg if(SiS_Pr->ChipType == SIS_300) { 17772b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */ 17872b676d7Smrg } else { 17972b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */ 18072b676d7Smrg } 18172b676d7Smrg SiS_Pr->SiS_VCLKData = SiS300_VCLKData; 18272b676d7Smrg SiS_Pr->SiS_VBVCLKData = (struct SiS_VBVCLKData *)SiS300_VCLKData; 18372b676d7Smrg 18472b676d7Smrg SiS_Pr->SiS_SR15 = SiS300_SR15; 18572b676d7Smrg 18672b676d7Smrg SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl; 18772b676d7Smrg SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl; 18872b676d7Smrg 18972b676d7Smrg SiS_Pr->SiS_ExtLCD1024x768Data = SiS300_ExtLCD1024x768Data; 19072b676d7Smrg SiS_Pr->SiS_St2LCD1024x768Data = SiS300_St2LCD1024x768Data; 19172b676d7Smrg SiS_Pr->SiS_ExtLCD1280x1024Data = SiS300_ExtLCD1280x1024Data; 19272b676d7Smrg SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data; 19372b676d7Smrg 19472b676d7Smrg SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1; 19572b676d7Smrg SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2; 19672b676d7Smrg SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3; 19772b676d7Smrg 19872b676d7Smrg SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData; 19972b676d7Smrg SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData; 20072b676d7Smrg SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */ 20172b676d7Smrg SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */ 20272b676d7Smrg SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData; /* not supported on 300 series */ 20372b676d7Smrg SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */ 20472b676d7Smrg SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData; 20572b676d7Smrg 20672b676d7Smrg SiS_Pr->SiS_LVDS848x480Data_1 = SiS300_LVDS848x480Data_1; 20772b676d7Smrg SiS_Pr->SiS_LVDS848x480Data_2 = SiS300_LVDS848x480Data_2; 20872b676d7Smrg SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1; 20972b676d7Smrg SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1; 21072b676d7Smrg SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2; 21172b676d7Smrg 21272b676d7Smrg SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a; 21372b676d7Smrg SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a; 21472b676d7Smrg SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b; 21572b676d7Smrg SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b; 21672b676d7Smrg 21772b676d7Smrg SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC; 21872b676d7Smrg SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC; 21972b676d7Smrg SiS_Pr->SiS_CHTVCRT1UPAL = SiS300_CHTVCRT1UPAL; 22072b676d7Smrg SiS_Pr->SiS_CHTVCRT1OPAL = SiS300_CHTVCRT1OPAL; 22172b676d7Smrg SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL; 22272b676d7Smrg SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC; 22372b676d7Smrg SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC; 22472b676d7Smrg SiS_Pr->SiS_CHTVReg_UPAL = SiS300_CHTVReg_UPAL; 22572b676d7Smrg SiS_Pr->SiS_CHTVReg_OPAL = SiS300_CHTVReg_OPAL; 22672b676d7Smrg SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC; /* not supported on 300 series */ 22772b676d7Smrg SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC; /* not supported on 300 series */ 22872b676d7Smrg SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL; /* not supported on 300 series */ 22972b676d7Smrg SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL; /* not supported on 300 series */ 23072b676d7Smrg SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL; 23172b676d7Smrg SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC; 23272b676d7Smrg SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC; 23372b676d7Smrg SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL; 23472b676d7Smrg SiS_Pr->SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL; 23572b676d7Smrg SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC; /* not supported on 300 series */ 23672b676d7Smrg SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC; /* not supported on 300 series */ 23772b676d7Smrg SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL; /* not supported on 300 series */ 23872b676d7Smrg SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */ 23972b676d7Smrg SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL; 24072b676d7Smrg} 24172b676d7Smrg#endif 24272b676d7Smrg 24372b676d7Smrg#ifdef SIS315H 24472b676d7Smrgstatic void 24572b676d7SmrgInitTo310Pointer(struct SiS_Private *SiS_Pr) 24672b676d7Smrg{ 24772b676d7Smrg InitCommonPointer(SiS_Pr); 24872b676d7Smrg 24972b676d7Smrg SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable; 25072b676d7Smrg SiS_Pr->SiS_RefIndex = SiS310_RefIndex; 25172b676d7Smrg SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table; 25272b676d7Smrg if(SiS_Pr->ChipType >= SIS_340) { 25372b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 + XGI */ 25472b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_761) { 25572b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761; /* 761 - preliminary */ 25672b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_760) { 25772b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */ 25872b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_661) { 25972b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */ 26072b676d7Smrg } else if(SiS_Pr->ChipType == SIS_330) { 26172b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */ 26272b676d7Smrg } else if(SiS_Pr->ChipType > SIS_315PRO) { 26372b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */ 26472b676d7Smrg } else { 26572b676d7Smrg SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */ 26672b676d7Smrg } 26772b676d7Smrg if(SiS_Pr->ChipType >= SIS_340) { 26872b676d7Smrg SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340; 26972b676d7Smrg } else { 27072b676d7Smrg SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1; 27172b676d7Smrg } 27272b676d7Smrg SiS_Pr->SiS_VCLKData = SiS310_VCLKData; 27372b676d7Smrg SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData; 27472b676d7Smrg 27572b676d7Smrg SiS_Pr->SiS_SR15 = SiS310_SR15; 27672b676d7Smrg 27772b676d7Smrg SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl; 27872b676d7Smrg SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS; 27972b676d7Smrg 28072b676d7Smrg SiS_Pr->SiS_St2LCD1024x768Data = SiS310_St2LCD1024x768Data; 28172b676d7Smrg SiS_Pr->SiS_ExtLCD1024x768Data = SiS310_ExtLCD1024x768Data; 28272b676d7Smrg SiS_Pr->SiS_St2LCD1280x1024Data = SiS310_St2LCD1280x1024Data; 28372b676d7Smrg SiS_Pr->SiS_ExtLCD1280x1024Data = SiS310_ExtLCD1280x1024Data; 28472b676d7Smrg 28572b676d7Smrg SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1; 28672b676d7Smrg 28772b676d7Smrg SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData; 28872b676d7Smrg SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData; 28972b676d7Smrg SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData; 29072b676d7Smrg SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData; 29172b676d7Smrg SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData; 29272b676d7Smrg SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData; 29372b676d7Smrg SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData; 29472b676d7Smrg 29572b676d7Smrg SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC; 29672b676d7Smrg SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC; 29772b676d7Smrg SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL; 29872b676d7Smrg SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL; 29972b676d7Smrg SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL; 30072b676d7Smrg 30172b676d7Smrg SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC; 30272b676d7Smrg SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC; 30372b676d7Smrg SiS_Pr->SiS_CHTVReg_UPAL = SiS310_CHTVReg_UPAL; 30472b676d7Smrg SiS_Pr->SiS_CHTVReg_OPAL = SiS310_CHTVReg_OPAL; 30572b676d7Smrg SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM; 30672b676d7Smrg SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM; 30772b676d7Smrg SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN; 30872b676d7Smrg SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN; 30972b676d7Smrg SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL; 31072b676d7Smrg 31172b676d7Smrg SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC; 31272b676d7Smrg SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC; 31372b676d7Smrg SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL; 31472b676d7Smrg SiS_Pr->SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL; 31572b676d7Smrg SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM; 31672b676d7Smrg SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM; 31772b676d7Smrg SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN; 31872b676d7Smrg SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN; 31972b676d7Smrg SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL; 32072b676d7Smrg} 32172b676d7Smrg#endif 32272b676d7Smrg 32372b676d7SmrgBOOLEAN 32472b676d7SmrgSiSInitPtr(struct SiS_Private *SiS_Pr) 32572b676d7Smrg{ 32672b676d7Smrg if(SiS_Pr->ChipType < SIS_315H) { 32772b676d7Smrg#ifdef SIS300 32872b676d7Smrg InitTo300Pointer(SiS_Pr); 32972b676d7Smrg#else 33072b676d7Smrg return FALSE; 33172b676d7Smrg#endif 33272b676d7Smrg } else { 33372b676d7Smrg#ifdef SIS315H 33472b676d7Smrg InitTo310Pointer(SiS_Pr); 33572b676d7Smrg#else 33672b676d7Smrg return FALSE; 33772b676d7Smrg#endif 33872b676d7Smrg } 33972b676d7Smrg return TRUE; 34072b676d7Smrg} 34172b676d7Smrg 34272b676d7Smrg/*********************************************/ 34372b676d7Smrg/* HELPER: Get ModeID */ 34472b676d7Smrg/*********************************************/ 34572b676d7Smrg 34672b676d7Smrg#ifndef SIS_XORG_XF86 34772b676d7Smrgstatic 34872b676d7Smrg#endif 34972b676d7Smrgunsigned short 35072b676d7SmrgSiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, 35172b676d7Smrg int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight) 35272b676d7Smrg{ 35372b676d7Smrg unsigned short ModeIndex = 0; 35472b676d7Smrg 35572b676d7Smrg switch(HDisplay) 35672b676d7Smrg { 35772b676d7Smrg case 320: 35872b676d7Smrg if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 35972b676d7Smrg else if(VDisplay == 240) { 36072b676d7Smrg if((VBFlags & CRT2_LCD) && (FSTN)) 36172b676d7Smrg ModeIndex = ModeIndex_320x240_FSTN[Depth]; 36272b676d7Smrg else 36372b676d7Smrg ModeIndex = ModeIndex_320x240[Depth]; 36472b676d7Smrg } 36572b676d7Smrg break; 36672b676d7Smrg case 400: 36772b676d7Smrg if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) { 36872b676d7Smrg if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 36972b676d7Smrg } 37072b676d7Smrg break; 37172b676d7Smrg case 512: 37272b676d7Smrg if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) { 37372b676d7Smrg if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 37472b676d7Smrg } 37572b676d7Smrg break; 37672b676d7Smrg case 640: 37772b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 37872b676d7Smrg else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 37972b676d7Smrg break; 38072b676d7Smrg case 720: 38172b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth]; 38272b676d7Smrg else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth]; 38372b676d7Smrg break; 38472b676d7Smrg case 768: 38572b676d7Smrg if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 38672b676d7Smrg break; 38772b676d7Smrg case 800: 38872b676d7Smrg if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 38972b676d7Smrg else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; 39072b676d7Smrg break; 39172b676d7Smrg case 848: 39272b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 39372b676d7Smrg break; 39472b676d7Smrg case 856: 39572b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 39672b676d7Smrg break; 39772b676d7Smrg case 960: 39872b676d7Smrg if(VGAEngine == SIS_315_VGA) { 39972b676d7Smrg if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth]; 40072b676d7Smrg else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth]; 40172b676d7Smrg } 40272b676d7Smrg break; 40372b676d7Smrg case 1024: 40472b676d7Smrg if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth]; 40572b676d7Smrg else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 40672b676d7Smrg else if(VGAEngine == SIS_300_VGA) { 40772b676d7Smrg if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth]; 40872b676d7Smrg } 40972b676d7Smrg break; 41072b676d7Smrg case 1152: 41172b676d7Smrg if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth]; 41272b676d7Smrg if(VGAEngine == SIS_300_VGA) { 41372b676d7Smrg if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth]; 41472b676d7Smrg } 41572b676d7Smrg break; 41672b676d7Smrg case 1280: 41772b676d7Smrg switch(VDisplay) { 41872b676d7Smrg case 720: 41972b676d7Smrg ModeIndex = ModeIndex_1280x720[Depth]; 42072b676d7Smrg break; 42172b676d7Smrg case 768: 42272b676d7Smrg if(VGAEngine == SIS_300_VGA) { 42372b676d7Smrg ModeIndex = ModeIndex_300_1280x768[Depth]; 42472b676d7Smrg } else { 42572b676d7Smrg ModeIndex = ModeIndex_310_1280x768[Depth]; 42672b676d7Smrg } 42772b676d7Smrg break; 42872b676d7Smrg case 800: 42972b676d7Smrg if(VGAEngine == SIS_315_VGA) { 43072b676d7Smrg ModeIndex = ModeIndex_1280x800[Depth]; 43172b676d7Smrg } 43272b676d7Smrg break; 43372b676d7Smrg case 854: 43472b676d7Smrg if(VGAEngine == SIS_315_VGA) { 43572b676d7Smrg ModeIndex = ModeIndex_1280x854[Depth]; 43672b676d7Smrg } 43772b676d7Smrg break; 43872b676d7Smrg case 960: 43972b676d7Smrg ModeIndex = ModeIndex_1280x960[Depth]; 44072b676d7Smrg break; 44172b676d7Smrg case 1024: 44272b676d7Smrg ModeIndex = ModeIndex_1280x1024[Depth]; 44372b676d7Smrg break; 44472b676d7Smrg } 44572b676d7Smrg break; 44672b676d7Smrg case 1360: 44772b676d7Smrg if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 44872b676d7Smrg if(VGAEngine == SIS_300_VGA) { 44972b676d7Smrg if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth]; 45072b676d7Smrg } 45172b676d7Smrg break; 45272b676d7Smrg case 1400: 45372b676d7Smrg if(VGAEngine == SIS_315_VGA) { 45472b676d7Smrg if(VDisplay == 1050) { 45572b676d7Smrg ModeIndex = ModeIndex_1400x1050[Depth]; 45672b676d7Smrg } 45772b676d7Smrg } 45872b676d7Smrg break; 45972b676d7Smrg case 1600: 46072b676d7Smrg if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 46172b676d7Smrg break; 46272b676d7Smrg case 1680: 46372b676d7Smrg if(VGAEngine == SIS_315_VGA) { 46472b676d7Smrg if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; 46572b676d7Smrg } 46672b676d7Smrg break; 46772b676d7Smrg case 1920: 46872b676d7Smrg if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth]; 46972b676d7Smrg else if(VGAEngine == SIS_315_VGA) { 47072b676d7Smrg if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth]; 47172b676d7Smrg } 47272b676d7Smrg break; 47372b676d7Smrg case 2048: 47472b676d7Smrg if(VDisplay == 1536) { 47572b676d7Smrg if(VGAEngine == SIS_300_VGA) { 47672b676d7Smrg ModeIndex = ModeIndex_300_2048x1536[Depth]; 47772b676d7Smrg } else { 47872b676d7Smrg ModeIndex = ModeIndex_310_2048x1536[Depth]; 47972b676d7Smrg } 48072b676d7Smrg } 48172b676d7Smrg break; 48272b676d7Smrg } 48372b676d7Smrg 48472b676d7Smrg return ModeIndex; 48572b676d7Smrg} 48672b676d7Smrg 48772b676d7Smrgunsigned short 48872b676d7SmrgSiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, 48972b676d7Smrg int Depth, BOOLEAN FSTN, unsigned short CustomT, int LCDwidth, int LCDheight, 49072b676d7Smrg unsigned int VBFlags2) 49172b676d7Smrg{ 49272b676d7Smrg unsigned short ModeIndex = 0; 49372b676d7Smrg 49472b676d7Smrg if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) { 49572b676d7Smrg 49672b676d7Smrg switch(HDisplay) 49772b676d7Smrg { 49872b676d7Smrg case 320: 49972b676d7Smrg if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) { 50072b676d7Smrg if(VDisplay == 200) { 50172b676d7Smrg if(!FSTN) ModeIndex = ModeIndex_320x200[Depth]; 50272b676d7Smrg } else if(VDisplay == 240) { 50372b676d7Smrg if(!FSTN) ModeIndex = ModeIndex_320x240[Depth]; 50472b676d7Smrg else if(VGAEngine == SIS_315_VGA) { 50572b676d7Smrg ModeIndex = ModeIndex_320x240_FSTN[Depth]; 50672b676d7Smrg } 50772b676d7Smrg } 50872b676d7Smrg } 50972b676d7Smrg break; 51072b676d7Smrg case 400: 51172b676d7Smrg if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) { 51272b676d7Smrg if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) { 51372b676d7Smrg if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 51472b676d7Smrg } 51572b676d7Smrg } 51672b676d7Smrg break; 51772b676d7Smrg case 512: 51872b676d7Smrg if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) { 51972b676d7Smrg if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) { 52072b676d7Smrg if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) { 52172b676d7Smrg if(VDisplay == 384) { 52272b676d7Smrg ModeIndex = ModeIndex_512x384[Depth]; 52372b676d7Smrg } 52472b676d7Smrg } 52572b676d7Smrg } 52672b676d7Smrg } 52772b676d7Smrg break; 52872b676d7Smrg case 640: 52972b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 53072b676d7Smrg else if(VDisplay == 400) { 53172b676d7Smrg if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) 53272b676d7Smrg ModeIndex = ModeIndex_640x400[Depth]; 53372b676d7Smrg } 53472b676d7Smrg break; 53572b676d7Smrg case 800: 53672b676d7Smrg if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 53772b676d7Smrg break; 53872b676d7Smrg case 848: 53972b676d7Smrg if(CustomT == CUT_PANEL848) { 54072b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 54172b676d7Smrg } 54272b676d7Smrg break; 54372b676d7Smrg case 856: 54472b676d7Smrg if(CustomT == CUT_PANEL856) { 54572b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 54672b676d7Smrg } 54772b676d7Smrg break; 54872b676d7Smrg case 1024: 54972b676d7Smrg if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 55072b676d7Smrg else if(VGAEngine == SIS_300_VGA) { 55172b676d7Smrg if((VDisplay == 600) && (LCDheight == 600)) { 55272b676d7Smrg ModeIndex = ModeIndex_1024x600[Depth]; 55372b676d7Smrg } 55472b676d7Smrg } 55572b676d7Smrg break; 55672b676d7Smrg case 1152: 55772b676d7Smrg if(VGAEngine == SIS_300_VGA) { 55872b676d7Smrg if((VDisplay == 768) && (LCDheight == 768)) { 55972b676d7Smrg ModeIndex = ModeIndex_1152x768[Depth]; 56072b676d7Smrg } 56172b676d7Smrg } 56272b676d7Smrg break; 56372b676d7Smrg case 1280: 56472b676d7Smrg if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth]; 56572b676d7Smrg else if(VGAEngine == SIS_315_VGA) { 56672b676d7Smrg if((VDisplay == 768) && (LCDheight == 768)) { 56772b676d7Smrg ModeIndex = ModeIndex_310_1280x768[Depth]; 56872b676d7Smrg } 56972b676d7Smrg } 57072b676d7Smrg break; 57172b676d7Smrg case 1360: 57272b676d7Smrg if(VGAEngine == SIS_300_VGA) { 57372b676d7Smrg if(CustomT == CUT_BARCO1366) { 57472b676d7Smrg if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth]; 57572b676d7Smrg } 57672b676d7Smrg } 57772b676d7Smrg if(CustomT == CUT_PANEL848) { 57872b676d7Smrg if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 57972b676d7Smrg } 58072b676d7Smrg break; 58172b676d7Smrg case 1400: 58272b676d7Smrg if(VGAEngine == SIS_315_VGA) { 58372b676d7Smrg if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth]; 58472b676d7Smrg } 58572b676d7Smrg break; 58672b676d7Smrg case 1600: 58772b676d7Smrg if(VGAEngine == SIS_315_VGA) { 58872b676d7Smrg if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 58972b676d7Smrg } 59072b676d7Smrg break; 59172b676d7Smrg } 59272b676d7Smrg 59372b676d7Smrg } else if(VBFlags2 & VB2_SISBRIDGE) { 59472b676d7Smrg 59572b676d7Smrg switch(HDisplay) 59672b676d7Smrg { 59772b676d7Smrg case 320: 59872b676d7Smrg if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 59972b676d7Smrg else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth]; 60072b676d7Smrg break; 60172b676d7Smrg case 400: 60272b676d7Smrg if(LCDwidth >= 800 && LCDheight >= 600) { 60372b676d7Smrg if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 60472b676d7Smrg } 60572b676d7Smrg break; 60672b676d7Smrg case 512: 60772b676d7Smrg if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) { 60872b676d7Smrg if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 60972b676d7Smrg } 61072b676d7Smrg break; 61172b676d7Smrg case 640: 61272b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 61372b676d7Smrg else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 61472b676d7Smrg break; 61572b676d7Smrg case 720: 61672b676d7Smrg if(VGAEngine == SIS_315_VGA) { 61772b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth]; 61872b676d7Smrg else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth]; 61972b676d7Smrg } 62072b676d7Smrg break; 62172b676d7Smrg case 768: 62272b676d7Smrg if(VGAEngine == SIS_315_VGA) { 62372b676d7Smrg if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 62472b676d7Smrg } 62572b676d7Smrg break; 62672b676d7Smrg case 800: 62772b676d7Smrg if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 62872b676d7Smrg if(VGAEngine == SIS_315_VGA) { 62972b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; 63072b676d7Smrg } 63172b676d7Smrg break; 63272b676d7Smrg case 848: 63372b676d7Smrg if(VGAEngine == SIS_315_VGA) { 63472b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 63572b676d7Smrg } 63672b676d7Smrg break; 63772b676d7Smrg case 856: 63872b676d7Smrg if(VGAEngine == SIS_315_VGA) { 63972b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 64072b676d7Smrg } 64172b676d7Smrg break; 64272b676d7Smrg case 960: 64372b676d7Smrg if(VGAEngine == SIS_315_VGA) { 64472b676d7Smrg if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth]; 64572b676d7Smrg else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth]; 64672b676d7Smrg } 64772b676d7Smrg break; 64872b676d7Smrg case 1024: 64972b676d7Smrg if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 65072b676d7Smrg if(VGAEngine == SIS_315_VGA) { 65172b676d7Smrg if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth]; 65272b676d7Smrg } 65372b676d7Smrg break; 65472b676d7Smrg case 1152: 65572b676d7Smrg if(VGAEngine == SIS_315_VGA) { 65672b676d7Smrg if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth]; 65772b676d7Smrg } 65872b676d7Smrg break; 65972b676d7Smrg case 1280: 66072b676d7Smrg switch(VDisplay) { 66172b676d7Smrg case 720: 66272b676d7Smrg ModeIndex = ModeIndex_1280x720[Depth]; 66372b676d7Smrg case 768: 66472b676d7Smrg if(VGAEngine == SIS_300_VGA) { 66572b676d7Smrg ModeIndex = ModeIndex_300_1280x768[Depth]; 66672b676d7Smrg } else { 66772b676d7Smrg ModeIndex = ModeIndex_310_1280x768[Depth]; 66872b676d7Smrg } 66972b676d7Smrg break; 67072b676d7Smrg case 800: 67172b676d7Smrg if(VGAEngine == SIS_315_VGA) { 67272b676d7Smrg ModeIndex = ModeIndex_1280x800[Depth]; 67372b676d7Smrg } 67472b676d7Smrg break; 67572b676d7Smrg case 854: 67672b676d7Smrg if(VGAEngine == SIS_315_VGA) { 67772b676d7Smrg ModeIndex = ModeIndex_1280x854[Depth]; 67872b676d7Smrg } 67972b676d7Smrg break; 68072b676d7Smrg case 960: 68172b676d7Smrg ModeIndex = ModeIndex_1280x960[Depth]; 68272b676d7Smrg break; 68372b676d7Smrg case 1024: 68472b676d7Smrg ModeIndex = ModeIndex_1280x1024[Depth]; 68572b676d7Smrg break; 68672b676d7Smrg } 68772b676d7Smrg break; 68872b676d7Smrg case 1360: 68972b676d7Smrg if(VGAEngine == SIS_315_VGA) { /* OVER1280 only? */ 69072b676d7Smrg if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 69172b676d7Smrg } 69272b676d7Smrg break; 69372b676d7Smrg case 1400: 69472b676d7Smrg if(VGAEngine == SIS_315_VGA) { 69572b676d7Smrg if(VBFlags2 & VB2_LCDOVER1280BRIDGE) { 69672b676d7Smrg if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth]; 69772b676d7Smrg } 69872b676d7Smrg } 69972b676d7Smrg break; 70072b676d7Smrg case 1600: 70172b676d7Smrg if(VGAEngine == SIS_315_VGA) { 70272b676d7Smrg if(VBFlags2 & VB2_LCDOVER1280BRIDGE) { 70372b676d7Smrg if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 70472b676d7Smrg } 70572b676d7Smrg } 70672b676d7Smrg break; 70772b676d7Smrg#ifndef VB_FORBID_CRT2LCD_OVER_1600 70872b676d7Smrg case 1680: 70972b676d7Smrg if(VGAEngine == SIS_315_VGA) { 71072b676d7Smrg if(VBFlags2 & VB2_LCDOVER1280BRIDGE) { 71172b676d7Smrg if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; 71272b676d7Smrg } 71372b676d7Smrg } 71472b676d7Smrg break; 71572b676d7Smrg case 1920: 71672b676d7Smrg if(VGAEngine == SIS_315_VGA) { 71772b676d7Smrg if(VBFlags2 & VB2_LCDOVER1600BRIDGE) { 71872b676d7Smrg if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth]; 71972b676d7Smrg } 72072b676d7Smrg } 72172b676d7Smrg break; 72272b676d7Smrg case 2048: 72372b676d7Smrg if(VGAEngine == SIS_315_VGA) { 72472b676d7Smrg if(VBFlags2 & VB2_LCDOVER1600BRIDGE) { 72572b676d7Smrg if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth]; 72672b676d7Smrg } 72772b676d7Smrg } 72872b676d7Smrg break; 72972b676d7Smrg#endif 73072b676d7Smrg } 73172b676d7Smrg } 73272b676d7Smrg 73372b676d7Smrg return ModeIndex; 73472b676d7Smrg} 73572b676d7Smrg 73672b676d7Smrgunsigned short 73772b676d7SmrgSiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth, 73872b676d7Smrg unsigned int VBFlags2) 73972b676d7Smrg{ 74072b676d7Smrg unsigned short ModeIndex = 0; 74172b676d7Smrg 74272b676d7Smrg if(VBFlags2 & VB2_CHRONTEL) { 74372b676d7Smrg 74472b676d7Smrg switch(HDisplay) 74572b676d7Smrg { 74672b676d7Smrg case 512: 74772b676d7Smrg if(VGAEngine == SIS_315_VGA) { 74872b676d7Smrg if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 74972b676d7Smrg } 75072b676d7Smrg break; 75172b676d7Smrg case 640: 75272b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 75372b676d7Smrg else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 75472b676d7Smrg break; 75572b676d7Smrg case 800: 75672b676d7Smrg if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 75772b676d7Smrg break; 75872b676d7Smrg case 1024: 75972b676d7Smrg if(VGAEngine == SIS_315_VGA) { 76072b676d7Smrg if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 76172b676d7Smrg } 76272b676d7Smrg break; 76372b676d7Smrg } 76472b676d7Smrg 76572b676d7Smrg } else if(VBFlags2 & VB2_SISTVBRIDGE) { 76672b676d7Smrg 76772b676d7Smrg switch(HDisplay) 76872b676d7Smrg { 76972b676d7Smrg case 320: 77072b676d7Smrg if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 77172b676d7Smrg else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth]; 77272b676d7Smrg break; 77372b676d7Smrg case 400: 77472b676d7Smrg if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 77572b676d7Smrg break; 77672b676d7Smrg case 512: 77772b676d7Smrg if(VBFlags2 & VB2_30xBLV) { 77872b676d7Smrg if( ((VBFlags & TV_YPBPR) && (!(VBFlags & (TV_YPBPR525P | TV_YPBPR525I)))) || 77972b676d7Smrg (VBFlags & TV_HIVISION) || 78072b676d7Smrg ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) { 78172b676d7Smrg if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 78272b676d7Smrg } 78372b676d7Smrg } 78472b676d7Smrg break; 78572b676d7Smrg case 640: 78672b676d7Smrg if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 78772b676d7Smrg else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 78872b676d7Smrg break; 78972b676d7Smrg case 720: 79072b676d7Smrg if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) { 79172b676d7Smrg if(VDisplay == 480) { 79272b676d7Smrg ModeIndex = ModeIndex_720x480[Depth]; 79372b676d7Smrg } else if(VDisplay == 576) { 79472b676d7Smrg ModeIndex = ModeIndex_720x576[Depth]; 79572b676d7Smrg } 79672b676d7Smrg } 79772b676d7Smrg break; 79872b676d7Smrg case 768: 79972b676d7Smrg if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) { 80072b676d7Smrg if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 80172b676d7Smrg } 80272b676d7Smrg break; 80372b676d7Smrg case 800: 80472b676d7Smrg if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 80572b676d7Smrg else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; 80672b676d7Smrg break; 80772b676d7Smrg case 960: 80872b676d7Smrg if(VGAEngine == SIS_315_VGA) { 80972b676d7Smrg if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 81072b676d7Smrg if(VDisplay == 600) { 81172b676d7Smrg ModeIndex = ModeIndex_960x600[Depth]; 81272b676d7Smrg } else if(VDisplay == 540) { 81372b676d7Smrg ModeIndex = ModeIndex_960x540[Depth]; 81472b676d7Smrg } 81572b676d7Smrg } 81672b676d7Smrg } 81772b676d7Smrg break; 81872b676d7Smrg case 1024: 81972b676d7Smrg if((VBFlags2 & VB2_30xBLV) || 82072b676d7Smrg (VBFlags & TV_HIVISION) || 82172b676d7Smrg ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 82272b676d7Smrg if(VDisplay == 768) { 82372b676d7Smrg ModeIndex = ModeIndex_1024x768[Depth]; 82472b676d7Smrg } else if(VDisplay == 576) { 82572b676d7Smrg ModeIndex = ModeIndex_1024x576[Depth]; 82672b676d7Smrg } 82772b676d7Smrg } 82872b676d7Smrg break; 82972b676d7Smrg case 1280: 83072b676d7Smrg if(VDisplay == 720) { 83172b676d7Smrg if((VBFlags & TV_HIVISION) || 83272b676d7Smrg ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) { 83372b676d7Smrg ModeIndex = ModeIndex_1280x720[Depth]; 83472b676d7Smrg } 83572b676d7Smrg } else if(VDisplay == 1024) { 83672b676d7Smrg if((VBFlags & TV_HIVISION) || 83772b676d7Smrg ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 83872b676d7Smrg ModeIndex = ModeIndex_1280x1024[Depth]; 83972b676d7Smrg } 84072b676d7Smrg } 84172b676d7Smrg break; 84272b676d7Smrg } 84372b676d7Smrg } 84472b676d7Smrg return ModeIndex; 84572b676d7Smrg} 84672b676d7Smrg 84772b676d7Smrgunsigned short 84872b676d7SmrgSiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth, 84972b676d7Smrg unsigned int VBFlags2) 85072b676d7Smrg{ 85172b676d7Smrg if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0; 85272b676d7Smrg 85372b676d7Smrg if(HDisplay >= 1920) return 0; 85472b676d7Smrg 85572b676d7Smrg switch(HDisplay) 85672b676d7Smrg { 85772b676d7Smrg case 1600: 85872b676d7Smrg if(VDisplay == 1200) { 85972b676d7Smrg if(VGAEngine != SIS_315_VGA) return 0; 86072b676d7Smrg if(!(VBFlags2 & VB2_30xB)) return 0; 86172b676d7Smrg } 86272b676d7Smrg break; 86372b676d7Smrg case 1680: 86472b676d7Smrg if(VDisplay == 1050) { 86572b676d7Smrg if(VGAEngine != SIS_315_VGA) return 0; 86672b676d7Smrg if(!(VBFlags2 & VB2_30xB)) return 0; 86772b676d7Smrg } 86872b676d7Smrg break; 86972b676d7Smrg } 87072b676d7Smrg 87172b676d7Smrg return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, FALSE, 0, 0); 87272b676d7Smrg} 87372b676d7Smrg 87472b676d7Smrg 87572b676d7Smrg/*********************************************/ 87672b676d7Smrg/* HELPER: SetReg, GetReg */ 87772b676d7Smrg/*********************************************/ 87872b676d7Smrg 87972b676d7Smrgvoid 88072b676d7SmrgSiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data) 88172b676d7Smrg{ 88272b676d7Smrg OutPortByte(port, index); 88372b676d7Smrg OutPortByte(port + 1, data); 88472b676d7Smrg} 88572b676d7Smrg 88672b676d7Smrgvoid 88772b676d7SmrgSiS_SetRegByte(SISIOADDRESS port, unsigned short data) 88872b676d7Smrg{ 88972b676d7Smrg OutPortByte(port, data); 89072b676d7Smrg} 89172b676d7Smrg 89272b676d7Smrgvoid 89372b676d7SmrgSiS_SetRegShort(SISIOADDRESS port, unsigned short data) 89472b676d7Smrg{ 89572b676d7Smrg OutPortWord(port, data); 89672b676d7Smrg} 89772b676d7Smrg 89872b676d7Smrgvoid 89972b676d7SmrgSiS_SetRegLong(SISIOADDRESS port, unsigned int data) 90072b676d7Smrg{ 90172b676d7Smrg OutPortLong(port, data); 90272b676d7Smrg} 90372b676d7Smrg 90472b676d7Smrgunsigned char 90572b676d7SmrgSiS_GetReg(SISIOADDRESS port, unsigned short index) 90672b676d7Smrg{ 90772b676d7Smrg OutPortByte(port, index); 90872b676d7Smrg return(InPortByte(port + 1)); 90972b676d7Smrg} 91072b676d7Smrg 91172b676d7Smrgunsigned char 91272b676d7SmrgSiS_GetRegByte(SISIOADDRESS port) 91372b676d7Smrg{ 91472b676d7Smrg return(InPortByte(port)); 91572b676d7Smrg} 91672b676d7Smrg 91772b676d7Smrgunsigned short 91872b676d7SmrgSiS_GetRegShort(SISIOADDRESS port) 91972b676d7Smrg{ 92072b676d7Smrg return(InPortWord(port)); 92172b676d7Smrg} 92272b676d7Smrg 92372b676d7Smrgunsigned int 92472b676d7SmrgSiS_GetRegLong(SISIOADDRESS port) 92572b676d7Smrg{ 92672b676d7Smrg return(InPortLong(port)); 92772b676d7Smrg} 92872b676d7Smrg 92972b676d7Smrgvoid 93072b676d7SmrgSiS_SetRegANDOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR) 93172b676d7Smrg{ 93272b676d7Smrg unsigned short temp; 93372b676d7Smrg 93472b676d7Smrg temp = SiS_GetReg(Port, Index); 93572b676d7Smrg temp = (temp & (DataAND)) | DataOR; 93672b676d7Smrg SiS_SetReg(Port, Index, temp); 93772b676d7Smrg} 93872b676d7Smrg 93972b676d7Smrgvoid 94072b676d7SmrgSiS_SetRegAND(SISIOADDRESS Port, unsigned short Index, unsigned short DataAND) 94172b676d7Smrg{ 94272b676d7Smrg unsigned short temp; 94372b676d7Smrg 94472b676d7Smrg temp = SiS_GetReg(Port, Index); 94572b676d7Smrg temp &= DataAND; 94672b676d7Smrg SiS_SetReg(Port, Index, temp); 94772b676d7Smrg} 94872b676d7Smrg 94972b676d7Smrgvoid 95072b676d7SmrgSiS_SetRegOR(SISIOADDRESS Port, unsigned short Index, unsigned short DataOR) 95172b676d7Smrg{ 95272b676d7Smrg unsigned short temp; 95372b676d7Smrg 95472b676d7Smrg temp = SiS_GetReg(Port, Index); 95572b676d7Smrg temp |= DataOR; 95672b676d7Smrg SiS_SetReg(Port, Index, temp); 95772b676d7Smrg} 95872b676d7Smrg 95972b676d7Smrg/*********************************************/ 96072b676d7Smrg/* HELPER: DisplayOn, DisplayOff */ 96172b676d7Smrg/*********************************************/ 96272b676d7Smrg 96372b676d7Smrgvoid 96472b676d7SmrgSiS_DisplayOn(struct SiS_Private *SiS_Pr) 96572b676d7Smrg{ 96672b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF); 96772b676d7Smrg} 96872b676d7Smrg 96972b676d7Smrgvoid 97072b676d7SmrgSiS_DisplayOff(struct SiS_Private *SiS_Pr) 97172b676d7Smrg{ 97272b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20); 97372b676d7Smrg} 97472b676d7Smrg 97572b676d7Smrg 97672b676d7Smrg/*********************************************/ 97772b676d7Smrg/* HELPER: Init Port Addresses */ 97872b676d7Smrg/*********************************************/ 97972b676d7Smrg 98072b676d7Smrgvoid 98172b676d7SmrgSiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr) 98272b676d7Smrg{ 98372b676d7Smrg SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; 98472b676d7Smrg SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; 98572b676d7Smrg SiS_Pr->SiS_P3c0 = BaseAddr + 0x10; 98672b676d7Smrg SiS_Pr->SiS_P3ce = BaseAddr + 0x1e; 98772b676d7Smrg SiS_Pr->SiS_P3c2 = BaseAddr + 0x12; 98872b676d7Smrg SiS_Pr->SiS_P3ca = BaseAddr + 0x1a; 98972b676d7Smrg SiS_Pr->SiS_P3c6 = BaseAddr + 0x16; 99072b676d7Smrg SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; 99172b676d7Smrg SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; 99272b676d7Smrg SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; 99372b676d7Smrg SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; 99472b676d7Smrg SiS_Pr->SiS_P3cc = BaseAddr + 0x1c; 99572b676d7Smrg SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; 99672b676d7Smrg SiS_Pr->SiS_P3da = BaseAddr + 0x2a; 99772b676d7Smrg SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; 99872b676d7Smrg SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; 99972b676d7Smrg SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; 100072b676d7Smrg SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; 100172b676d7Smrg SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; 100272b676d7Smrg SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; 100372b676d7Smrg SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE; 100472b676d7Smrg SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK; 100572b676d7Smrg} 100672b676d7Smrg 100772b676d7Smrg/*********************************************/ 100872b676d7Smrg/* HELPER: GetSysFlags */ 100972b676d7Smrg/*********************************************/ 101072b676d7Smrg 101172b676d7Smrgstatic void 101272b676d7SmrgSiS_GetSysFlags(struct SiS_Private *SiS_Pr) 101372b676d7Smrg{ 101472b676d7Smrg unsigned char cr5f, temp1, temp2; 101572b676d7Smrg 101672b676d7Smrg /* 661 and newer: NEVER write non-zero to SR11[7:4] */ 101772b676d7Smrg /* (SR11 is used for DDC and in enable/disablebridge) */ 101872b676d7Smrg SiS_Pr->SiS_SensibleSR11 = FALSE; 101972b676d7Smrg SiS_Pr->SiS_MyCR63 = 0x63; 102072b676d7Smrg if(SiS_Pr->ChipType >= SIS_330) { 102172b676d7Smrg SiS_Pr->SiS_MyCR63 = 0x53; 102272b676d7Smrg if(SiS_Pr->ChipType >= SIS_661) { 102372b676d7Smrg SiS_Pr->SiS_SensibleSR11 = TRUE; 102472b676d7Smrg } 102572b676d7Smrg } 102672b676d7Smrg 102772b676d7Smrg /* You should use the macros, not these flags directly */ 102872b676d7Smrg 102972b676d7Smrg SiS_Pr->SiS_SysFlags = 0; 103072b676d7Smrg if(SiS_Pr->ChipType == SIS_650) { 103172b676d7Smrg cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0; 103272b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07); 103372b676d7Smrg temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 103472b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8); 103572b676d7Smrg temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 103672b676d7Smrg if((!temp1) || (temp2)) { 103772b676d7Smrg switch(cr5f) { 103872b676d7Smrg case 0x80: 103972b676d7Smrg case 0x90: 104072b676d7Smrg case 0xc0: 104172b676d7Smrg SiS_Pr->SiS_SysFlags |= SF_IsM650; 104272b676d7Smrg break; 104372b676d7Smrg case 0xa0: 104472b676d7Smrg case 0xb0: 104572b676d7Smrg case 0xe0: 104672b676d7Smrg SiS_Pr->SiS_SysFlags |= SF_Is651; 104772b676d7Smrg break; 104872b676d7Smrg } 104972b676d7Smrg } else { 105072b676d7Smrg switch(cr5f) { 105172b676d7Smrg case 0x90: 105272b676d7Smrg temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 105372b676d7Smrg switch(temp1) { 105472b676d7Smrg case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break; 105572b676d7Smrg case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break; 105672b676d7Smrg default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break; 105772b676d7Smrg } 105872b676d7Smrg break; 105972b676d7Smrg case 0xb0: 106072b676d7Smrg SiS_Pr->SiS_SysFlags |= SF_Is652; 106172b676d7Smrg break; 106272b676d7Smrg default: 106372b676d7Smrg SiS_Pr->SiS_SysFlags |= SF_IsM650; 106472b676d7Smrg break; 106572b676d7Smrg } 106672b676d7Smrg } 106772b676d7Smrg } 106872b676d7Smrg 106972b676d7Smrg if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) { 107072b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) { 107172b676d7Smrg SiS_Pr->SiS_SysFlags |= SF_760LFB; 107272b676d7Smrg } 107372b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) { 107472b676d7Smrg SiS_Pr->SiS_SysFlags |= SF_760UMA; 107572b676d7Smrg } 107672b676d7Smrg } 107772b676d7Smrg} 107872b676d7Smrg 107972b676d7Smrg/*********************************************/ 108072b676d7Smrg/* HELPER: Init PCI & Engines */ 108172b676d7Smrg/*********************************************/ 108272b676d7Smrg 108372b676d7Smrgstatic void 108472b676d7SmrgSiSInitPCIetc(struct SiS_Private *SiS_Pr) 108572b676d7Smrg{ 108672b676d7Smrg switch(SiS_Pr->ChipType) { 108772b676d7Smrg#ifdef SIS300 108872b676d7Smrg case SIS_300: 108972b676d7Smrg case SIS_540: 109072b676d7Smrg case SIS_630: 109172b676d7Smrg case SIS_730: 109272b676d7Smrg /* Set - PCI LINEAR ADDRESSING ENABLE (0x80) 109372b676d7Smrg * - RELOCATED VGA IO ENABLED (0x20) 109472b676d7Smrg * - MMIO ENABLED (0x01) 109572b676d7Smrg * Leave other bits untouched. 109672b676d7Smrg */ 109772b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1); 109872b676d7Smrg /* - Enable 2D (0x40) 109972b676d7Smrg * - Enable 3D (0x02) 110072b676d7Smrg * - Enable 3D Vertex command fetch (0x10) ? 110172b676d7Smrg * - Enable 3D command parser (0x08) ? 110272b676d7Smrg */ 110372b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A); 110472b676d7Smrg break; 110572b676d7Smrg#endif 110672b676d7Smrg#ifdef SIS315H 110772b676d7Smrg case SIS_315H: 110872b676d7Smrg case SIS_315: 110972b676d7Smrg case SIS_315PRO: 111072b676d7Smrg case SIS_650: 111172b676d7Smrg case SIS_740: 111272b676d7Smrg case SIS_330: 111372b676d7Smrg case SIS_661: 111472b676d7Smrg case SIS_741: 111572b676d7Smrg case SIS_660: 111672b676d7Smrg case SIS_760: 111772b676d7Smrg case SIS_761: 111872b676d7Smrg case SIS_340: 111972b676d7Smrg case XGI_40: 112072b676d7Smrg /* See above */ 112172b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1); 112272b676d7Smrg /* - Enable 3D G/L transformation engine (0x80) 112372b676d7Smrg * - Enable 2D (0x40) 112472b676d7Smrg * - Enable 3D vertex command fetch (0x10) 112572b676d7Smrg * - Enable 3D command parser (0x08) 112672b676d7Smrg * - Enable 3D (0x02) 112772b676d7Smrg */ 112872b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA); 112972b676d7Smrg break; 113072b676d7Smrg case XGI_20: 113172b676d7Smrg case SIS_550: 113272b676d7Smrg /* See above */ 113372b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1); 113472b676d7Smrg /* No 3D engine ! */ 113572b676d7Smrg /* - Enable 2D (0x40) 113672b676d7Smrg * - disable 3D 113772b676d7Smrg */ 113872b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40); 113972b676d7Smrg break; 114072b676d7Smrg#endif 114172b676d7Smrg default: 114272b676d7Smrg break; 114372b676d7Smrg } 114472b676d7Smrg} 114572b676d7Smrg 114672b676d7Smrg/*********************************************/ 114772b676d7Smrg/* HELPER: SetLVDSetc */ 114872b676d7Smrg/*********************************************/ 114972b676d7Smrg 115072b676d7Smrg#ifdef SIS_LINUX_KERNEL 115172b676d7Smrgstatic 115272b676d7Smrg#endif 115372b676d7Smrgvoid 115472b676d7SmrgSiSSetLVDSetc(struct SiS_Private *SiS_Pr) 115572b676d7Smrg{ 115672b676d7Smrg unsigned short temp; 115772b676d7Smrg 115872b676d7Smrg SiS_Pr->SiS_IF_DEF_LVDS = 0; 115972b676d7Smrg SiS_Pr->SiS_IF_DEF_TRUMPION = 0; 116072b676d7Smrg SiS_Pr->SiS_IF_DEF_CH70xx = 0; 116172b676d7Smrg SiS_Pr->SiS_IF_DEF_CONEX = 0; 116272b676d7Smrg 116372b676d7Smrg SiS_Pr->SiS_ChrontelInit = 0; 116472b676d7Smrg 116572b676d7Smrg if(SiS_Pr->ChipType == XGI_20) return; 116672b676d7Smrg 116772b676d7Smrg /* Check for SiS30x first */ 116872b676d7Smrg temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 116972b676d7Smrg if((temp == 1) || (temp == 2)) return; 117072b676d7Smrg 117172b676d7Smrg switch(SiS_Pr->ChipType) { 117272b676d7Smrg#ifdef SIS300 117372b676d7Smrg case SIS_540: 117472b676d7Smrg case SIS_630: 117572b676d7Smrg case SIS_730: 117672b676d7Smrg temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1; 117772b676d7Smrg if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 117872b676d7Smrg if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1; 117972b676d7Smrg if((temp == 4) || (temp == 5)) { 118072b676d7Smrg /* Save power status (and error check) - UNUSED */ 118172b676d7Smrg SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e); 118272b676d7Smrg SiS_Pr->SiS_IF_DEF_CH70xx = 1; 118372b676d7Smrg } 118472b676d7Smrg break; 118572b676d7Smrg#endif 118672b676d7Smrg#ifdef SIS315H 118772b676d7Smrg case SIS_550: 118872b676d7Smrg case SIS_650: 118972b676d7Smrg case SIS_740: 119072b676d7Smrg case SIS_330: 119172b676d7Smrg temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1; 119272b676d7Smrg if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 119372b676d7Smrg if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2; 119472b676d7Smrg break; 119572b676d7Smrg case SIS_661: 119672b676d7Smrg case SIS_741: 119772b676d7Smrg case SIS_660: 119872b676d7Smrg case SIS_760: 119972b676d7Smrg case SIS_761: 120072b676d7Smrg case SIS_340: 120172b676d7Smrg case XGI_20: 120272b676d7Smrg case XGI_40: 120372b676d7Smrg temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5; 120472b676d7Smrg if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 120572b676d7Smrg if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2; 120672b676d7Smrg if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */ 120772b676d7Smrg break; 120872b676d7Smrg#endif 120972b676d7Smrg default: 121072b676d7Smrg break; 121172b676d7Smrg } 121272b676d7Smrg} 121372b676d7Smrg 121472b676d7Smrg/*********************************************/ 121572b676d7Smrg/* HELPER: Enable DSTN/FSTN */ 121672b676d7Smrg/*********************************************/ 121772b676d7Smrg 121872b676d7Smrgvoid 121972b676d7SmrgSiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable) 122072b676d7Smrg{ 122172b676d7Smrg SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0; 122272b676d7Smrg} 122372b676d7Smrg 122472b676d7Smrgvoid 122572b676d7SmrgSiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable) 122672b676d7Smrg{ 122772b676d7Smrg SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0; 122872b676d7Smrg} 122972b676d7Smrg 123072b676d7Smrg/*********************************************/ 123172b676d7Smrg/* HELPER: Get modeflag */ 123272b676d7Smrg/*********************************************/ 123372b676d7Smrg 123472b676d7Smrgunsigned short 123572b676d7SmrgSiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 123672b676d7Smrg unsigned short ModeIdIndex) 123772b676d7Smrg{ 123872b676d7Smrg if(SiS_Pr->UseCustomMode) { 123972b676d7Smrg return SiS_Pr->CModeFlag; 124072b676d7Smrg } else if(ModeNo <= 0x13) { 124172b676d7Smrg return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 124272b676d7Smrg } else { 124372b676d7Smrg return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 124472b676d7Smrg } 124572b676d7Smrg} 124672b676d7Smrg 124772b676d7Smrg/*********************************************/ 124872b676d7Smrg/* HELPER: Determine ROM usage */ 124972b676d7Smrg/*********************************************/ 125072b676d7Smrg 125172b676d7SmrgBOOLEAN 125272b676d7SmrgSiSDetermineROMLayout661(struct SiS_Private *SiS_Pr) 125372b676d7Smrg{ 125472b676d7Smrg unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 125572b676d7Smrg unsigned short romversoffs, romvmaj = 1, romvmin = 0; 125672b676d7Smrg 125772b676d7Smrg if(SiS_Pr->ChipType >= XGI_20) { 125872b676d7Smrg /* XGI ROMs don't qualify */ 125972b676d7Smrg return FALSE; 126072b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_761) { 126172b676d7Smrg /* I very much assume 761, 340 and newer will use new layout */ 126272b676d7Smrg return TRUE; 126372b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_661) { 126472b676d7Smrg if((ROMAddr[0x1a] == 'N') && 126572b676d7Smrg (ROMAddr[0x1b] == 'e') && 126672b676d7Smrg (ROMAddr[0x1c] == 'w') && 126772b676d7Smrg (ROMAddr[0x1d] == 'V')) { 126872b676d7Smrg return TRUE; 126972b676d7Smrg } 127072b676d7Smrg romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8); 127172b676d7Smrg if(romversoffs) { 127272b676d7Smrg if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) { 127372b676d7Smrg romvmaj = ROMAddr[romversoffs] - '0'; 127472b676d7Smrg romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0'); 127572b676d7Smrg } 127672b676d7Smrg } 127772b676d7Smrg if((romvmaj != 0) || (romvmin >= 92)) { 127872b676d7Smrg return TRUE; 127972b676d7Smrg } 128072b676d7Smrg } else if(IS_SIS650740) { 128172b676d7Smrg if((ROMAddr[0x1a] == 'N') && 128272b676d7Smrg (ROMAddr[0x1b] == 'e') && 128372b676d7Smrg (ROMAddr[0x1c] == 'w') && 128472b676d7Smrg (ROMAddr[0x1d] == 'V')) { 128572b676d7Smrg return TRUE; 128672b676d7Smrg } 128772b676d7Smrg } 128872b676d7Smrg return FALSE; 128972b676d7Smrg} 129072b676d7Smrg 129172b676d7Smrgstatic void 129272b676d7SmrgSiSDetermineROMUsage(struct SiS_Private *SiS_Pr) 129372b676d7Smrg{ 129472b676d7Smrg unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 129572b676d7Smrg unsigned short romptr = 0; 129672b676d7Smrg 129772b676d7Smrg SiS_Pr->SiS_UseROM = FALSE; 129872b676d7Smrg SiS_Pr->SiS_ROMNew = FALSE; 129972b676d7Smrg SiS_Pr->SiS_PWDOffset = 0; 130072b676d7Smrg 130172b676d7Smrg if(SiS_Pr->ChipType >= XGI_20) return; 130272b676d7Smrg 130372b676d7Smrg if((ROMAddr) && (SiS_Pr->UseROM)) { 130472b676d7Smrg if(SiS_Pr->ChipType == SIS_300) { 130572b676d7Smrg /* 300: We check if the code starts below 0x220 by 130672b676d7Smrg * checking the jmp instruction at the beginning 130772b676d7Smrg * of the BIOS image. 130872b676d7Smrg */ 130972b676d7Smrg if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a) 131072b676d7Smrg SiS_Pr->SiS_UseROM = TRUE; 131172b676d7Smrg } else if(SiS_Pr->ChipType < SIS_315H) { 131272b676d7Smrg /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps 131372b676d7Smrg * the others do as well 131472b676d7Smrg */ 131572b676d7Smrg SiS_Pr->SiS_UseROM = TRUE; 131672b676d7Smrg } else { 131772b676d7Smrg /* 315/330 series stick to the standard(s) */ 131872b676d7Smrg SiS_Pr->SiS_UseROM = TRUE; 131972b676d7Smrg if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) { 132072b676d7Smrg SiS_Pr->SiS_EMIOffset = 14; 132172b676d7Smrg SiS_Pr->SiS_PWDOffset = 17; 132272b676d7Smrg SiS_Pr->SiS661LCD2TableSize = 36; 132372b676d7Smrg /* Find out about LCD data table entry size */ 132472b676d7Smrg if((romptr = SISGETROMW(0x0102))) { 132572b676d7Smrg if(ROMAddr[romptr + (32 * 16)] == 0xff) 132672b676d7Smrg SiS_Pr->SiS661LCD2TableSize = 32; 132772b676d7Smrg else if(ROMAddr[romptr + (34 * 16)] == 0xff) 132872b676d7Smrg SiS_Pr->SiS661LCD2TableSize = 34; 132972b676d7Smrg else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94, 2.05.00+ */ 133072b676d7Smrg SiS_Pr->SiS661LCD2TableSize = 36; 133172b676d7Smrg else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */ 133272b676d7Smrg (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00 - <2.05.00 */ 133372b676d7Smrg SiS_Pr->SiS661LCD2TableSize = 38; /* UMC data layout abandoned at 2.05.00 */ 133472b676d7Smrg SiS_Pr->SiS_EMIOffset = 16; 133572b676d7Smrg SiS_Pr->SiS_PWDOffset = 19; 133672b676d7Smrg } 133772b676d7Smrg } 133872b676d7Smrg } 133972b676d7Smrg } 134072b676d7Smrg } 134172b676d7Smrg} 134272b676d7Smrg 134372b676d7Smrg/*********************************************/ 134472b676d7Smrg/* HELPER: SET SEGMENT REGISTERS */ 134572b676d7Smrg/*********************************************/ 134672b676d7Smrg 134772b676d7Smrgstatic void 134872b676d7SmrgSiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) 134972b676d7Smrg{ 135072b676d7Smrg unsigned short temp; 135172b676d7Smrg 135272b676d7Smrg value &= 0x00ff; 135372b676d7Smrg temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0; 135472b676d7Smrg temp |= (value >> 4); 135572b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp); 135672b676d7Smrg temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0; 135772b676d7Smrg temp |= (value & 0x0f); 135872b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp); 135972b676d7Smrg} 136072b676d7Smrg 136172b676d7Smrgstatic void 136272b676d7SmrgSiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) 136372b676d7Smrg{ 136472b676d7Smrg unsigned short temp; 136572b676d7Smrg 136672b676d7Smrg value &= 0x00ff; 136772b676d7Smrg temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f; 136872b676d7Smrg temp |= (value & 0xf0); 136972b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp); 137072b676d7Smrg temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f; 137172b676d7Smrg temp |= (value << 4); 137272b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp); 137372b676d7Smrg} 137472b676d7Smrg 137572b676d7Smrgstatic void 137672b676d7SmrgSiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) 137772b676d7Smrg{ 137872b676d7Smrg SiS_SetSegRegLower(SiS_Pr, value); 137972b676d7Smrg SiS_SetSegRegUpper(SiS_Pr, value); 138072b676d7Smrg} 138172b676d7Smrg 138272b676d7Smrgstatic void 138372b676d7SmrgSiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) 138472b676d7Smrg{ 138572b676d7Smrg SiS_SetSegmentReg(SiS_Pr, 0); 138672b676d7Smrg} 138772b676d7Smrg 138872b676d7Smrgstatic void 138972b676d7SmrgSiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value) 139072b676d7Smrg{ 139172b676d7Smrg unsigned short temp = value >> 8; 139272b676d7Smrg 139372b676d7Smrg temp &= 0x07; 139472b676d7Smrg temp |= (temp << 4); 139572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp); 139672b676d7Smrg SiS_SetSegmentReg(SiS_Pr, value); 139772b676d7Smrg} 139872b676d7Smrg 139972b676d7Smrgstatic void 140072b676d7SmrgSiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) 140172b676d7Smrg{ 140272b676d7Smrg SiS_SetSegmentRegOver(SiS_Pr, 0); 140372b676d7Smrg} 140472b676d7Smrg 140572b676d7Smrgstatic void 140672b676d7SmrgSiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) 140772b676d7Smrg{ 140872b676d7Smrg if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) { 140972b676d7Smrg SiS_ResetSegmentReg(SiS_Pr); 141072b676d7Smrg SiS_ResetSegmentRegOver(SiS_Pr); 141172b676d7Smrg } 141272b676d7Smrg} 141372b676d7Smrg 141472b676d7Smrg/*********************************************/ 141572b676d7Smrg/* HELPER: GetVBType */ 141672b676d7Smrg/*********************************************/ 141772b676d7Smrg 141872b676d7Smrg#ifdef SIS_LINUX_KERNEL 141972b676d7Smrgstatic 142072b676d7Smrg#endif 142172b676d7Smrgvoid 142272b676d7SmrgSiS_GetVBType(struct SiS_Private *SiS_Pr) 142372b676d7Smrg{ 142472b676d7Smrg unsigned short flag = 0, rev = 0, nolcd = 0; 142572b676d7Smrg unsigned short p4_0f, p4_25, p4_27; 142672b676d7Smrg 142772b676d7Smrg SiS_Pr->SiS_VBType = 0; 142872b676d7Smrg 142972b676d7Smrg if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX)) 143072b676d7Smrg return; 143172b676d7Smrg 143272b676d7Smrg if(SiS_Pr->ChipType == XGI_20) 143372b676d7Smrg return; 143472b676d7Smrg 143572b676d7Smrg flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 143672b676d7Smrg 143772b676d7Smrg if(flag > 3) 143872b676d7Smrg return; 143972b676d7Smrg 144072b676d7Smrg rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); 144172b676d7Smrg 144272b676d7Smrg if(flag >= 2) { 144372b676d7Smrg SiS_Pr->SiS_VBType = VB_SIS302B; 144472b676d7Smrg } else if(flag == 1) { 144572b676d7Smrg if(rev >= 0xC0) { 144672b676d7Smrg SiS_Pr->SiS_VBType = VB_SIS301C; 144772b676d7Smrg } else if(rev >= 0xB0) { 144872b676d7Smrg SiS_Pr->SiS_VBType = VB_SIS301B; 144972b676d7Smrg /* Check if 30xB DH version (no LCD support, use Panel Link instead) */ 145072b676d7Smrg nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23); 145172b676d7Smrg if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD; 145272b676d7Smrg } else { 145372b676d7Smrg SiS_Pr->SiS_VBType = VB_SIS301; 145472b676d7Smrg } 145572b676d7Smrg } 145672b676d7Smrg if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) { 145772b676d7Smrg if(rev >= 0xE0) { 145872b676d7Smrg flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39); 145972b676d7Smrg if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV; 146072b676d7Smrg else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */ 146172b676d7Smrg } else if(rev >= 0xD0) { 146272b676d7Smrg SiS_Pr->SiS_VBType = VB_SIS301LV; 146372b676d7Smrg } 146472b676d7Smrg } 146572b676d7Smrg if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) { 146672b676d7Smrg p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f); 146772b676d7Smrg p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25); 146872b676d7Smrg p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27); 146972b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f); 147072b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08); 147172b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd); 147272b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) { 147372b676d7Smrg SiS_Pr->SiS_VBType |= VB_UMC; 147472b676d7Smrg } 147572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27); 147672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25); 147772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f); 147872b676d7Smrg } 147972b676d7Smrg} 148072b676d7Smrg 148172b676d7Smrg/*********************************************/ 148272b676d7Smrg/* HELPER: Check RAM size */ 148372b676d7Smrg/*********************************************/ 148472b676d7Smrg 148572b676d7Smrg#ifdef SIS_LINUX_KERNEL 148672b676d7Smrgstatic BOOLEAN 148772b676d7SmrgSiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 148872b676d7Smrg unsigned short ModeIdIndex) 148972b676d7Smrg{ 149072b676d7Smrg unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024); 149172b676d7Smrg unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 149272b676d7Smrg unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1; 149372b676d7Smrg 149472b676d7Smrg if(!AdapterMemSize) return TRUE; 149572b676d7Smrg 149672b676d7Smrg if(AdapterMemSize < memorysize) return FALSE; 149772b676d7Smrg return TRUE; 149872b676d7Smrg} 149972b676d7Smrg#endif 150072b676d7Smrg 150172b676d7Smrg/*********************************************/ 150272b676d7Smrg/* HELPER: Get DRAM type */ 150372b676d7Smrg/*********************************************/ 150472b676d7Smrg 150572b676d7Smrg#ifdef SIS315H 150672b676d7Smrgstatic unsigned char 150772b676d7SmrgSiS_Get310DRAMType(struct SiS_Private *SiS_Pr) 150872b676d7Smrg{ 150972b676d7Smrg unsigned char data; 151072b676d7Smrg 151172b676d7Smrg if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) { 151272b676d7Smrg data = (*SiS_Pr->pSiS_SoftSetting) & 0x03; 151372b676d7Smrg } else { 151472b676d7Smrg if(SiS_Pr->ChipType >= XGI_20) { 151572b676d7Smrg /* Do I need this? SR17 seems to be zero anyway... */ 151672b676d7Smrg data = 0; 151772b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_340) { 151872b676d7Smrg /* TODO */ 151972b676d7Smrg data = 0; 152072b676d7Smrg } if(SiS_Pr->ChipType >= SIS_661) { 152172b676d7Smrg if(SiS_Pr->SiS_ROMNew) { 152272b676d7Smrg data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6); 152372b676d7Smrg } else { 152472b676d7Smrg data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07; 152572b676d7Smrg } 152672b676d7Smrg } else if(IS_SIS550650740) { 152772b676d7Smrg data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07; 152872b676d7Smrg } else { /* 315, 330 */ 152972b676d7Smrg data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03; 153072b676d7Smrg if(SiS_Pr->ChipType == SIS_330) { 153172b676d7Smrg if(data > 1) { 153272b676d7Smrg switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) { 153372b676d7Smrg case 0x00: data = 1; break; 153472b676d7Smrg case 0x10: data = 3; break; 153572b676d7Smrg case 0x20: data = 3; break; 153672b676d7Smrg case 0x30: data = 2; break; 153772b676d7Smrg } 153872b676d7Smrg } else { 153972b676d7Smrg data = 0; 154072b676d7Smrg } 154172b676d7Smrg } 154272b676d7Smrg } 154372b676d7Smrg } 154472b676d7Smrg 154572b676d7Smrg return data; 154672b676d7Smrg} 154772b676d7Smrg 154872b676d7Smrgstatic unsigned short 154972b676d7SmrgSiS_GetMCLK(struct SiS_Private *SiS_Pr) 155072b676d7Smrg{ 155172b676d7Smrg unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 155272b676d7Smrg unsigned short index; 155372b676d7Smrg 155472b676d7Smrg index = SiS_Get310DRAMType(SiS_Pr); 155572b676d7Smrg if(SiS_Pr->ChipType >= SIS_661) { 155672b676d7Smrg if(SiS_Pr->SiS_ROMNew) { 155772b676d7Smrg return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3)))); 155872b676d7Smrg } 155972b676d7Smrg return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); 156072b676d7Smrg } else if(index >= 4) { 156172b676d7Smrg return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK); 156272b676d7Smrg } else { 156372b676d7Smrg return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); 156472b676d7Smrg } 156572b676d7Smrg} 156672b676d7Smrg#endif 156772b676d7Smrg 156872b676d7Smrg/*********************************************/ 156972b676d7Smrg/* HELPER: ClearBuffer */ 157072b676d7Smrg/*********************************************/ 157172b676d7Smrg 157272b676d7Smrg#ifdef SIS_LINUX_KERNEL 157372b676d7Smrgstatic void 157472b676d7SmrgSiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 157572b676d7Smrg{ 157672b676d7Smrg unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress; 157772b676d7Smrg unsigned int memsize = SiS_Pr->VideoMemorySize; 157872b676d7Smrg unsigned short SISIOMEMTYPE *pBuffer; 157972b676d7Smrg int i; 158072b676d7Smrg 158172b676d7Smrg if(!memaddr || !memsize) return; 158272b676d7Smrg 158372b676d7Smrg if(SiS_Pr->SiS_ModeType >= ModeEGA) { 158472b676d7Smrg if(ModeNo > 0x13) { 158572b676d7Smrg SiS_SetMemory(memaddr, memsize, 0); 158672b676d7Smrg } else { 158772b676d7Smrg pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; 158872b676d7Smrg for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]); 158972b676d7Smrg } 159072b676d7Smrg } else if(SiS_Pr->SiS_ModeType < ModeCGA) { 159172b676d7Smrg pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; 159272b676d7Smrg for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]); 159372b676d7Smrg } else { 159472b676d7Smrg SiS_SetMemory(memaddr, 0x8000, 0); 159572b676d7Smrg } 159672b676d7Smrg} 159772b676d7Smrg#endif 159872b676d7Smrg 159972b676d7Smrg/*********************************************/ 160072b676d7Smrg/* HELPER: SearchModeID */ 160172b676d7Smrg/*********************************************/ 160272b676d7Smrg 160372b676d7SmrgBOOLEAN 160472b676d7SmrgSiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, 160572b676d7Smrg unsigned short *ModeIdIndex) 160672b676d7Smrg{ 160772b676d7Smrg unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO; 160872b676d7Smrg 160972b676d7Smrg if((*ModeNo) <= 0x13) { 161072b676d7Smrg 161172b676d7Smrg if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01; 161272b676d7Smrg 161372b676d7Smrg for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) { 161472b676d7Smrg if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break; 161572b676d7Smrg if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return FALSE; 161672b676d7Smrg } 161772b676d7Smrg 161872b676d7Smrg if((*ModeNo) == 0x07) { 161972b676d7Smrg if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ 162072b676d7Smrg /* else 350 lines */ 162172b676d7Smrg } 162272b676d7Smrg if((*ModeNo) <= 0x03) { 162372b676d7Smrg if(!(VGAINFO & 0x80)) (*ModeIdIndex)++; 162472b676d7Smrg if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ 162572b676d7Smrg /* else 350 lines */ 162672b676d7Smrg } 162772b676d7Smrg /* else 200 lines */ 162872b676d7Smrg 162972b676d7Smrg } else { 163072b676d7Smrg 163172b676d7Smrg for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) { 163272b676d7Smrg if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break; 163372b676d7Smrg if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return FALSE; 163472b676d7Smrg } 163572b676d7Smrg 163672b676d7Smrg } 163772b676d7Smrg return TRUE; 163872b676d7Smrg} 163972b676d7Smrg 164072b676d7Smrg/*********************************************/ 164172b676d7Smrg/* HELPER: GetModePtr */ 164272b676d7Smrg/*********************************************/ 164372b676d7Smrg 164472b676d7Smrgunsigned short 164572b676d7SmrgSiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 164672b676d7Smrg{ 164772b676d7Smrg unsigned short index; 164872b676d7Smrg 164972b676d7Smrg if(ModeNo <= 0x13) { 165072b676d7Smrg index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex; 165172b676d7Smrg } else { 165272b676d7Smrg if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B; 165372b676d7Smrg else index = 0x0F; 165472b676d7Smrg } 165572b676d7Smrg return index; 165672b676d7Smrg} 165772b676d7Smrg 165872b676d7Smrg/*********************************************/ 165972b676d7Smrg/* HELPERS: Get some indices */ 166072b676d7Smrg/*********************************************/ 166172b676d7Smrg 166272b676d7Smrgunsigned short 166372b676d7SmrgSiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide) 166472b676d7Smrg{ 166572b676d7Smrg if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) { 166672b676d7Smrg if(UseWide == 1) { 166772b676d7Smrg return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE; 166872b676d7Smrg } else { 166972b676d7Smrg return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM; 167072b676d7Smrg } 167172b676d7Smrg } else { 167272b676d7Smrg return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK; 167372b676d7Smrg } 167472b676d7Smrg} 167572b676d7Smrg 167672b676d7Smrgunsigned short 167772b676d7SmrgSiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide) 167872b676d7Smrg{ 167972b676d7Smrg if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) { 168072b676d7Smrg if(UseWide == 1) { 168172b676d7Smrg return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE; 168272b676d7Smrg } else { 168372b676d7Smrg return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM; 168472b676d7Smrg } 168572b676d7Smrg } else { 168672b676d7Smrg return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC; 168772b676d7Smrg } 168872b676d7Smrg} 168972b676d7Smrg 169072b676d7Smrg/*********************************************/ 169172b676d7Smrg/* HELPER: LowModeTests */ 169272b676d7Smrg/*********************************************/ 169372b676d7Smrg 169472b676d7Smrgstatic BOOLEAN 169572b676d7SmrgSiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 169672b676d7Smrg{ 169772b676d7Smrg unsigned short temp, temp1, temp2; 169872b676d7Smrg 169972b676d7Smrg if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12)) 170072b676d7Smrg return TRUE; 170172b676d7Smrg temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11); 170272b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80); 170372b676d7Smrg temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); 170472b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55); 170572b676d7Smrg temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); 170672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1); 170772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp); 170872b676d7Smrg if((SiS_Pr->ChipType >= SIS_315H) || 170972b676d7Smrg (SiS_Pr->ChipType == SIS_300)) { 171072b676d7Smrg if(temp2 == 0x55) return FALSE; 171172b676d7Smrg else return TRUE; 171272b676d7Smrg } else { 171372b676d7Smrg if(temp2 != 0x55) return TRUE; 171472b676d7Smrg else { 171572b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 171672b676d7Smrg return FALSE; 171772b676d7Smrg } 171872b676d7Smrg } 171972b676d7Smrg} 172072b676d7Smrg 172172b676d7Smrgstatic void 172272b676d7SmrgSiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 172372b676d7Smrg{ 172472b676d7Smrg if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) { 172572b676d7Smrg SiS_Pr->SiS_SetFlag |= LowModeTests; 172672b676d7Smrg } 172772b676d7Smrg} 172872b676d7Smrg 172972b676d7Smrg/*********************************************/ 173072b676d7Smrg/* HELPER: OPEN/CLOSE CRT1 CRTC */ 173172b676d7Smrg/*********************************************/ 173272b676d7Smrg 173372b676d7Smrgstatic void 173472b676d7SmrgSiS_OpenCRTC(struct SiS_Private *SiS_Pr) 173572b676d7Smrg{ 173672b676d7Smrg if(IS_SIS650) { 173772b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); 173872b676d7Smrg if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20); 173972b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); 174072b676d7Smrg } else if(IS_SIS661741660760) { 174172b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7); 174272b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); 174372b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); 174472b676d7Smrg if(!SiS_Pr->SiS_ROMNew) { 174572b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef); 174672b676d7Smrg } 174772b676d7Smrg } 174872b676d7Smrg} 174972b676d7Smrg 175072b676d7Smrgstatic void 175172b676d7SmrgSiS_CloseCRTC(struct SiS_Private *SiS_Pr) 175272b676d7Smrg{ 175372b676d7Smrg#if 0 /* This locks some CRTC registers. We don't want that. */ 175472b676d7Smrg unsigned short temp1 = 0, temp2 = 0; 175572b676d7Smrg 175672b676d7Smrg if(IS_SIS661741660760) { 175772b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 175872b676d7Smrg temp1 = 0xa0; temp2 = 0x08; 175972b676d7Smrg } 176072b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1); 176172b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2); 176272b676d7Smrg } 176372b676d7Smrg#endif 176472b676d7Smrg} 176572b676d7Smrg 176672b676d7Smrgstatic void 176772b676d7SmrgSiS_HandleCRT1(struct SiS_Private *SiS_Pr) 176872b676d7Smrg{ 176972b676d7Smrg /* Enable CRT1 gating */ 177072b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf); 177172b676d7Smrg#if 0 177272b676d7Smrg if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) { 177372b676d7Smrg if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) || 177472b676d7Smrg (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) { 177572b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40); 177672b676d7Smrg } 177772b676d7Smrg } 177872b676d7Smrg#endif 177972b676d7Smrg} 178072b676d7Smrg 178172b676d7Smrg/*********************************************/ 178272b676d7Smrg/* HELPER: GetColorDepth */ 178372b676d7Smrg/*********************************************/ 178472b676d7Smrg 178572b676d7Smrgunsigned short 178672b676d7SmrgSiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 178772b676d7Smrg unsigned short ModeIdIndex) 178872b676d7Smrg{ 178972b676d7Smrg static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; 179072b676d7Smrg unsigned short modeflag; 179172b676d7Smrg short index; 179272b676d7Smrg 179372b676d7Smrg /* Do NOT check UseCustomMode, will skrew up FIFO */ 179472b676d7Smrg if(ModeNo == 0xfe) { 179572b676d7Smrg modeflag = SiS_Pr->CModeFlag; 179672b676d7Smrg } else if(ModeNo <= 0x13) { 179772b676d7Smrg modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 179872b676d7Smrg } else { 179972b676d7Smrg modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 180072b676d7Smrg } 180172b676d7Smrg 180272b676d7Smrg index = (modeflag & ModeTypeMask) - ModeEGA; 180372b676d7Smrg if(index < 0) index = 0; 180472b676d7Smrg return ColorDepth[index]; 180572b676d7Smrg} 180672b676d7Smrg 180772b676d7Smrg/*********************************************/ 180872b676d7Smrg/* HELPER: GetOffset */ 180972b676d7Smrg/*********************************************/ 181072b676d7Smrg 181172b676d7Smrgunsigned short 181272b676d7SmrgSiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 181372b676d7Smrg unsigned short ModeIdIndex, unsigned short RRTI) 181472b676d7Smrg{ 181572b676d7Smrg unsigned short xres, temp, colordepth, infoflag; 181672b676d7Smrg 181772b676d7Smrg if(SiS_Pr->UseCustomMode) { 181872b676d7Smrg infoflag = SiS_Pr->CInfoFlag; 181972b676d7Smrg xres = SiS_Pr->CHDisplay; 182072b676d7Smrg } else { 182172b676d7Smrg infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag; 182272b676d7Smrg xres = SiS_Pr->SiS_RefIndex[RRTI].XRes; 182372b676d7Smrg } 182472b676d7Smrg 182572b676d7Smrg colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex); 182672b676d7Smrg 182772b676d7Smrg temp = xres / 16; 182872b676d7Smrg if(infoflag & InterlaceMode) temp <<= 1; 182972b676d7Smrg temp *= colordepth; 183072b676d7Smrg if(xres % 16) temp += (colordepth >> 1); 183172b676d7Smrg 183272b676d7Smrg return temp; 183372b676d7Smrg} 183472b676d7Smrg 183572b676d7Smrg/*********************************************/ 183672b676d7Smrg/* SEQ */ 183772b676d7Smrg/*********************************************/ 183872b676d7Smrg 183972b676d7Smrgstatic void 184072b676d7SmrgSiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 184172b676d7Smrg{ 184272b676d7Smrg unsigned char SRdata; 184372b676d7Smrg int i; 184472b676d7Smrg 184572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); 184672b676d7Smrg 184772b676d7Smrg /* or "display off" */ 184872b676d7Smrg SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; 184972b676d7Smrg 185072b676d7Smrg /* determine whether to force x8 dotclock */ 185172b676d7Smrg if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) { 185272b676d7Smrg 185372b676d7Smrg if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { 185472b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) SRdata |= 0x01; 185572b676d7Smrg } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01; 185672b676d7Smrg 185772b676d7Smrg } 185872b676d7Smrg 185972b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata); 186072b676d7Smrg 186172b676d7Smrg for(i = 2; i <= 4; i++) { 186272b676d7Smrg SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1]; 186372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata); 186472b676d7Smrg } 186572b676d7Smrg} 186672b676d7Smrg 186772b676d7Smrg/*********************************************/ 186872b676d7Smrg/* MISC */ 186972b676d7Smrg/*********************************************/ 187072b676d7Smrg 187172b676d7Smrgstatic void 187272b676d7SmrgSiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 187372b676d7Smrg{ 187472b676d7Smrg unsigned char Miscdata; 187572b676d7Smrg 187672b676d7Smrg Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; 187772b676d7Smrg 187872b676d7Smrg if(SiS_Pr->ChipType < SIS_661) { 187972b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 188072b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 188172b676d7Smrg Miscdata |= 0x0C; 188272b676d7Smrg } 188372b676d7Smrg } 188472b676d7Smrg } 188572b676d7Smrg 188672b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata); 188772b676d7Smrg} 188872b676d7Smrg 188972b676d7Smrg/*********************************************/ 189072b676d7Smrg/* CRTC */ 189172b676d7Smrg/*********************************************/ 189272b676d7Smrg 189372b676d7Smrgstatic void 189472b676d7SmrgSiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 189572b676d7Smrg{ 189672b676d7Smrg unsigned char CRTCdata; 189772b676d7Smrg unsigned short i; 189872b676d7Smrg 189972b676d7Smrg /* Unlock CRTC */ 190072b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 190172b676d7Smrg 190272b676d7Smrg for(i = 0; i <= 0x18; i++) { 190372b676d7Smrg CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; 190472b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); 190572b676d7Smrg } 190672b676d7Smrg 190772b676d7Smrg if(SiS_Pr->ChipType >= SIS_661) { 190872b676d7Smrg SiS_OpenCRTC(SiS_Pr); 190972b676d7Smrg for(i = 0x13; i <= 0x14; i++) { 191072b676d7Smrg CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; 191172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); 191272b676d7Smrg } 191372b676d7Smrg } else if( ( (SiS_Pr->ChipType == SIS_630) || 191472b676d7Smrg (SiS_Pr->ChipType == SIS_730) ) && 191572b676d7Smrg (SiS_Pr->ChipRevision >= 0x30) ) { 191672b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 191772b676d7Smrg if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { 191872b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE); 191972b676d7Smrg } 192072b676d7Smrg } 192172b676d7Smrg } 192272b676d7Smrg} 192372b676d7Smrg 192472b676d7Smrg/*********************************************/ 192572b676d7Smrg/* ATT */ 192672b676d7Smrg/*********************************************/ 192772b676d7Smrg 192872b676d7Smrgstatic void 192972b676d7SmrgSiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 193072b676d7Smrg{ 193172b676d7Smrg unsigned char ARdata; 193272b676d7Smrg unsigned short i; 193372b676d7Smrg 193472b676d7Smrg for(i = 0; i <= 0x13; i++) { 193572b676d7Smrg ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; 193672b676d7Smrg 193772b676d7Smrg if(i == 0x13) { 193872b676d7Smrg /* Pixel shift. If screen on LCD or TV is shifted left or right, 193972b676d7Smrg * this might be the cause. 194072b676d7Smrg */ 194172b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 194272b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0; 194372b676d7Smrg } 194472b676d7Smrg if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 194572b676d7Smrg if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 194672b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 194772b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 194872b676d7Smrg } 194972b676d7Smrg } 195072b676d7Smrg } 195172b676d7Smrg if(SiS_Pr->ChipType >= SIS_661) { 195272b676d7Smrg if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { 195372b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 195472b676d7Smrg } 195572b676d7Smrg } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 195672b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 195772b676d7Smrg if(IS_SIS550650740660) { 195872b676d7Smrg /* 315, 330 don't do this */ 195972b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 196072b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 196172b676d7Smrg } else { 196272b676d7Smrg ARdata = 0; 196372b676d7Smrg } 196472b676d7Smrg } 196572b676d7Smrg } else { 196672b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 196772b676d7Smrg } 196872b676d7Smrg } 196972b676d7Smrg } 197072b676d7Smrg SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */ 197172b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */ 197272b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */ 197372b676d7Smrg } 197472b676d7Smrg 197572b676d7Smrg SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */ 197672b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */ 197772b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */ 197872b676d7Smrg 197972b676d7Smrg SiS_GetRegByte(SiS_Pr->SiS_P3da); 198072b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */ 198172b676d7Smrg SiS_GetRegByte(SiS_Pr->SiS_P3da); 198272b676d7Smrg} 198372b676d7Smrg 198472b676d7Smrg/*********************************************/ 198572b676d7Smrg/* GRC */ 198672b676d7Smrg/*********************************************/ 198772b676d7Smrg 198872b676d7Smrgstatic void 198972b676d7SmrgSiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 199072b676d7Smrg{ 199172b676d7Smrg unsigned char GRdata; 199272b676d7Smrg unsigned short i; 199372b676d7Smrg 199472b676d7Smrg for(i = 0; i <= 0x08; i++) { 199572b676d7Smrg GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; 199672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata); 199772b676d7Smrg } 199872b676d7Smrg 199972b676d7Smrg if(SiS_Pr->SiS_ModeType > ModeVGA) { 200072b676d7Smrg /* 256 color disable */ 200172b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF); 200272b676d7Smrg } 200372b676d7Smrg} 200472b676d7Smrg 200572b676d7Smrg/*********************************************/ 200672b676d7Smrg/* CLEAR EXTENDED REGISTERS */ 200772b676d7Smrg/*********************************************/ 200872b676d7Smrg 200972b676d7Smrgstatic void 201072b676d7SmrgSiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 201172b676d7Smrg{ 201272b676d7Smrg unsigned short i; 201372b676d7Smrg 201472b676d7Smrg for(i = 0x0A; i <= 0x0E; i++) { 201572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00); 201672b676d7Smrg } 201772b676d7Smrg 201872b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 201972b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE); 202072b676d7Smrg if(ModeNo <= 0x13) { 202172b676d7Smrg if(ModeNo == 0x06 || ModeNo >= 0x0e) { 202272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20); 202372b676d7Smrg } 202472b676d7Smrg } 202572b676d7Smrg } 202672b676d7Smrg} 202772b676d7Smrg 202872b676d7Smrg/*********************************************/ 202972b676d7Smrg/* RESET VCLK */ 203072b676d7Smrg/*********************************************/ 203172b676d7Smrg 203272b676d7Smrgstatic void 203372b676d7SmrgSiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr) 203472b676d7Smrg{ 203572b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 203672b676d7Smrg if(SiS_Pr->ChipType < SIS_661) { 203772b676d7Smrg if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return; 203872b676d7Smrg } 203972b676d7Smrg } else { 204072b676d7Smrg if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && 204172b676d7Smrg (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) { 204272b676d7Smrg return; 204372b676d7Smrg } 204472b676d7Smrg } 204572b676d7Smrg 204672b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20); 204772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B); 204872b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C); 204972b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 205072b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10); 205172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B); 205272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C); 205372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 205472b676d7Smrg} 205572b676d7Smrg 205672b676d7Smrg/*********************************************/ 205772b676d7Smrg/* SYNC */ 205872b676d7Smrg/*********************************************/ 205972b676d7Smrg 206072b676d7Smrgstatic void 206172b676d7SmrgSiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI) 206272b676d7Smrg{ 206372b676d7Smrg unsigned short sync; 206472b676d7Smrg 206572b676d7Smrg if(SiS_Pr->UseCustomMode) { 206672b676d7Smrg sync = SiS_Pr->CInfoFlag >> 8; 206772b676d7Smrg } else { 206872b676d7Smrg sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8; 206972b676d7Smrg } 207072b676d7Smrg 207172b676d7Smrg sync &= 0xC0; 207272b676d7Smrg sync |= 0x2f; 207372b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync); 207472b676d7Smrg} 207572b676d7Smrg 207672b676d7Smrg/*********************************************/ 207772b676d7Smrg/* CRTC/2 */ 207872b676d7Smrg/*********************************************/ 207972b676d7Smrg 208072b676d7Smrgstatic void 208172b676d7SmrgSiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 208272b676d7Smrg unsigned short ModeIdIndex, unsigned short RRTI) 208372b676d7Smrg{ 208472b676d7Smrg unsigned short temp, i, j, modeflag; 208572b676d7Smrg unsigned char *crt1data = NULL; 208672b676d7Smrg 208772b676d7Smrg modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 208872b676d7Smrg 208972b676d7Smrg if(SiS_Pr->UseCustomMode) { 209072b676d7Smrg 209172b676d7Smrg crt1data = &SiS_Pr->CCRT1CRTC[0]; 209272b676d7Smrg 209372b676d7Smrg } else { 209472b676d7Smrg 209572b676d7Smrg temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide); 209672b676d7Smrg 209772b676d7Smrg /* Alternate for 1600x1200 LCDA */ 209872b676d7Smrg if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57; 209972b676d7Smrg 210072b676d7Smrg crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0]; 210172b676d7Smrg 210272b676d7Smrg } 210372b676d7Smrg 210472b676d7Smrg /* unlock cr0-7 */ 210572b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 210672b676d7Smrg 210772b676d7Smrg for(i = 0, j = 0; i <= 7; i++, j++) { 210872b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]); 210972b676d7Smrg } 211072b676d7Smrg for(j = 0x10; i <= 10; i++, j++) { 211172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]); 211272b676d7Smrg } 211372b676d7Smrg for(j = 0x15; i <= 12; i++, j++) { 211472b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]); 211572b676d7Smrg } 211672b676d7Smrg for(j = 0x0A; i <= 15; i++, j++) { 211772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]); 211872b676d7Smrg } 211972b676d7Smrg 212072b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0); 212172b676d7Smrg 212272b676d7Smrg temp = (crt1data[16] & 0x01) << 5; 212372b676d7Smrg if(modeflag & DoubleScanMode) temp |= 0x80; 212472b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp); 212572b676d7Smrg 212672b676d7Smrg if(SiS_Pr->SiS_ModeType > ModeVGA) { 212772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F); 212872b676d7Smrg } 212972b676d7Smrg 213072b676d7Smrg#ifdef SIS315H 213172b676d7Smrg if(SiS_Pr->ChipType == XGI_20) { 213272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1); 213372b676d7Smrg if(!(temp = crt1data[5] & 0x1f)) { 213472b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb); 213572b676d7Smrg } 213672b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f)); 213772b676d7Smrg temp = (crt1data[16] >> 5) + 3; 213872b676d7Smrg if(temp > 7) temp -= 7; 213972b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5)); 214072b676d7Smrg } 214172b676d7Smrg#endif 214272b676d7Smrg} 214372b676d7Smrg 214472b676d7Smrg/*********************************************/ 214572b676d7Smrg/* OFFSET & PITCH */ 214672b676d7Smrg/*********************************************/ 214772b676d7Smrg/* (partly overruled by SetPitch() in XF86) */ 214872b676d7Smrg/*********************************************/ 214972b676d7Smrg 215072b676d7Smrgstatic void 215172b676d7SmrgSiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 215272b676d7Smrg unsigned short ModeIdIndex, unsigned short RRTI) 215372b676d7Smrg{ 215472b676d7Smrg unsigned short temp, DisplayUnit, infoflag; 215572b676d7Smrg 215672b676d7Smrg if(SiS_Pr->UseCustomMode) { 215772b676d7Smrg infoflag = SiS_Pr->CInfoFlag; 215872b676d7Smrg } else { 215972b676d7Smrg infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag; 216072b676d7Smrg } 216172b676d7Smrg 216272b676d7Smrg DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 216372b676d7Smrg 216472b676d7Smrg temp = (DisplayUnit >> 8) & 0x0f; 216572b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp); 216672b676d7Smrg 216772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF); 216872b676d7Smrg 216972b676d7Smrg if(infoflag & InterlaceMode) DisplayUnit >>= 1; 217072b676d7Smrg 217172b676d7Smrg DisplayUnit <<= 5; 217272b676d7Smrg temp = (DisplayUnit >> 8) + 1; 217372b676d7Smrg if(DisplayUnit & 0xff) temp++; 217472b676d7Smrg if(SiS_Pr->ChipType == XGI_20) { 217572b676d7Smrg if(ModeNo == 0x4a || ModeNo == 0x49) temp--; 217672b676d7Smrg } 217772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp); 217872b676d7Smrg} 217972b676d7Smrg 218072b676d7Smrg/*********************************************/ 218172b676d7Smrg/* VCLK */ 218272b676d7Smrg/*********************************************/ 218372b676d7Smrg 218472b676d7Smrgstatic void 218572b676d7SmrgSiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 218672b676d7Smrg unsigned short ModeIdIndex, unsigned short RRTI) 218772b676d7Smrg{ 218872b676d7Smrg unsigned short index = 0, clka, clkb; 218972b676d7Smrg 219072b676d7Smrg if(SiS_Pr->UseCustomMode) { 219172b676d7Smrg clka = SiS_Pr->CSR2B; 219272b676d7Smrg clkb = SiS_Pr->CSR2C; 219372b676d7Smrg } else { 219472b676d7Smrg index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 219572b676d7Smrg if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && 219672b676d7Smrg (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 219772b676d7Smrg /* Alternate for 1600x1200 LCDA */ 219872b676d7Smrg if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72; 219972b676d7Smrg clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A; 220072b676d7Smrg clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B; 220172b676d7Smrg } else { 220272b676d7Smrg clka = SiS_Pr->SiS_VCLKData[index].SR2B; 220372b676d7Smrg clkb = SiS_Pr->SiS_VCLKData[index].SR2C; 220472b676d7Smrg } 220572b676d7Smrg } 220672b676d7Smrg 220772b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF); 220872b676d7Smrg 220972b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka); 221072b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb); 221172b676d7Smrg 221272b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 221372b676d7Smrg#ifdef SIS315H 221472b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01); 221572b676d7Smrg if(SiS_Pr->ChipType == XGI_20) { 221672b676d7Smrg unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 221772b676d7Smrg if(mf & HalfDCLK) { 221872b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b)); 221972b676d7Smrg clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c); 222072b676d7Smrg clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0); 222172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb); 222272b676d7Smrg } 222372b676d7Smrg } 222472b676d7Smrg#endif 222572b676d7Smrg } else { 222672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 222772b676d7Smrg } 222872b676d7Smrg} 222972b676d7Smrg 223072b676d7Smrg/*********************************************/ 223172b676d7Smrg/* FIFO */ 223272b676d7Smrg/*********************************************/ 223372b676d7Smrg 223472b676d7Smrg#ifdef SIS300 223572b676d7Smrgvoid 223672b676d7SmrgSiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1, 223772b676d7Smrg unsigned short *idx2) 223872b676d7Smrg{ 223972b676d7Smrg unsigned short temp1, temp2; 224072b676d7Smrg static const unsigned char ThTiming[8] = { 224172b676d7Smrg 1, 2, 2, 3, 0, 1, 1, 2 224272b676d7Smrg }; 224372b676d7Smrg 224472b676d7Smrg temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1; 224572b676d7Smrg (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]); 224672b676d7Smrg (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03; 224772b676d7Smrg (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c)); 224872b676d7Smrg (*idx1) <<= 1; 224972b676d7Smrg} 225072b676d7Smrg 225172b676d7Smrgstatic unsigned short 225272b676d7SmrgSiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2) 225372b676d7Smrg{ 225472b676d7Smrg static const unsigned char ThLowA[8 * 3] = { 225572b676d7Smrg 61, 3,52, 5,68, 7,100,11, 225672b676d7Smrg 43, 3,42, 5,54, 7, 78,11, 225772b676d7Smrg 34, 3,37, 5,47, 7, 67,11 225872b676d7Smrg }; 225972b676d7Smrg 226072b676d7Smrg return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]); 226172b676d7Smrg} 226272b676d7Smrg 226372b676d7Smrgunsigned short 226472b676d7SmrgSiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2) 226572b676d7Smrg{ 226672b676d7Smrg static const unsigned char ThLowB[8 * 3] = { 226772b676d7Smrg 81, 4,72, 6,88, 8,120,12, 226872b676d7Smrg 55, 4,54, 6,66, 8, 90,12, 226972b676d7Smrg 42, 4,45, 6,55, 8, 75,12 227072b676d7Smrg }; 227172b676d7Smrg 227272b676d7Smrg return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]); 227372b676d7Smrg} 227472b676d7Smrg 227572b676d7Smrgstatic unsigned short 227672b676d7SmrgSiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK, 227772b676d7Smrg unsigned short colordepth, unsigned short key) 227872b676d7Smrg{ 227972b676d7Smrg unsigned short idx1, idx2; 228072b676d7Smrg unsigned int longtemp = VCLK * colordepth; 228172b676d7Smrg 228272b676d7Smrg SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2); 228372b676d7Smrg 228472b676d7Smrg if(key == 0) { 228572b676d7Smrg longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2); 228672b676d7Smrg } else { 228772b676d7Smrg longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2); 228872b676d7Smrg } 228972b676d7Smrg idx1 = longtemp % (MCLK * 16); 229072b676d7Smrg longtemp /= (MCLK * 16); 229172b676d7Smrg if(idx1) longtemp++; 229272b676d7Smrg return (unsigned short)longtemp; 229372b676d7Smrg} 229472b676d7Smrg 229572b676d7Smrgstatic unsigned short 229672b676d7SmrgSiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK, 229772b676d7Smrg unsigned short colordepth, unsigned short MCLK) 229872b676d7Smrg{ 229972b676d7Smrg unsigned short temp1, temp2; 230072b676d7Smrg 230172b676d7Smrg temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0); 230272b676d7Smrg temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1); 230372b676d7Smrg if(temp1 < 4) temp1 = 4; 230472b676d7Smrg temp1 -= 4; 230572b676d7Smrg if(temp2 < temp1) temp2 = temp1; 230672b676d7Smrg return temp2; 230772b676d7Smrg} 230872b676d7Smrg 230972b676d7Smrgstatic void 231072b676d7SmrgSiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 231172b676d7Smrg unsigned short RefreshRateTableIndex) 231272b676d7Smrg{ 231372b676d7Smrg unsigned short ThresholdLow = 0; 231472b676d7Smrg unsigned short temp, index, VCLK, MCLK, colorth; 231572b676d7Smrg static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 }; 231672b676d7Smrg 231772b676d7Smrg if(ModeNo > 0x13) { 231872b676d7Smrg 231972b676d7Smrg /* Get VCLK */ 232072b676d7Smrg if(SiS_Pr->UseCustomMode) { 232172b676d7Smrg VCLK = SiS_Pr->CSRClock; 232272b676d7Smrg } else { 232372b676d7Smrg index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide); 232472b676d7Smrg VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 232572b676d7Smrg } 232672b676d7Smrg 232772b676d7Smrg /* Get half colordepth */ 232872b676d7Smrg colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)]; 232972b676d7Smrg 233072b676d7Smrg /* Get MCLK */ 233172b676d7Smrg index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07; 233272b676d7Smrg MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; 233372b676d7Smrg 233472b676d7Smrg temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3; 233572b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp); 233672b676d7Smrg 233772b676d7Smrg do { 233872b676d7Smrg ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1; 233972b676d7Smrg if(ThresholdLow < 0x13) break; 234072b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc); 234172b676d7Smrg ThresholdLow = 0x13; 234272b676d7Smrg temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6; 234372b676d7Smrg if(!temp) break; 234472b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6)); 234572b676d7Smrg } while(0); 234672b676d7Smrg 234772b676d7Smrg } else ThresholdLow = 2; 234872b676d7Smrg 234972b676d7Smrg /* Write CRT/CPU threshold low, CRT/Engine threshold high */ 235072b676d7Smrg temp = (ThresholdLow << 4) | 0x0f; 235172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp); 235272b676d7Smrg 235372b676d7Smrg temp = (ThresholdLow & 0x10) << 1; 235472b676d7Smrg if(ModeNo > 0x13) temp |= 0x40; 235572b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp); 235672b676d7Smrg 235772b676d7Smrg /* What is this? */ 235872b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09); 235972b676d7Smrg 236072b676d7Smrg /* Write CRT/CPU threshold high */ 236172b676d7Smrg temp = ThresholdLow + 3; 236272b676d7Smrg if(temp > 0x0f) temp = 0x0f; 236372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp); 236472b676d7Smrg} 236572b676d7Smrg 236672b676d7Smrgunsigned short 236772b676d7SmrgSiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index) 236872b676d7Smrg{ 236972b676d7Smrg static const unsigned char LatencyFactor[] = { 237072b676d7Smrg 97, 88, 86, 79, 77, 0, /* 64 bit BQ=2 */ 237172b676d7Smrg 0, 87, 85, 78, 76, 54, /* 64 bit BQ=1 */ 237272b676d7Smrg 97, 88, 86, 79, 77, 0, /* 128 bit BQ=2 */ 237372b676d7Smrg 0, 79, 77, 70, 68, 48, /* 128 bit BQ=1 */ 237472b676d7Smrg 80, 72, 69, 63, 61, 0, /* 64 bit BQ=2 */ 237572b676d7Smrg 0, 70, 68, 61, 59, 37, /* 64 bit BQ=1 */ 237672b676d7Smrg 86, 77, 75, 68, 66, 0, /* 128 bit BQ=2 */ 237772b676d7Smrg 0, 68, 66, 59, 57, 37 /* 128 bit BQ=1 */ 237872b676d7Smrg }; 237972b676d7Smrg static const unsigned char LatencyFactor730[] = { 238072b676d7Smrg 69, 63, 61, 238172b676d7Smrg 86, 79, 77, 238272b676d7Smrg 103, 96, 94, 238372b676d7Smrg 120,113,111, 238472b676d7Smrg 137,130,128 238572b676d7Smrg }; 238672b676d7Smrg 238772b676d7Smrg if(SiS_Pr->ChipType == SIS_730) { 238872b676d7Smrg return (unsigned short)LatencyFactor730[index]; 238972b676d7Smrg } else { 239072b676d7Smrg return (unsigned short)LatencyFactor[index]; 239172b676d7Smrg } 239272b676d7Smrg} 239372b676d7Smrg 239472b676d7Smrgstatic unsigned short 239572b676d7SmrgSiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key) 239672b676d7Smrg{ 239772b676d7Smrg unsigned short index; 239872b676d7Smrg 239972b676d7Smrg if(SiS_Pr->ChipType == SIS_730) { 240072b676d7Smrg index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6); 240172b676d7Smrg } else { 240272b676d7Smrg index = (key & 0xe0) >> 5; 240372b676d7Smrg if(key & 0x10) index += 6; 240472b676d7Smrg if(!(key & 0x01)) index += 24; 240572b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12; 240672b676d7Smrg } 240772b676d7Smrg return SiS_GetLatencyFactor630(SiS_Pr, index); 240872b676d7Smrg} 240972b676d7Smrg 241072b676d7Smrgstatic void 241172b676d7SmrgSiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 241272b676d7Smrg unsigned short RefreshRateTableIndex) 241372b676d7Smrg{ 241472b676d7Smrg unsigned short ThresholdLow = 0; 241572b676d7Smrg unsigned short i, data, VCLK, MCLK16, colorth = 0; 241672b676d7Smrg unsigned int templ, datal; 241772b676d7Smrg const unsigned char *queuedata = NULL; 241872b676d7Smrg static const unsigned char FQBQData[21] = { 241972b676d7Smrg 0x01,0x21,0x41,0x61,0x81, 242072b676d7Smrg 0x31,0x51,0x71,0x91,0xb1, 242172b676d7Smrg 0x00,0x20,0x40,0x60,0x80, 242272b676d7Smrg 0x30,0x50,0x70,0x90,0xb0, 242372b676d7Smrg 0xff 242472b676d7Smrg }; 242572b676d7Smrg static const unsigned char FQBQData730[16] = { 242672b676d7Smrg 0x34,0x74,0xb4, 242772b676d7Smrg 0x23,0x63,0xa3, 242872b676d7Smrg 0x12,0x52,0x92, 242972b676d7Smrg 0x01,0x41,0x81, 243072b676d7Smrg 0x00,0x40,0x80, 243172b676d7Smrg 0xff 243272b676d7Smrg }; 243372b676d7Smrg static const unsigned short colortharray[6] = { 243472b676d7Smrg 1, 1, 2, 2, 3, 4 243572b676d7Smrg }; 243672b676d7Smrg 243772b676d7Smrg i = 0; 243872b676d7Smrg 243972b676d7Smrg if(ModeNo > 0x13) { 244072b676d7Smrg 244172b676d7Smrg /* Get VCLK */ 244272b676d7Smrg if(SiS_Pr->UseCustomMode) { 244372b676d7Smrg VCLK = SiS_Pr->CSRClock; 244472b676d7Smrg } else { 244572b676d7Smrg data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide); 244672b676d7Smrg VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK; 244772b676d7Smrg } 244872b676d7Smrg 244972b676d7Smrg /* Get MCLK * 16 */ 245072b676d7Smrg data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07; 245172b676d7Smrg MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16; 245272b676d7Smrg 245372b676d7Smrg /* Get half colordepth */ 245472b676d7Smrg colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)]; 245572b676d7Smrg 245672b676d7Smrg if(SiS_Pr->ChipType == SIS_730) { 245772b676d7Smrg queuedata = &FQBQData730[0]; 245872b676d7Smrg } else { 245972b676d7Smrg queuedata = &FQBQData[0]; 246072b676d7Smrg } 246172b676d7Smrg 246272b676d7Smrg do { 246372b676d7Smrg templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth; 246472b676d7Smrg 246572b676d7Smrg datal = templ % MCLK16; 246672b676d7Smrg templ = (templ / MCLK16) + 1; 246772b676d7Smrg if(datal) templ++; 246872b676d7Smrg 246972b676d7Smrg if(templ > 0x13) { 247072b676d7Smrg if(queuedata[i + 1] == 0xFF) { 247172b676d7Smrg ThresholdLow = 0x13; 247272b676d7Smrg break; 247372b676d7Smrg } 247472b676d7Smrg i++; 247572b676d7Smrg } else { 247672b676d7Smrg ThresholdLow = templ; 247772b676d7Smrg break; 247872b676d7Smrg } 247972b676d7Smrg } while(queuedata[i] != 0xFF); 248072b676d7Smrg 248172b676d7Smrg } else { 248272b676d7Smrg 248372b676d7Smrg if(SiS_Pr->ChipType != SIS_730) i = 9; 248472b676d7Smrg ThresholdLow = 0x02; 248572b676d7Smrg 248672b676d7Smrg } 248772b676d7Smrg 248872b676d7Smrg /* Write CRT/CPU threshold low, CRT/Engine threshold high */ 248972b676d7Smrg data = ((ThresholdLow & 0x0f) << 4) | 0x0f; 249072b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data); 249172b676d7Smrg 249272b676d7Smrg data = (ThresholdLow & 0x10) << 1; 249372b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data); 249472b676d7Smrg 249572b676d7Smrg /* What is this? */ 249672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09); 249772b676d7Smrg 249872b676d7Smrg /* Write CRT/CPU threshold high (gap = 3) */ 249972b676d7Smrg data = ThresholdLow + 3; 250072b676d7Smrg if(data > 0x0f) data = 0x0f; 250172b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data); 250272b676d7Smrg 250372b676d7Smrg /* Write foreground and background queue */ 250472b676d7Smrg#ifdef SIS_LINUX_KERNEL 250572b676d7Smrg templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); 250672b676d7Smrg#else 25071fd23544Smrg templ = sis_pci_read_host_bridge_u32(0x50); 250872b676d7Smrg#endif 250972b676d7Smrg 251072b676d7Smrg if(SiS_Pr->ChipType == SIS_730) { 251172b676d7Smrg 251272b676d7Smrg templ &= 0xfffff9ff; 251372b676d7Smrg templ |= ((queuedata[i] & 0xc0) << 3); 251472b676d7Smrg 251572b676d7Smrg } else { 251672b676d7Smrg 251772b676d7Smrg templ &= 0xf0ffffff; 251872b676d7Smrg if( (ModeNo <= 0x13) && 251972b676d7Smrg (SiS_Pr->ChipType == SIS_630) && 252072b676d7Smrg (SiS_Pr->ChipRevision >= 0x30) ) { 252172b676d7Smrg templ |= 0x0b000000; 252272b676d7Smrg } else { 252372b676d7Smrg templ |= ((queuedata[i] & 0xf0) << 20); 252472b676d7Smrg } 252572b676d7Smrg 252672b676d7Smrg } 252772b676d7Smrg 252872b676d7Smrg#ifdef SIS_LINUX_KERNEL 252972b676d7Smrg sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ); 253072b676d7Smrg templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0); 253172b676d7Smrg#else 25321fd23544Smrg sis_pci_write_host_bridge_u32(0x50, templ); 25331fd23544Smrg templ = sis_pci_read_host_bridge_u32(0xA0); 253472b676d7Smrg#endif 253572b676d7Smrg 253672b676d7Smrg /* GUI grant timer (PCI config 0xA3) */ 253772b676d7Smrg if(SiS_Pr->ChipType == SIS_730) { 253872b676d7Smrg 253972b676d7Smrg templ &= 0x00ffffff; 254072b676d7Smrg datal = queuedata[i] << 8; 254172b676d7Smrg templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20); 254272b676d7Smrg 254372b676d7Smrg } else { 254472b676d7Smrg 254572b676d7Smrg templ &= 0xf0ffffff; 254672b676d7Smrg templ |= ((queuedata[i] & 0x0f) << 24); 254772b676d7Smrg 254872b676d7Smrg } 254972b676d7Smrg 255072b676d7Smrg#ifdef SIS_LINUX_KERNEL 255172b676d7Smrg sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ); 255272b676d7Smrg#else 25531fd23544Smrg sis_pci_write_host_bridge_u32(0xA0, templ); 255472b676d7Smrg#endif 255572b676d7Smrg} 255672b676d7Smrg#endif /* SIS300 */ 255772b676d7Smrg 255872b676d7Smrg#ifdef SIS315H 255972b676d7Smrgstatic void 256072b676d7SmrgSiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 256172b676d7Smrg{ 256272b676d7Smrg unsigned short modeflag; 256372b676d7Smrg 256472b676d7Smrg /* disable auto-threshold */ 256572b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE); 256672b676d7Smrg 256772b676d7Smrg modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 256872b676d7Smrg 256972b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE); 257072b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0); 257172b676d7Smrg if(ModeNo > 0x13) { 257272b676d7Smrg if(SiS_Pr->ChipType >= XGI_20) { 257372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 257472b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 257572b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_661) { 257672b676d7Smrg if(!(modeflag & HalfDCLK)) { 257772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 257872b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 257972b676d7Smrg } 258072b676d7Smrg } else { 258172b676d7Smrg if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) { 258272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 258372b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 258472b676d7Smrg } 258572b676d7Smrg } 258672b676d7Smrg } 258772b676d7Smrg} 258872b676d7Smrg#endif 258972b676d7Smrg 259072b676d7Smrg/*********************************************/ 259172b676d7Smrg/* MODE REGISTERS */ 259272b676d7Smrg/*********************************************/ 259372b676d7Smrg 259472b676d7Smrgstatic void 259572b676d7SmrgSiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 259672b676d7Smrg unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex) 259772b676d7Smrg{ 259872b676d7Smrg unsigned short data = 0, VCLK = 0, index = 0; 259972b676d7Smrg 260072b676d7Smrg if(ModeNo > 0x13) { 260172b676d7Smrg if(SiS_Pr->UseCustomMode) { 260272b676d7Smrg VCLK = SiS_Pr->CSRClock; 260372b676d7Smrg } else { 260472b676d7Smrg index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 260572b676d7Smrg VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 260672b676d7Smrg } 260772b676d7Smrg } 260872b676d7Smrg 260972b676d7Smrg if(SiS_Pr->ChipType < SIS_315H) { 261072b676d7Smrg#ifdef SIS300 261172b676d7Smrg if(VCLK > 150) data |= 0x80; 261272b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data); 261372b676d7Smrg 261472b676d7Smrg data = 0x00; 261572b676d7Smrg if(VCLK >= 150) data |= 0x08; 261672b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data); 261772b676d7Smrg#endif 261872b676d7Smrg } else if(SiS_Pr->ChipType < XGI_20) { 261972b676d7Smrg#ifdef SIS315H 262072b676d7Smrg if(VCLK >= 166) data |= 0x0c; 262172b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); 262272b676d7Smrg 262372b676d7Smrg if(VCLK >= 166) { 262472b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7); 262572b676d7Smrg } 262672b676d7Smrg#endif 262772b676d7Smrg } else { 262872b676d7Smrg#ifdef SIS315H 262972b676d7Smrg if(VCLK >= 200) data |= 0x0c; 263072b676d7Smrg if(SiS_Pr->ChipType == XGI_20) data &= ~0x04; 263172b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); 263272b676d7Smrg if(SiS_Pr->ChipType != XGI_20) { 263372b676d7Smrg data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7; 263472b676d7Smrg if(VCLK < 200) data |= 0x10; 263572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data); 263672b676d7Smrg } 263772b676d7Smrg#endif 263872b676d7Smrg } 263972b676d7Smrg 264072b676d7Smrg /* DAC speed */ 264172b676d7Smrg if(SiS_Pr->ChipType >= SIS_661) { 264272b676d7Smrg 264372b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10); 264472b676d7Smrg 264572b676d7Smrg } else { 264672b676d7Smrg 264772b676d7Smrg data = 0x03; 264872b676d7Smrg if(VCLK >= 260) data = 0x00; 264972b676d7Smrg else if(VCLK >= 160) data = 0x01; 265072b676d7Smrg else if(VCLK >= 135) data = 0x02; 265172b676d7Smrg 265272b676d7Smrg if(SiS_Pr->ChipType == SIS_540) { 265372b676d7Smrg if((VCLK == 203) || (VCLK < 234)) data = 0x02; 265472b676d7Smrg } 265572b676d7Smrg 265672b676d7Smrg if(SiS_Pr->ChipType < SIS_315H) { 265772b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data); 265872b676d7Smrg } else { 265972b676d7Smrg if(SiS_Pr->ChipType > SIS_315PRO) { 266072b676d7Smrg if(ModeNo > 0x13) data &= 0xfc; 266172b676d7Smrg } 266272b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data); 266372b676d7Smrg } 266472b676d7Smrg 266572b676d7Smrg } 266672b676d7Smrg} 266772b676d7Smrg 266872b676d7Smrgstatic void 266972b676d7SmrgSiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 267072b676d7Smrg unsigned short ModeIdIndex, unsigned short RRTI) 267172b676d7Smrg{ 267274fcc364Smrg unsigned short data, infoflag = 0, modeflag; 267372b676d7Smrg#ifdef SIS315H 267472b676d7Smrg unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 267572b676d7Smrg unsigned short data2, data3; 267672b676d7Smrg#endif 267772b676d7Smrg 267872b676d7Smrg modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 267972b676d7Smrg 268072b676d7Smrg if(SiS_Pr->UseCustomMode) { 268172b676d7Smrg infoflag = SiS_Pr->CInfoFlag; 268272b676d7Smrg } else { 268372b676d7Smrg if(ModeNo > 0x13) { 268472b676d7Smrg infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag; 268572b676d7Smrg } 268672b676d7Smrg } 268772b676d7Smrg 268872b676d7Smrg /* Disable DPMS */ 268972b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); 269072b676d7Smrg 269172b676d7Smrg data = 0; 269272b676d7Smrg if(ModeNo > 0x13) { 269372b676d7Smrg if(SiS_Pr->SiS_ModeType > ModeEGA) { 269472b676d7Smrg data |= 0x02; 269572b676d7Smrg data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); 269672b676d7Smrg } 269772b676d7Smrg if(infoflag & InterlaceMode) data |= 0x20; 269872b676d7Smrg } 269972b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data); 270072b676d7Smrg 270172b676d7Smrg if(SiS_Pr->ChipType != SIS_300) { 270272b676d7Smrg data = 0; 270372b676d7Smrg if(infoflag & InterlaceMode) { 270472b676d7Smrg /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ 270572b676d7Smrg int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) | 270672b676d7Smrg ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3; 270772b676d7Smrg int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) | 270872b676d7Smrg ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5; 270972b676d7Smrg data = hrs - (hto >> 1) + 3; 271072b676d7Smrg } 271172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data); 271272b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03)); 271372b676d7Smrg } 271472b676d7Smrg 271572b676d7Smrg if(modeflag & HalfDCLK) { 271672b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08); 271772b676d7Smrg } 271872b676d7Smrg 271972b676d7Smrg data = 0; 272072b676d7Smrg if(modeflag & LineCompareOff) data = 0x08; 272172b676d7Smrg if(SiS_Pr->ChipType == SIS_300) { 272272b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data); 272372b676d7Smrg } else { 272472b676d7Smrg if(SiS_Pr->ChipType >= XGI_20) data |= 0x20; 272572b676d7Smrg if(SiS_Pr->SiS_ModeType == ModeEGA) { 272672b676d7Smrg if(ModeNo > 0x13) { 272772b676d7Smrg data |= 0x40; 272872b676d7Smrg } 272972b676d7Smrg } 273072b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data); 273172b676d7Smrg } 273272b676d7Smrg 273372b676d7Smrg#ifdef SIS315H 273472b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 273572b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb); 273672b676d7Smrg } 273772b676d7Smrg 273872b676d7Smrg if(SiS_Pr->ChipType == SIS_315PRO) { 273972b676d7Smrg 274072b676d7Smrg data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)]; 274172b676d7Smrg if(SiS_Pr->SiS_ModeType == ModeText) { 274272b676d7Smrg data &= 0xc7; 274372b676d7Smrg } else { 274472b676d7Smrg data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1; 274572b676d7Smrg if(infoflag & InterlaceMode) data2 >>= 1; 274672b676d7Smrg data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1; 274772b676d7Smrg if(data3) data2 /= data3; 274872b676d7Smrg if(data2 >= 0x50) { 274972b676d7Smrg data &= 0x0f; 275072b676d7Smrg data |= 0x50; 275172b676d7Smrg } 275272b676d7Smrg } 275372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data); 275472b676d7Smrg 275572b676d7Smrg } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) { 275672b676d7Smrg 275772b676d7Smrg data = SiS_Get310DRAMType(SiS_Pr); 275872b676d7Smrg if(SiS_Pr->ChipType == SIS_330) { 275972b676d7Smrg data = SiS_Pr->SiS_SR15[(2 * 4) + data]; 276072b676d7Smrg } else { 276172b676d7Smrg if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6]; 276272b676d7Smrg else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data]; 276372b676d7Smrg else data = 0xba; 276472b676d7Smrg } 276572b676d7Smrg if(SiS_Pr->SiS_ModeType <= ModeEGA) { 276672b676d7Smrg data &= 0xc7; 276772b676d7Smrg } else { 276872b676d7Smrg if(SiS_Pr->UseCustomMode) { 276972b676d7Smrg data2 = SiS_Pr->CSRClock; 277072b676d7Smrg } else { 277172b676d7Smrg data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 277272b676d7Smrg data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK; 277372b676d7Smrg } 277472b676d7Smrg 277572b676d7Smrg data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1; 277672b676d7Smrg if(data3) data2 *= data3; 277772b676d7Smrg 277872b676d7Smrg data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2; 277972b676d7Smrg 278072b676d7Smrg if(SiS_Pr->ChipType == SIS_330) { 278172b676d7Smrg if(SiS_Pr->SiS_ModeType != Mode16Bpp) { 278272b676d7Smrg if (data2 >= 0x19c) data = 0xba; 278372b676d7Smrg else if(data2 >= 0x140) data = 0x7a; 278472b676d7Smrg else if(data2 >= 0x101) data = 0x3a; 278572b676d7Smrg else if(data2 >= 0xf5) data = 0x32; 278672b676d7Smrg else if(data2 >= 0xe2) data = 0x2a; 278772b676d7Smrg else if(data2 >= 0xc4) data = 0x22; 278872b676d7Smrg else if(data2 >= 0xac) data = 0x1a; 278972b676d7Smrg else if(data2 >= 0x9e) data = 0x12; 279072b676d7Smrg else if(data2 >= 0x8e) data = 0x0a; 279172b676d7Smrg else data = 0x02; 279272b676d7Smrg } else { 279372b676d7Smrg if(data2 >= 0x127) data = 0xba; 279472b676d7Smrg else data = 0x7a; 279572b676d7Smrg } 279672b676d7Smrg } else { /* 76x+LFB */ 279772b676d7Smrg if (data2 >= 0x190) data = 0xba; 279872b676d7Smrg else if(data2 >= 0xff) data = 0x7a; 279972b676d7Smrg else if(data2 >= 0xd3) data = 0x3a; 280072b676d7Smrg else if(data2 >= 0xa9) data = 0x1a; 280172b676d7Smrg else if(data2 >= 0x93) data = 0x0a; 280272b676d7Smrg else data = 0x02; 280372b676d7Smrg } 280472b676d7Smrg } 280572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data); 280672b676d7Smrg 280772b676d7Smrg } 280872b676d7Smrg /* XGI: Nothing. */ 280972b676d7Smrg /* TODO: Check SiS340 */ 281072b676d7Smrg#endif 281172b676d7Smrg 281272b676d7Smrg data = 0x60; 281372b676d7Smrg if(SiS_Pr->SiS_ModeType != ModeText) { 281472b676d7Smrg data ^= 0x60; 281572b676d7Smrg if(SiS_Pr->SiS_ModeType != ModeEGA) { 281672b676d7Smrg data ^= 0xA0; 281772b676d7Smrg } 281872b676d7Smrg } 281972b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data); 282072b676d7Smrg 282172b676d7Smrg SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex); 282272b676d7Smrg 282372b676d7Smrg#ifdef SIS315H 282472b676d7Smrg if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) || 282572b676d7Smrg (SiS_Pr->ChipType == XGI_40)) { 282672b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { 282772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c); 282872b676d7Smrg } else { 282972b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c); 283072b676d7Smrg } 283172b676d7Smrg } else if(SiS_Pr->ChipType == XGI_20) { 283272b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { 283372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33); 283472b676d7Smrg } else { 283572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73); 283672b676d7Smrg } 283772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02); 283872b676d7Smrg } 283972b676d7Smrg#endif 284072b676d7Smrg} 284172b676d7Smrg 284272b676d7Smrg#ifdef SIS315H 284372b676d7Smrgstatic void 284472b676d7SmrgSiS_SetupDualChip(struct SiS_Private *SiS_Pr) 284572b676d7Smrg{ 284672b676d7Smrg#if 0 284772b676d7Smrg /* TODO: Find out about IOAddress2 */ 284872b676d7Smrg SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12; 284972b676d7Smrg SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14; 285072b676d7Smrg SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e; 285172b676d7Smrg int i; 285272b676d7Smrg 285372b676d7Smrg if((SiS_Pr->ChipRevision != 0) || 285472b676d7Smrg (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04))) 285572b676d7Smrg return; 285672b676d7Smrg 285772b676d7Smrg for(i = 0; i <= 4; i++) { /* SR00 - SR04 */ 285872b676d7Smrg SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i)); 285972b676d7Smrg } 286072b676d7Smrg for(i = 0; i <= 8; i++) { /* GR00 - GR08 */ 286172b676d7Smrg SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i)); 286272b676d7Smrg } 286372b676d7Smrg SiS_SetReg(P2_3c4,0x05,0x86); 286472b676d7Smrg SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06)); /* SR06 */ 286572b676d7Smrg SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21)); /* SR21 */ 286672b676d7Smrg SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc)); /* MISC */ 286772b676d7Smrg SiS_SetReg(P2_3c4,0x05,0x00); 286872b676d7Smrg#endif 286972b676d7Smrg} 287072b676d7Smrg#endif 287172b676d7Smrg 287272b676d7Smrg/*********************************************/ 287372b676d7Smrg/* LOAD DAC */ 287472b676d7Smrg/*********************************************/ 287572b676d7Smrg 287672b676d7Smrgstatic void 287772b676d7SmrgSiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag, 287872b676d7Smrg unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh) 287972b676d7Smrg{ 288072b676d7Smrg unsigned short d1, d2, d3; 288172b676d7Smrg 288272b676d7Smrg switch(dl) { 288372b676d7Smrg case 0: d1 = dh; d2 = ah; d3 = al; break; 288472b676d7Smrg case 1: d1 = ah; d2 = al; d3 = dh; break; 288572b676d7Smrg default: d1 = al; d2 = dh; d3 = ah; 288672b676d7Smrg } 288772b676d7Smrg SiS_SetRegByte(DACData, (d1 << shiftflag)); 288872b676d7Smrg SiS_SetRegByte(DACData, (d2 << shiftflag)); 288972b676d7Smrg SiS_SetRegByte(DACData, (d3 << shiftflag)); 289072b676d7Smrg} 289172b676d7Smrg 289272b676d7Smrgvoid 289372b676d7SmrgSiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 289472b676d7Smrg{ 289572b676d7Smrg unsigned short data, data2, time, i, j, k, m, n, o; 289672b676d7Smrg unsigned short si, di, bx, sf; 289772b676d7Smrg SISIOADDRESS DACAddr, DACData; 289872b676d7Smrg const unsigned char *table = NULL; 289972b676d7Smrg 290072b676d7Smrg data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag; 290172b676d7Smrg 290272b676d7Smrg j = time = 64; 290372b676d7Smrg if(data == 0x00) table = SiS_MDA_DAC; 290472b676d7Smrg else if(data == 0x08) table = SiS_CGA_DAC; 290572b676d7Smrg else if(data == 0x10) table = SiS_EGA_DAC; 290672b676d7Smrg else if(data == 0x18) { 290772b676d7Smrg j = 16; 290872b676d7Smrg time = 256; 290972b676d7Smrg table = SiS_VGA_DAC; 291072b676d7Smrg } 291172b676d7Smrg 291272b676d7Smrg if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */ 291372b676d7Smrg (SiS_Pr->SiS_VBType & VB_NoLCD) ) || 291472b676d7Smrg (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */ 291572b676d7Smrg (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */ 291672b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 291772b676d7Smrg DACAddr = SiS_Pr->SiS_P3c8; 291872b676d7Smrg DACData = SiS_Pr->SiS_P3c9; 291972b676d7Smrg sf = 0; 292072b676d7Smrg } else { 292172b676d7Smrg DACAddr = SiS_Pr->SiS_Part5Port; 292272b676d7Smrg DACData = SiS_Pr->SiS_Part5Port + 1; 292372b676d7Smrg sf = 2; 292472b676d7Smrg } 292572b676d7Smrg 292672b676d7Smrg SiS_SetRegByte(DACAddr,0x00); 292772b676d7Smrg 292872b676d7Smrg for(i = 0; i < j; i++) { 292972b676d7Smrg data = table[i]; 293072b676d7Smrg for(k = 0; k < 3; k++) { 293172b676d7Smrg data2 = 0; 293272b676d7Smrg if(data & 0x01) data2 += 0x2A; 293372b676d7Smrg if(data & 0x02) data2 += 0x15; 293472b676d7Smrg SiS_SetRegByte(DACData, (data2 << sf)); 293572b676d7Smrg data >>= 2; 293672b676d7Smrg } 293772b676d7Smrg } 293872b676d7Smrg 293972b676d7Smrg if(time == 256) { 294072b676d7Smrg for(i = 16; i < 32; i++) { 294172b676d7Smrg data = table[i] << sf; 294272b676d7Smrg for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data); 294372b676d7Smrg } 294472b676d7Smrg si = 32; 294572b676d7Smrg for(m = 0; m < 9; m++) { 294672b676d7Smrg di = si; 294772b676d7Smrg bx = si + 4; 294872b676d7Smrg for(n = 0; n < 3; n++) { 294972b676d7Smrg for(o = 0; o < 5; o++) { 295072b676d7Smrg SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]); 295172b676d7Smrg si++; 295272b676d7Smrg } 295372b676d7Smrg si -= 2; 295472b676d7Smrg for(o = 0; o < 3; o++) { 295572b676d7Smrg SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]); 295672b676d7Smrg si--; 295772b676d7Smrg } 295872b676d7Smrg } /* for n < 3 */ 295972b676d7Smrg si += 5; 296072b676d7Smrg } /* for m < 9 */ 296172b676d7Smrg } 296272b676d7Smrg} 296372b676d7Smrg 296472b676d7Smrg/*********************************************/ 296572b676d7Smrg/* SET CRT1 REGISTER GROUP */ 296672b676d7Smrg/*********************************************/ 296772b676d7Smrg 296872b676d7Smrgstatic void 296972b676d7SmrgSiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 297072b676d7Smrg{ 297172b676d7Smrg unsigned short StandTableIndex, RefreshRateTableIndex; 297272b676d7Smrg 297372b676d7Smrg SiS_Pr->SiS_CRT1Mode = ModeNo; 297472b676d7Smrg 297572b676d7Smrg StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex); 297672b676d7Smrg 297772b676d7Smrg if(SiS_Pr->SiS_SetFlag & LowModeTests) { 297872b676d7Smrg if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) { 297972b676d7Smrg SiS_DisableBridge(SiS_Pr); 298072b676d7Smrg } 298172b676d7Smrg } 298272b676d7Smrg 298372b676d7Smrg SiS_ResetSegmentRegisters(SiS_Pr); 298472b676d7Smrg 298572b676d7Smrg SiS_SetSeqRegs(SiS_Pr, StandTableIndex); 298672b676d7Smrg SiS_SetMiscRegs(SiS_Pr, StandTableIndex); 298772b676d7Smrg SiS_SetCRTCRegs(SiS_Pr, StandTableIndex); 298872b676d7Smrg SiS_SetATTRegs(SiS_Pr, StandTableIndex); 298972b676d7Smrg SiS_SetGRCRegs(SiS_Pr, StandTableIndex); 299072b676d7Smrg SiS_ClearExt1Regs(SiS_Pr, ModeNo); 299172b676d7Smrg SiS_ResetCRT1VCLK(SiS_Pr); 299272b676d7Smrg 299372b676d7Smrg SiS_Pr->SiS_SelectCRT2Rate = 0; 299472b676d7Smrg SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 299572b676d7Smrg 299672b676d7Smrg#ifdef SIS_XORG_XF86 299772b676d7Smrg xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n", 299872b676d7Smrg SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo); 299972b676d7Smrg#endif 300072b676d7Smrg 300172b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { 300272b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 300372b676d7Smrg SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 300472b676d7Smrg } 300572b676d7Smrg } 300672b676d7Smrg 300772b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 300872b676d7Smrg SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 300972b676d7Smrg } 301072b676d7Smrg 301172b676d7Smrg RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex); 301272b676d7Smrg 301372b676d7Smrg if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 301472b676d7Smrg SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2; 301572b676d7Smrg } 301672b676d7Smrg 301772b676d7Smrg if(RefreshRateTableIndex != 0xFFFF) { 301872b676d7Smrg SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex); 301972b676d7Smrg SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 302072b676d7Smrg SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 302172b676d7Smrg SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 302272b676d7Smrg } 302372b676d7Smrg 302472b676d7Smrg switch(SiS_Pr->ChipType) { 302572b676d7Smrg#ifdef SIS300 302672b676d7Smrg case SIS_300: 302772b676d7Smrg SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex); 302872b676d7Smrg break; 302972b676d7Smrg case SIS_540: 303072b676d7Smrg case SIS_630: 303172b676d7Smrg case SIS_730: 303272b676d7Smrg SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex); 303372b676d7Smrg break; 303472b676d7Smrg#endif 303572b676d7Smrg default: 303672b676d7Smrg#ifdef SIS315H 303772b676d7Smrg if(SiS_Pr->ChipType == XGI_20) { 303872b676d7Smrg unsigned char sr2b = 0, sr2c = 0; 303972b676d7Smrg switch(ModeNo) { 304072b676d7Smrg case 0x00: 304172b676d7Smrg case 0x01: sr2b = 0x4e; sr2c = 0xe9; break; 304272b676d7Smrg case 0x04: 304372b676d7Smrg case 0x05: 304472b676d7Smrg case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break; 304572b676d7Smrg } 304672b676d7Smrg if(sr2b) { 304772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b); 304872b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c); 304972b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c)); 305072b676d7Smrg } 305172b676d7Smrg } 305272b676d7Smrg SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex); 305372b676d7Smrg#endif 305472b676d7Smrg break; 305572b676d7Smrg } 305672b676d7Smrg 305772b676d7Smrg SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 305872b676d7Smrg 305972b676d7Smrg#ifdef SIS315H 306072b676d7Smrg if(SiS_Pr->ChipType == XGI_40) { 306172b676d7Smrg SiS_SetupDualChip(SiS_Pr); 306272b676d7Smrg } 306372b676d7Smrg#endif 306472b676d7Smrg 306572b676d7Smrg SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); 306672b676d7Smrg 306772b676d7Smrg#ifdef SIS_LINUX_KERNEL 306872b676d7Smrg if(SiS_Pr->SiS_flag_clearbuffer) { 306972b676d7Smrg SiS_ClearBuffer(SiS_Pr, ModeNo); 307072b676d7Smrg } 307172b676d7Smrg#endif 307272b676d7Smrg 307372b676d7Smrg if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) { 307472b676d7Smrg SiS_WaitRetrace1(SiS_Pr); 307572b676d7Smrg SiS_DisplayOn(SiS_Pr); 307672b676d7Smrg } 307772b676d7Smrg} 307872b676d7Smrg 307972b676d7Smrg/*********************************************/ 308072b676d7Smrg/* HELPER: VIDEO BRIDGE PROG CLK */ 308172b676d7Smrg/*********************************************/ 308272b676d7Smrg 308372b676d7Smrgstatic void 308472b676d7SmrgSiS_InitVB(struct SiS_Private *SiS_Pr) 308572b676d7Smrg{ 308672b676d7Smrg unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 308772b676d7Smrg 308872b676d7Smrg SiS_Pr->Init_P4_0E = 0; 308972b676d7Smrg if(SiS_Pr->SiS_ROMNew) { 309072b676d7Smrg SiS_Pr->Init_P4_0E = ROMAddr[0x82]; 309172b676d7Smrg } else if(SiS_Pr->ChipType >= XGI_40) { 309272b676d7Smrg if(SiS_Pr->SiS_XGIROM) { 309372b676d7Smrg SiS_Pr->Init_P4_0E = ROMAddr[0x80]; 309472b676d7Smrg } 309572b676d7Smrg } 309672b676d7Smrg} 309772b676d7Smrg 309872b676d7Smrgstatic void 309972b676d7SmrgSiS_ResetVB(struct SiS_Private *SiS_Pr) 310072b676d7Smrg{ 310172b676d7Smrg#ifdef SIS315H 310272b676d7Smrg unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 310372b676d7Smrg unsigned short temp; 310472b676d7Smrg 310572b676d7Smrg /* VB programming clock */ 310672b676d7Smrg if(SiS_Pr->SiS_UseROM) { 310772b676d7Smrg if(SiS_Pr->ChipType < SIS_330) { 310872b676d7Smrg temp = ROMAddr[VB310Data_1_2_Offset] | 0x40; 310972b676d7Smrg if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40; 311072b676d7Smrg SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 311172b676d7Smrg } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) { 311272b676d7Smrg temp = ROMAddr[0x7e] | 0x40; 311372b676d7Smrg if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40; 311472b676d7Smrg SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 311572b676d7Smrg } 311672b676d7Smrg } else if(SiS_Pr->ChipType >= XGI_40) { 311772b676d7Smrg temp = 0x40; 311872b676d7Smrg if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e]; 311972b676d7Smrg /* Can we do this on any chipset? */ 312072b676d7Smrg SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 312172b676d7Smrg } 312272b676d7Smrg#endif 312372b676d7Smrg} 312472b676d7Smrg 312572b676d7Smrg/*********************************************/ 312672b676d7Smrg/* HELPER: SET VIDEO/CAPTURE REGISTERS */ 312772b676d7Smrg/*********************************************/ 312872b676d7Smrg 312972b676d7Smrgstatic void 313072b676d7SmrgSiS_StrangeStuff(struct SiS_Private *SiS_Pr) 313172b676d7Smrg{ 313272b676d7Smrg /* SiS65x and XGI set up some sort of "lock mode" for text 313372b676d7Smrg * which locks CRT2 in some way to CRT1 timing. Disable 313472b676d7Smrg * this here. 313572b676d7Smrg */ 313672b676d7Smrg#ifdef SIS315H 313772b676d7Smrg if((IS_SIS651) || (IS_SISM650) || 313872b676d7Smrg SiS_Pr->ChipType == SIS_340 || 313972b676d7Smrg SiS_Pr->ChipType == XGI_40) { 314072b676d7Smrg SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */ 314172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00); 314272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */ 314372b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */ 314472b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef); 314572b676d7Smrg } 314672b676d7Smrg /* !!! This does not support modes < 0x13 !!! */ 314772b676d7Smrg#endif 314872b676d7Smrg} 314972b676d7Smrg 315072b676d7Smrg/*********************************************/ 315172b676d7Smrg/* HELPER: SET AGP TIMING FOR SiS760 */ 315272b676d7Smrg/*********************************************/ 315372b676d7Smrg 315472b676d7Smrgstatic void 315572b676d7SmrgSiS_Handle760(struct SiS_Private *SiS_Pr) 315672b676d7Smrg{ 315772b676d7Smrg#ifdef SIS315H 315872b676d7Smrg unsigned int somebase; 315972b676d7Smrg unsigned char temp1, temp2, temp3; 316072b676d7Smrg 316172b676d7Smrg if( (SiS_Pr->ChipType != SIS_760) || 316272b676d7Smrg ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) || 316372b676d7Smrg (!(SiS_Pr->SiS_SysFlags & SF_760LFB)) || 316472b676d7Smrg (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) ) 316572b676d7Smrg return; 316672b676d7Smrg 316772b676d7Smrg#ifdef SIS_LINUX_KERNEL 316872b676d7Smrg somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74); 316972b676d7Smrg#else 31701fd23544Smrg somebase = sis_pci_read_device_u32(2, 0x74); 317172b676d7Smrg#endif 317272b676d7Smrg somebase &= 0xffff; 317372b676d7Smrg 317472b676d7Smrg if(somebase == 0) return; 317572b676d7Smrg 317672b676d7Smrg temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7; 317772b676d7Smrg 317872b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { 317972b676d7Smrg temp1 = 0x21; 318072b676d7Smrg temp2 = 0x03; 318172b676d7Smrg temp3 |= 0x08; 318272b676d7Smrg } else { 318372b676d7Smrg temp1 = 0x25; 318472b676d7Smrg temp2 = 0x0b; 318572b676d7Smrg } 318672b676d7Smrg 318772b676d7Smrg#ifdef SIS_LINUX_KERNEL 318872b676d7Smrg sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1); 318972b676d7Smrg sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2); 319072b676d7Smrg#else 31911fd23544Smrg sis_pci_write_host_bridge_u8(0x7e, temp1); 31921fd23544Smrg sis_pci_write_host_bridge_u8(0x8d, temp2); 319372b676d7Smrg#endif 319472b676d7Smrg 319572b676d7Smrg SiS_SetRegByte((somebase + 0x85), temp3); 319672b676d7Smrg#endif 319772b676d7Smrg} 319872b676d7Smrg 319972b676d7Smrg/*********************************************/ 320072b676d7Smrg/* X.org/XFree86: SET SCREEN PITCH */ 320172b676d7Smrg/*********************************************/ 320272b676d7Smrg 320372b676d7Smrg#ifdef SIS_XORG_XF86 320472b676d7Smrgstatic void 320572b676d7SmrgSiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) 320672b676d7Smrg{ 320772b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 320872b676d7Smrg unsigned short HDisplay = pSiS->scrnPitch >> 3; 320972b676d7Smrg 321072b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF)); 321172b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8)); 321272b676d7Smrg} 321372b676d7Smrg 321472b676d7Smrgstatic void 321572b676d7SmrgSiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) 321672b676d7Smrg{ 321772b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 321872b676d7Smrg unsigned short HDisplay = pSiS->scrnPitch2 >> 3; 321972b676d7Smrg 322072b676d7Smrg /* Unlock CRT2 */ 322172b676d7Smrg if(pSiS->VGAEngine == SIS_315_VGA) 322272b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01); 322372b676d7Smrg else 322472b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01); 322572b676d7Smrg 322672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF)); 322772b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8)); 322872b676d7Smrg} 322972b676d7Smrg 323072b676d7Smrgstatic void 323172b676d7SmrgSiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn) 323272b676d7Smrg{ 323372b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 323472b676d7Smrg BOOLEAN isslavemode = FALSE; 323572b676d7Smrg 323672b676d7Smrg if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) && 323772b676d7Smrg ( ((pSiS->VGAEngine == SIS_300_VGA) && 323872b676d7Smrg (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) || 323972b676d7Smrg ((pSiS->VGAEngine == SIS_315_VGA) && 324072b676d7Smrg (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) { 324172b676d7Smrg isslavemode = TRUE; 324272b676d7Smrg } 324372b676d7Smrg 324472b676d7Smrg /* We need to set pitch for CRT1 if bridge is in slave mode, too */ 324572b676d7Smrg if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) { 324672b676d7Smrg SiS_SetPitchCRT1(SiS_Pr, pScrn); 324772b676d7Smrg } 324872b676d7Smrg /* We must not set the pitch for CRT2 if bridge is in slave mode */ 324972b676d7Smrg if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) { 325072b676d7Smrg SiS_SetPitchCRT2(SiS_Pr, pScrn); 325172b676d7Smrg } 325272b676d7Smrg} 325372b676d7Smrg#endif 325472b676d7Smrg 325572b676d7Smrg/*********************************************/ 325672b676d7Smrg/* SiSSetMode() */ 325772b676d7Smrg/*********************************************/ 325872b676d7Smrg 325972b676d7Smrg#ifdef SIS_XORG_XF86 326072b676d7Smrg/* We need pScrn for setting the pitch correctly */ 326172b676d7SmrgBOOLEAN 326272b676d7SmrgSiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, BOOLEAN dosetpitch) 326372b676d7Smrg#else 326472b676d7SmrgBOOLEAN 326572b676d7SmrgSiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 326672b676d7Smrg#endif 326772b676d7Smrg{ 326872b676d7Smrg SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; 326972b676d7Smrg unsigned short RealModeNo, ModeIdIndex; 327072b676d7Smrg unsigned char backupreg = 0; 327172b676d7Smrg#ifdef SIS_LINUX_KERNEL 327272b676d7Smrg unsigned short KeepLockReg; 327372b676d7Smrg 327472b676d7Smrg SiS_Pr->UseCustomMode = FALSE; 327572b676d7Smrg SiS_Pr->CRT1UsesCustomMode = FALSE; 327672b676d7Smrg#endif 327772b676d7Smrg 327872b676d7Smrg SiS_Pr->SiS_flag_clearbuffer = 0; 327972b676d7Smrg 328072b676d7Smrg if(SiS_Pr->UseCustomMode) { 328172b676d7Smrg ModeNo = 0xfe; 328272b676d7Smrg } else { 328372b676d7Smrg#ifdef SIS_LINUX_KERNEL 328472b676d7Smrg if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1; 328572b676d7Smrg#endif 328672b676d7Smrg ModeNo &= 0x7f; 328772b676d7Smrg } 328872b676d7Smrg 328972b676d7Smrg /* Don't use FSTN mode for CRT1 */ 329072b676d7Smrg RealModeNo = ModeNo; 329172b676d7Smrg if(ModeNo == 0x5b) ModeNo = 0x56; 329272b676d7Smrg 329372b676d7Smrg SiSInitPtr(SiS_Pr); 329472b676d7Smrg SiSRegInit(SiS_Pr, BaseAddr); 329572b676d7Smrg SiS_GetSysFlags(SiS_Pr); 329672b676d7Smrg 329772b676d7Smrg SiS_Pr->SiS_VGAINFO = 0x11; 329872b676d7Smrg#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)) 329972b676d7Smrg if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); 330072b676d7Smrg#endif 330172b676d7Smrg 330272b676d7Smrg#ifdef SIS_LINUX_KERNEL 330372b676d7Smrg KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); 330472b676d7Smrg#endif 330572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 330672b676d7Smrg 330772b676d7Smrg SiSInitPCIetc(SiS_Pr); 330872b676d7Smrg SiSSetLVDSetc(SiS_Pr); 330972b676d7Smrg SiSDetermineROMUsage(SiS_Pr); 331072b676d7Smrg 331172b676d7Smrg SiS_UnLockCRT2(SiS_Pr); 331272b676d7Smrg 331372b676d7Smrg if(!SiS_Pr->UseCustomMode) { 331472b676d7Smrg if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE; 331572b676d7Smrg } else { 331672b676d7Smrg ModeIdIndex = 0; 331772b676d7Smrg } 331872b676d7Smrg 331972b676d7Smrg SiS_GetVBType(SiS_Pr); 332072b676d7Smrg 332172b676d7Smrg /* Init/restore some VB registers */ 332272b676d7Smrg SiS_InitVB(SiS_Pr); 332372b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 332472b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 332572b676d7Smrg SiS_ResetVB(SiS_Pr); 332672b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); 332772b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c); 332872b676d7Smrg backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 332972b676d7Smrg } else { 333072b676d7Smrg backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 333172b676d7Smrg } 333272b676d7Smrg } 333372b676d7Smrg 333472b676d7Smrg /* Get VB information (connectors, connected devices) */ 333572b676d7Smrg SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1); 333672b676d7Smrg SiS_SetYPbPr(SiS_Pr); 333772b676d7Smrg SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); 333872b676d7Smrg SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); 333972b676d7Smrg SiS_SetLowModeTest(SiS_Pr, ModeNo); 334072b676d7Smrg 334172b676d7Smrg#ifdef SIS_LINUX_KERNEL 334272b676d7Smrg /* Check memory size (kernel framebuffer driver only) */ 334372b676d7Smrg if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) { 334472b676d7Smrg return FALSE; 334572b676d7Smrg } 334672b676d7Smrg#endif 334772b676d7Smrg 334872b676d7Smrg SiS_OpenCRTC(SiS_Pr); 334972b676d7Smrg 335072b676d7Smrg if(SiS_Pr->UseCustomMode) { 335172b676d7Smrg SiS_Pr->CRT1UsesCustomMode = TRUE; 335272b676d7Smrg SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock; 335372b676d7Smrg SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag; 335472b676d7Smrg } else { 335572b676d7Smrg SiS_Pr->CRT1UsesCustomMode = FALSE; 335672b676d7Smrg } 335772b676d7Smrg 335872b676d7Smrg /* Set mode on CRT1 */ 335972b676d7Smrg if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) || 336072b676d7Smrg (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) { 336172b676d7Smrg SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex); 336272b676d7Smrg } 336372b676d7Smrg 336472b676d7Smrg /* Set mode on CRT2 */ 336572b676d7Smrg if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) { 336672b676d7Smrg if( (SiS_Pr->SiS_VBType & VB_SISVB) || 336772b676d7Smrg (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 336872b676d7Smrg (SiS_Pr->SiS_IF_DEF_CH70xx != 0) || 336972b676d7Smrg (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) { 337072b676d7Smrg SiS_SetCRT2Group(SiS_Pr, RealModeNo); 337172b676d7Smrg } 337272b676d7Smrg } 337372b676d7Smrg 337472b676d7Smrg SiS_HandleCRT1(SiS_Pr); 337572b676d7Smrg 337672b676d7Smrg SiS_StrangeStuff(SiS_Pr); 337772b676d7Smrg 337872b676d7Smrg SiS_DisplayOn(SiS_Pr); 337972b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 338072b676d7Smrg 338172b676d7Smrg#ifdef SIS315H 338272b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 338372b676d7Smrg if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 338472b676d7Smrg if(!(SiS_IsDualEdge(SiS_Pr))) { 338572b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 338672b676d7Smrg } 338772b676d7Smrg } 338872b676d7Smrg } 338972b676d7Smrg#endif 339072b676d7Smrg 339172b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 339272b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 339372b676d7Smrg#ifdef SIS315H 339472b676d7Smrg if(!SiS_Pr->SiS_ROMNew) { 339572b676d7Smrg if(SiS_IsVAMode(SiS_Pr)) { 339672b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 339772b676d7Smrg } else { 339872b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); 339972b676d7Smrg } 340072b676d7Smrg } 340172b676d7Smrg 340272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); 340372b676d7Smrg 340472b676d7Smrg if((IS_SIS650) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) { 340572b676d7Smrg if((ModeNo == 0x03) || (ModeNo == 0x10)) { 340672b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80); 340772b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08); 340872b676d7Smrg } 340972b676d7Smrg } 341072b676d7Smrg 341172b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { 341272b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 341372b676d7Smrg } 341472b676d7Smrg#endif 341572b676d7Smrg } else if((SiS_Pr->ChipType == SIS_630) || 341672b676d7Smrg (SiS_Pr->ChipType == SIS_730)) { 341772b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); 341872b676d7Smrg } 341972b676d7Smrg } 342072b676d7Smrg 342172b676d7Smrg#ifdef SIS_XORG_XF86 342272b676d7Smrg if(pScrn) { 342372b676d7Smrg /* SetPitch: Adapt to virtual size & position */ 342472b676d7Smrg if((ModeNo > 0x13) && (dosetpitch)) { 342572b676d7Smrg SiS_SetPitch(SiS_Pr, pScrn); 342672b676d7Smrg } 342772b676d7Smrg 342872b676d7Smrg /* Backup/Set ModeNo in BIOS scratch area */ 342972b676d7Smrg SiS_GetSetModeID(pScrn, ModeNo); 343072b676d7Smrg } 343172b676d7Smrg#endif 343272b676d7Smrg 343372b676d7Smrg SiS_CloseCRTC(SiS_Pr); 343472b676d7Smrg 343572b676d7Smrg SiS_Handle760(SiS_Pr); 343672b676d7Smrg 343772b676d7Smrg#ifdef SIS_LINUX_KERNEL 343872b676d7Smrg /* We never lock registers in XF86 */ 343972b676d7Smrg if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00); 344072b676d7Smrg#endif 344172b676d7Smrg 344272b676d7Smrg return TRUE; 344372b676d7Smrg} 344472b676d7Smrg 344572b676d7Smrg/*********************************************/ 344672b676d7Smrg/* X.org/XFree86: SiSBIOSSetMode() */ 344772b676d7Smrg/* for non-Dual-Head mode */ 344872b676d7Smrg/*********************************************/ 344972b676d7Smrg 345072b676d7Smrg#ifdef SIS_XORG_XF86 345172b676d7SmrgBOOLEAN 345272b676d7SmrgSiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, 345372b676d7Smrg DisplayModePtr mode, BOOLEAN IsCustom) 345472b676d7Smrg{ 345572b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 345672b676d7Smrg unsigned short ModeNo = 0; 345772b676d7Smrg 345872b676d7Smrg SiS_Pr->UseCustomMode = FALSE; 345972b676d7Smrg 346072b676d7Smrg if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { 346172b676d7Smrg 346272b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", 346372b676d7Smrg SiS_Pr->CHDisplay, 346472b676d7Smrg (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 : 346572b676d7Smrg (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 : 346672b676d7Smrg SiS_Pr->CVDisplay))); 346772b676d7Smrg 346872b676d7Smrg } else { 346972b676d7Smrg 347072b676d7Smrg /* Don't need vbflags here; checks done earlier */ 347172b676d7Smrg ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags); 347272b676d7Smrg if(!ModeNo) return FALSE; 347372b676d7Smrg 347472b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo); 347572b676d7Smrg 347672b676d7Smrg } 347772b676d7Smrg 347872b676d7Smrg return(SiSSetMode(SiS_Pr, pScrn, ModeNo, TRUE)); 347972b676d7Smrg} 348072b676d7Smrg 348172b676d7Smrg/*********************************************/ 348272b676d7Smrg/* X.org/XFree86: SiSBIOSSetModeCRT2() */ 348372b676d7Smrg/* for Dual-Head modes */ 348472b676d7Smrg/*********************************************/ 348572b676d7Smrg 348672b676d7SmrgBOOLEAN 348772b676d7SmrgSiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, 348872b676d7Smrg DisplayModePtr mode, BOOLEAN IsCustom) 348972b676d7Smrg{ 349072b676d7Smrg SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; 349172b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 349272b676d7Smrg#ifdef SISDUALHEAD 349372b676d7Smrg SISEntPtr pSiSEnt = pSiS->entityPrivate; 349472b676d7Smrg#endif 349572b676d7Smrg unsigned short ModeIdIndex; 349672b676d7Smrg unsigned short ModeNo = 0; 349772b676d7Smrg unsigned char backupreg = 0; 349872b676d7Smrg 349972b676d7Smrg SiS_Pr->UseCustomMode = FALSE; 350072b676d7Smrg 350172b676d7Smrg /* Remember: Custom modes for CRT2 are ONLY supported 350272b676d7Smrg * -) on the 30x/B/C, and 350372b676d7Smrg * -) if CRT2 is LCD or VGA, or CRT1 is LCDA 350472b676d7Smrg */ 350572b676d7Smrg 350672b676d7Smrg if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { 350772b676d7Smrg 350872b676d7Smrg ModeNo = 0xfe; 350972b676d7Smrg 351072b676d7Smrg } else { 351172b676d7Smrg 351272b676d7Smrg ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags); 351372b676d7Smrg if(!ModeNo) return FALSE; 351472b676d7Smrg 351572b676d7Smrg } 351672b676d7Smrg 351772b676d7Smrg SiSRegInit(SiS_Pr, BaseAddr); 351872b676d7Smrg SiSInitPtr(SiS_Pr); 351972b676d7Smrg SiS_GetSysFlags(SiS_Pr); 352072b676d7Smrg#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__) 352172b676d7Smrg SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); 352272b676d7Smrg#else 352372b676d7Smrg SiS_Pr->SiS_VGAINFO = 0x11; 352472b676d7Smrg#endif 352572b676d7Smrg 352672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 352772b676d7Smrg 352872b676d7Smrg SiSInitPCIetc(SiS_Pr); 352972b676d7Smrg SiSSetLVDSetc(SiS_Pr); 353072b676d7Smrg SiSDetermineROMUsage(SiS_Pr); 353172b676d7Smrg 353272b676d7Smrg /* Save mode info so we can set it from within SetMode for CRT1 */ 353372b676d7Smrg#ifdef SISDUALHEAD 353472b676d7Smrg if(pSiS->DualHeadMode) { 353572b676d7Smrg pSiSEnt->CRT2ModeNo = ModeNo; 353672b676d7Smrg pSiSEnt->CRT2DMode = mode; 353772b676d7Smrg pSiSEnt->CRT2IsCustom = IsCustom; 353872b676d7Smrg pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 353972b676d7Smrg pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); 354072b676d7Smrg pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 354172b676d7Smrg pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 354272b676d7Smrg#if 0 354372b676d7Smrg /* We can't set CRT2 mode before CRT1 mode is set - says who...? */ 354472b676d7Smrg if(pSiSEnt->CRT1ModeNo == -1) { 354572b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 354672b676d7Smrg "Setting CRT2 mode delayed until after setting CRT1 mode\n"); 354772b676d7Smrg return TRUE; 354872b676d7Smrg } 354972b676d7Smrg#endif 355072b676d7Smrg pSiSEnt->CRT2ModeSet = TRUE; 355172b676d7Smrg } 355272b676d7Smrg#endif 355372b676d7Smrg 355472b676d7Smrg if(SiS_Pr->UseCustomMode) { 355572b676d7Smrg 355672b676d7Smrg unsigned short temptemp = SiS_Pr->CVDisplay; 355772b676d7Smrg 355872b676d7Smrg if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; 355972b676d7Smrg else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; 356072b676d7Smrg 356172b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 356272b676d7Smrg "Setting custom mode %dx%d on CRT2\n", 356372b676d7Smrg SiS_Pr->CHDisplay, temptemp); 356472b676d7Smrg 356572b676d7Smrg } else { 356672b676d7Smrg 356772b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 356872b676d7Smrg "Setting standard mode 0x%x on CRT2\n", ModeNo); 356972b676d7Smrg 357072b676d7Smrg } 357172b676d7Smrg 357272b676d7Smrg SiS_UnLockCRT2(SiS_Pr); 357372b676d7Smrg 357472b676d7Smrg if(!SiS_Pr->UseCustomMode) { 357572b676d7Smrg if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE; 357672b676d7Smrg } else { 357772b676d7Smrg ModeIdIndex = 0; 357872b676d7Smrg } 357972b676d7Smrg 358072b676d7Smrg SiS_GetVBType(SiS_Pr); 358172b676d7Smrg 358272b676d7Smrg SiS_InitVB(SiS_Pr); 358372b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 358472b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 358572b676d7Smrg SiS_ResetVB(SiS_Pr); 358672b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); 358772b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c); 358872b676d7Smrg backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 358972b676d7Smrg } else { 359072b676d7Smrg backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 359172b676d7Smrg } 359272b676d7Smrg } 359372b676d7Smrg 359472b676d7Smrg /* Get VB information (connectors, connected devices) */ 359572b676d7Smrg if(!SiS_Pr->UseCustomMode) { 359672b676d7Smrg SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1); 359772b676d7Smrg } else { 359872b676d7Smrg /* If this is a custom mode, we don't check the modeflag for CRT2Mode */ 359972b676d7Smrg SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0); 360072b676d7Smrg } 360172b676d7Smrg SiS_SetYPbPr(SiS_Pr); 360272b676d7Smrg SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); 360372b676d7Smrg SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); 360472b676d7Smrg SiS_SetLowModeTest(SiS_Pr, ModeNo); 360572b676d7Smrg 360672b676d7Smrg SiS_ResetSegmentRegisters(SiS_Pr); 360772b676d7Smrg 360872b676d7Smrg /* Set mode on CRT2 */ 360972b676d7Smrg if( (SiS_Pr->SiS_VBType & VB_SISVB) || 361072b676d7Smrg (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 361172b676d7Smrg (SiS_Pr->SiS_IF_DEF_CH70xx != 0) || 361272b676d7Smrg (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) { 361372b676d7Smrg SiS_SetCRT2Group(SiS_Pr, ModeNo); 361472b676d7Smrg } 361572b676d7Smrg 361672b676d7Smrg SiS_StrangeStuff(SiS_Pr); 361772b676d7Smrg 361872b676d7Smrg SiS_DisplayOn(SiS_Pr); 361972b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 362072b676d7Smrg 362172b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 362272b676d7Smrg if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 362372b676d7Smrg if(!(SiS_IsDualEdge(SiS_Pr))) { 362472b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 362572b676d7Smrg } 362672b676d7Smrg } 362772b676d7Smrg } 362872b676d7Smrg 362972b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 363072b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 363172b676d7Smrg if(!SiS_Pr->SiS_ROMNew) { 363272b676d7Smrg if(SiS_IsVAMode(SiS_Pr)) { 363372b676d7Smrg SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 363472b676d7Smrg } else { 363572b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); 363672b676d7Smrg } 363772b676d7Smrg } 363872b676d7Smrg 363972b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); 364072b676d7Smrg 364172b676d7Smrg if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { 364272b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 364372b676d7Smrg } 364472b676d7Smrg } else if((SiS_Pr->ChipType == SIS_630) || 364572b676d7Smrg (SiS_Pr->ChipType == SIS_730)) { 364672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); 364772b676d7Smrg } 364872b676d7Smrg } 364972b676d7Smrg 365072b676d7Smrg /* SetPitch: Adapt to virtual size & position */ 365172b676d7Smrg SiS_SetPitchCRT2(SiS_Pr, pScrn); 365272b676d7Smrg 365372b676d7Smrg SiS_Handle760(SiS_Pr); 365472b676d7Smrg 365572b676d7Smrg return TRUE; 365672b676d7Smrg} 365772b676d7Smrg 365872b676d7Smrg/*********************************************/ 365972b676d7Smrg/* X.org/XFree86: SiSBIOSSetModeCRT1() */ 366072b676d7Smrg/* for Dual-Head modes */ 366172b676d7Smrg/*********************************************/ 366272b676d7Smrg 366372b676d7SmrgBOOLEAN 366472b676d7SmrgSiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, 366572b676d7Smrg DisplayModePtr mode, BOOLEAN IsCustom) 366672b676d7Smrg{ 366772b676d7Smrg SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; 366872b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 366972b676d7Smrg unsigned short ModeIdIndex, ModeNo = 0; 367072b676d7Smrg unsigned char backupreg = 0; 367172b676d7Smrg#ifdef SISDUALHEAD 367272b676d7Smrg SISEntPtr pSiSEnt = pSiS->entityPrivate; 367372b676d7Smrg unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0; 367472b676d7Smrg BOOLEAN backupcustom; 367572b676d7Smrg#endif 367672b676d7Smrg 367772b676d7Smrg SiS_Pr->UseCustomMode = FALSE; 367872b676d7Smrg 367972b676d7Smrg if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) { 368072b676d7Smrg 368172b676d7Smrg unsigned short temptemp = SiS_Pr->CVDisplay; 368272b676d7Smrg 368372b676d7Smrg if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1; 368472b676d7Smrg else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1; 368572b676d7Smrg 368672b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 368772b676d7Smrg "Setting custom mode %dx%d on CRT1\n", 368872b676d7Smrg SiS_Pr->CHDisplay, temptemp); 368972b676d7Smrg ModeNo = 0xfe; 369072b676d7Smrg 369172b676d7Smrg } else { 369272b676d7Smrg 369372b676d7Smrg ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */ 369472b676d7Smrg if(!ModeNo) return FALSE; 369572b676d7Smrg 369672b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 369772b676d7Smrg "Setting standard mode 0x%x on CRT1\n", ModeNo); 369872b676d7Smrg } 369972b676d7Smrg 370072b676d7Smrg SiSInitPtr(SiS_Pr); 370172b676d7Smrg SiSRegInit(SiS_Pr, BaseAddr); 370272b676d7Smrg SiS_GetSysFlags(SiS_Pr); 370372b676d7Smrg#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__) 370472b676d7Smrg SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff); 370572b676d7Smrg#else 370672b676d7Smrg SiS_Pr->SiS_VGAINFO = 0x11; 370772b676d7Smrg#endif 370872b676d7Smrg 370972b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 371072b676d7Smrg 371172b676d7Smrg SiSInitPCIetc(SiS_Pr); 371272b676d7Smrg SiSSetLVDSetc(SiS_Pr); 371372b676d7Smrg SiSDetermineROMUsage(SiS_Pr); 371472b676d7Smrg 371572b676d7Smrg SiS_UnLockCRT2(SiS_Pr); 371672b676d7Smrg 371772b676d7Smrg if(!SiS_Pr->UseCustomMode) { 371872b676d7Smrg if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE; 371972b676d7Smrg } else { 372072b676d7Smrg ModeIdIndex = 0; 372172b676d7Smrg } 372272b676d7Smrg 372372b676d7Smrg /* Determine VBType */ 372472b676d7Smrg SiS_GetVBType(SiS_Pr); 372572b676d7Smrg 372672b676d7Smrg SiS_InitVB(SiS_Pr); 372772b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 372872b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 372972b676d7Smrg backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 373072b676d7Smrg } else { 373172b676d7Smrg backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 373272b676d7Smrg } 373372b676d7Smrg } 373472b676d7Smrg 373572b676d7Smrg /* Get VB information (connectors, connected devices) */ 373672b676d7Smrg /* (We don't care if the current mode is a CRT2 mode) */ 373772b676d7Smrg SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0); 373872b676d7Smrg SiS_SetYPbPr(SiS_Pr); 373972b676d7Smrg SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); 374072b676d7Smrg SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); 374172b676d7Smrg SiS_SetLowModeTest(SiS_Pr, ModeNo); 374272b676d7Smrg 374372b676d7Smrg SiS_OpenCRTC(SiS_Pr); 374472b676d7Smrg 374572b676d7Smrg /* Set mode on CRT1 */ 374672b676d7Smrg SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex); 374772b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 374872b676d7Smrg SiS_SetCRT2Group(SiS_Pr, ModeNo); 374972b676d7Smrg } 375072b676d7Smrg 375172b676d7Smrg /* SetPitch: Adapt to virtual size & position */ 375272b676d7Smrg SiS_SetPitchCRT1(SiS_Pr, pScrn); 375372b676d7Smrg 375472b676d7Smrg SiS_HandleCRT1(SiS_Pr); 375572b676d7Smrg 375672b676d7Smrg SiS_StrangeStuff(SiS_Pr); 375772b676d7Smrg 375872b676d7Smrg SiS_CloseCRTC(SiS_Pr); 375972b676d7Smrg 376072b676d7Smrg#ifdef SISDUALHEAD 376172b676d7Smrg if(pSiS->DualHeadMode) { 376272b676d7Smrg pSiSEnt->CRT1ModeNo = ModeNo; 376372b676d7Smrg pSiSEnt->CRT1DMode = mode; 376472b676d7Smrg } 376572b676d7Smrg#endif 376672b676d7Smrg 376772b676d7Smrg if(SiS_Pr->UseCustomMode) { 376872b676d7Smrg SiS_Pr->CRT1UsesCustomMode = TRUE; 376972b676d7Smrg SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock; 377072b676d7Smrg SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag; 377172b676d7Smrg } else { 377272b676d7Smrg SiS_Pr->CRT1UsesCustomMode = FALSE; 377372b676d7Smrg } 377472b676d7Smrg 377572b676d7Smrg /* Reset CRT2 if changing mode on CRT1 */ 377672b676d7Smrg#ifdef SISDUALHEAD 377772b676d7Smrg if(pSiS->DualHeadMode) { 377872b676d7Smrg if(pSiSEnt->CRT2ModeNo != -1) { 377972b676d7Smrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 378072b676d7Smrg "(Re-)Setting mode for CRT2\n"); 378172b676d7Smrg backupcustom = SiS_Pr->UseCustomMode; 378272b676d7Smrg backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 378372b676d7Smrg backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); 378472b676d7Smrg backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 378572b676d7Smrg backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 378672b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SISVB) { 378772b676d7Smrg /* Backup LUT-enable */ 378872b676d7Smrg if(pSiSEnt->CRT2ModeSet) { 378972b676d7Smrg backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08; 379072b676d7Smrg } 379172b676d7Smrg } 379272b676d7Smrg if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 379372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30); 379472b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31); 379572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35); 379672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38); 379772b676d7Smrg } 379872b676d7Smrg 379972b676d7Smrg SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1, 380072b676d7Smrg pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom); 380172b676d7Smrg 380272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30); 380372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31); 380472b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35); 380572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38); 380672b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SISVB) { 380772b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d); 380872b676d7Smrg } 380972b676d7Smrg SiS_Pr->UseCustomMode = backupcustom; 381072b676d7Smrg } 381172b676d7Smrg } 381272b676d7Smrg#endif 381372b676d7Smrg 381472b676d7Smrg /* Warning: From here, the custom mode entries in SiS_Pr are 381572b676d7Smrg * possibly overwritten 381672b676d7Smrg */ 381772b676d7Smrg 381872b676d7Smrg SiS_DisplayOn(SiS_Pr); 381972b676d7Smrg SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 382072b676d7Smrg 382172b676d7Smrg if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 382272b676d7Smrg if(SiS_Pr->ChipType >= SIS_315H) { 382372b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); 382472b676d7Smrg } else if((SiS_Pr->ChipType == SIS_630) || 382572b676d7Smrg (SiS_Pr->ChipType == SIS_730)) { 382672b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); 382772b676d7Smrg } 382872b676d7Smrg } 382972b676d7Smrg 383072b676d7Smrg SiS_Handle760(SiS_Pr); 383172b676d7Smrg 383272b676d7Smrg /* Backup/Set ModeNo in BIOS scratch area */ 383372b676d7Smrg SiS_GetSetModeID(pScrn,ModeNo); 383472b676d7Smrg 383572b676d7Smrg return TRUE; 383672b676d7Smrg} 383772b676d7Smrg#endif /* Linux_XF86 */ 383872b676d7Smrg 383972b676d7Smrg#ifndef GETBITSTR 384072b676d7Smrg#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) 384172b676d7Smrg#define GENMASK(mask) BITMASK(1?mask,0?mask) 384272b676d7Smrg#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask)) 384372b676d7Smrg#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to)) 384472b676d7Smrg#endif 384572b676d7Smrg 384672b676d7Smrgvoid 384772b676d7SmrgSiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth) 384872b676d7Smrg{ 384972b676d7Smrg int x = 1; /* Fix sync */ 385072b676d7Smrg 385172b676d7Smrg SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */ 385272b676d7Smrg SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */ 385372b676d7Smrg SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */ 385472b676d7Smrg SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */ 385572b676d7Smrg SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */ 385672b676d7Smrg SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */ 385772b676d7Smrg (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F); 385872b676d7Smrg 385972b676d7Smrg SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */ 386072b676d7Smrg SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */ 386172b676d7Smrg | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7) 386272b676d7Smrg | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6) 386372b676d7Smrg | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5) 386472b676d7Smrg | 0x10 386572b676d7Smrg | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4) 386672b676d7Smrg | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3) 386772b676d7Smrg | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2); 386872b676d7Smrg 386972b676d7Smrg SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */ 387072b676d7Smrg 387172b676d7Smrg if(depth != 8) { 387272b676d7Smrg if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60; /* SRE */ 387372b676d7Smrg else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40; 387472b676d7Smrg } 387572b676d7Smrg 387672b676d7Smrg SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart - x) & 0xFF; /* CR10 */ 387772b676d7Smrg SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd - x) & 0x0F) | 0x80; /* CR11 */ 387872b676d7Smrg SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */ 387972b676d7Smrg SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */ 388072b676d7Smrg SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */ 388172b676d7Smrg 388272b676d7Smrg SiS_Pr->CCRT1CRTC[13] = /* SRA */ 388372b676d7Smrg GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) | 388472b676d7Smrg GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) | 388572b676d7Smrg GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) | 388672b676d7Smrg GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) | 388772b676d7Smrg GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) | 388872b676d7Smrg GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ; 388972b676d7Smrg 389072b676d7Smrg SiS_Pr->CCRT1CRTC[14] = /* SRB */ 389172b676d7Smrg GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) | 389272b676d7Smrg GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) | 389372b676d7Smrg GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) | 389472b676d7Smrg GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ; 389572b676d7Smrg 389672b676d7Smrg 389772b676d7Smrg SiS_Pr->CCRT1CRTC[15] = /* SRC */ 389872b676d7Smrg GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) | 389972b676d7Smrg GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ; 390072b676d7Smrg} 390172b676d7Smrg 390272b676d7Smrgvoid 390372b676d7SmrgSiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 390472b676d7Smrg unsigned short ModeIdIndex) 390572b676d7Smrg{ 390672b676d7Smrg unsigned short modeflag, tempax, tempbx = 0, remaining = 0; 390772b676d7Smrg unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE; 390872b676d7Smrg int i, j; 390972b676d7Smrg 391072b676d7Smrg /* 1:1 data: use data set by setcrt1crtc() */ 391172b676d7Smrg if(SiS_Pr->SiS_LCDInfo & LCDPass11) return; 391272b676d7Smrg 391372b676d7Smrg modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 391472b676d7Smrg 391572b676d7Smrg if(modeflag & HalfDCLK) VGAHDE >>= 1; 391672b676d7Smrg 391772b676d7Smrg SiS_Pr->CHDisplay = VGAHDE; 391872b676d7Smrg SiS_Pr->CHBlankStart = VGAHDE; 391972b676d7Smrg 392072b676d7Smrg SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE; 392172b676d7Smrg SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE; 392272b676d7Smrg 392372b676d7Smrg if(SiS_Pr->ChipType < SIS_315H) { 392472b676d7Smrg#ifdef SIS300 392572b676d7Smrg tempbx = SiS_Pr->SiS_VGAHT; 392672b676d7Smrg if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 392772b676d7Smrg tempbx = SiS_Pr->PanelHT; 392872b676d7Smrg } 392972b676d7Smrg if(modeflag & HalfDCLK) tempbx >>= 1; 393072b676d7Smrg remaining = tempbx % 8; 393172b676d7Smrg#endif 393272b676d7Smrg } else { 393372b676d7Smrg#ifdef SIS315H 393472b676d7Smrg /* OK for LCDA, LVDS */ 393572b676d7Smrg tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes; 393672b676d7Smrg tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */ 393772b676d7Smrg if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 393872b676d7Smrg tempax = SiS_Pr->PanelXRes; 393972b676d7Smrg } 394072b676d7Smrg tempbx += tempax; 394172b676d7Smrg if(modeflag & HalfDCLK) tempbx -= VGAHDE; 394272b676d7Smrg#endif 394372b676d7Smrg } 394472b676d7Smrg SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx; 394572b676d7Smrg 394672b676d7Smrg if(SiS_Pr->ChipType < SIS_315H) { 394772b676d7Smrg#ifdef SIS300 394872b676d7Smrg if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) { 394972b676d7Smrg SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1); 395072b676d7Smrg SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE; 395172b676d7Smrg if(modeflag & HalfDCLK) { 395272b676d7Smrg SiS_Pr->CHSyncStart >>= 1; 395372b676d7Smrg SiS_Pr->CHSyncEnd >>= 1; 395472b676d7Smrg } 395572b676d7Smrg } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 395672b676d7Smrg tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1; 395772b676d7Smrg tempbx = (SiS_Pr->PanelHRS + 1) & ~1; 395872b676d7Smrg if(modeflag & HalfDCLK) { 395972b676d7Smrg tempax >>= 1; 396072b676d7Smrg tempbx >>= 1; 396172b676d7Smrg } 396272b676d7Smrg SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7; 396372b676d7Smrg tempax = SiS_Pr->PanelHRE + 7; 396472b676d7Smrg if(modeflag & HalfDCLK) tempax >>= 1; 396572b676d7Smrg SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7; 396672b676d7Smrg } else { 396772b676d7Smrg SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE; 396872b676d7Smrg if(modeflag & HalfDCLK) { 396972b676d7Smrg SiS_Pr->CHSyncStart >>= 1; 397072b676d7Smrg tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1; 397172b676d7Smrg SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax; 397272b676d7Smrg } else { 397372b676d7Smrg SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7; 397472b676d7Smrg SiS_Pr->CHSyncStart += 8; 397572b676d7Smrg } 397672b676d7Smrg } 397772b676d7Smrg#endif 397872b676d7Smrg } else { 397972b676d7Smrg#ifdef SIS315H 398072b676d7Smrg tempax = VGAHDE; 398172b676d7Smrg if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 398272b676d7Smrg tempbx = SiS_Pr->PanelXRes; 398372b676d7Smrg if(modeflag & HalfDCLK) tempbx >>= 1; 398472b676d7Smrg tempax += ((tempbx - tempax) >> 1); 398572b676d7Smrg } 398672b676d7Smrg tempax += SiS_Pr->PanelHRS; 398772b676d7Smrg SiS_Pr->CHSyncStart = tempax; 398872b676d7Smrg tempax += SiS_Pr->PanelHRE; 398972b676d7Smrg SiS_Pr->CHSyncEnd = tempax; 399072b676d7Smrg#endif 399172b676d7Smrg } 399272b676d7Smrg 399372b676d7Smrg tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes; 399472b676d7Smrg tempax = SiS_Pr->SiS_VGAVDE; 399572b676d7Smrg if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 399672b676d7Smrg tempax = SiS_Pr->PanelYRes; 399772b676d7Smrg } else if(SiS_Pr->ChipType < SIS_315H) { 399872b676d7Smrg#ifdef SIS300 399972b676d7Smrg /* Stupid hack for 640x400/320x200 */ 400072b676d7Smrg if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 400172b676d7Smrg if((tempax + tempbx) == 438) tempbx += 16; 400272b676d7Smrg } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) || 400372b676d7Smrg (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) { 400472b676d7Smrg tempax = 0; 400572b676d7Smrg tempbx = SiS_Pr->SiS_VGAVT; 400672b676d7Smrg } 400772b676d7Smrg#endif 400872b676d7Smrg } 400972b676d7Smrg SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax; 401072b676d7Smrg 401172b676d7Smrg tempax = SiS_Pr->SiS_VGAVDE; 401272b676d7Smrg if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 401372b676d7Smrg tempax += (SiS_Pr->PanelYRes - tempax) >> 1; 401472b676d7Smrg } 401572b676d7Smrg tempax += SiS_Pr->PanelVRS; 401672b676d7Smrg SiS_Pr->CVSyncStart = tempax; 401772b676d7Smrg tempax += SiS_Pr->PanelVRE; 401872b676d7Smrg SiS_Pr->CVSyncEnd = tempax; 401972b676d7Smrg if(SiS_Pr->ChipType < SIS_315H) { 402072b676d7Smrg SiS_Pr->CVSyncStart--; 402172b676d7Smrg SiS_Pr->CVSyncEnd--; 402272b676d7Smrg } 402372b676d7Smrg 402472b676d7Smrg SiS_CalcCRRegisters(SiS_Pr, 8); 402572b676d7Smrg SiS_Pr->CCRT1CRTC[15] &= ~0xF8; 402672b676d7Smrg SiS_Pr->CCRT1CRTC[15] |= (remaining << 4); 402772b676d7Smrg SiS_Pr->CCRT1CRTC[16] &= ~0xE0; 402872b676d7Smrg 402972b676d7Smrg SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 403072b676d7Smrg 403172b676d7Smrg for(i = 0, j = 0; i <= 7; i++, j++) { 403272b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 403372b676d7Smrg } 403472b676d7Smrg for(j = 0x10; i <= 10; i++, j++) { 403572b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 403672b676d7Smrg } 403772b676d7Smrg for(j = 0x15; i <= 12; i++, j++) { 403872b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 403972b676d7Smrg } 404072b676d7Smrg for(j = 0x0A; i <= 15; i++, j++) { 404172b676d7Smrg SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]); 404272b676d7Smrg } 404372b676d7Smrg 404472b676d7Smrg tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0; 404572b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax); 404672b676d7Smrg 404772b676d7Smrg tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5; 404872b676d7Smrg if(modeflag & DoubleScanMode) tempax |= 0x80; 404972b676d7Smrg SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax); 405072b676d7Smrg 405172b676d7Smrg#ifdef SIS_XORG_XF86 405272b676d7Smrg#ifdef TWDEBUG 405372b676d7Smrg xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n", 405472b676d7Smrg SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal, 405572b676d7Smrg SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal, 405672b676d7Smrg SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd); 405772b676d7Smrg xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", 405872b676d7Smrg SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1], 405972b676d7Smrg SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3], 406072b676d7Smrg SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5], 406172b676d7Smrg SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]); 406272b676d7Smrg xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n", 406372b676d7Smrg SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9], 406472b676d7Smrg SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11], 406572b676d7Smrg SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13], 406672b676d7Smrg SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]); 406772b676d7Smrg xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]); 406872b676d7Smrg#endif 406972b676d7Smrg#endif 407072b676d7Smrg} 407172b676d7Smrg 407272b676d7Smrgvoid 407372b676d7SmrgSiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, 407472b676d7Smrg int xres, int yres, 407572b676d7Smrg#ifdef SIS_XORG_XF86 407672b676d7Smrg DisplayModePtr current 407772b676d7Smrg#endif 407872b676d7Smrg#ifdef SIS_LINUX_KERNEL 407972b676d7Smrg struct fb_var_screeninfo *var, BOOLEAN writeres 408072b676d7Smrg#endif 408172b676d7Smrg) 408272b676d7Smrg{ 408372b676d7Smrg unsigned short HRE, HBE, HRS, HBS, HDE, HT; 408472b676d7Smrg unsigned short VRE, VBE, VRS, VBS, VDE, VT; 408572b676d7Smrg unsigned char sr_data, cr_data, cr_data2; 408672b676d7Smrg int A, B, C, D, E, F, temp; 408772b676d7Smrg 408872b676d7Smrg sr_data = crdata[14]; 408972b676d7Smrg 409072b676d7Smrg /* Horizontal total */ 409172b676d7Smrg HT = crdata[0] | ((unsigned short)(sr_data & 0x03) << 8); 409272b676d7Smrg A = HT + 5; 409372b676d7Smrg 409472b676d7Smrg /* Horizontal display enable end */ 409572b676d7Smrg HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6); 409672b676d7Smrg E = HDE + 1; 409772b676d7Smrg 409872b676d7Smrg /* Horizontal retrace (=sync) start */ 409972b676d7Smrg HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2); 410072b676d7Smrg F = HRS - E - 3; 410172b676d7Smrg 410272b676d7Smrg /* Horizontal blank start */ 410372b676d7Smrg HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4); 410472b676d7Smrg 410572b676d7Smrg sr_data = crdata[15]; 410672b676d7Smrg cr_data = crdata[5]; 410772b676d7Smrg 410872b676d7Smrg /* Horizontal blank end */ 410972b676d7Smrg HBE = (crdata[3] & 0x1f) | 411072b676d7Smrg ((unsigned short)(cr_data & 0x80) >> 2) | 411172b676d7Smrg ((unsigned short)(sr_data & 0x03) << 6); 411272b676d7Smrg 411372b676d7Smrg /* Horizontal retrace (=sync) end */ 411472b676d7Smrg HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3); 411572b676d7Smrg 411672b676d7Smrg temp = HBE - ((E - 1) & 255); 411772b676d7Smrg B = (temp > 0) ? temp : (temp + 256); 411872b676d7Smrg 411972b676d7Smrg temp = HRE - ((E + F + 3) & 63); 412072b676d7Smrg C = (temp > 0) ? temp : (temp + 64); 412172b676d7Smrg 412272b676d7Smrg D = B - F - C; 412372b676d7Smrg 412472b676d7Smrg#ifdef SIS_XORG_XF86 412572b676d7Smrg current->HDisplay = (E * 8); 412672b676d7Smrg current->HSyncStart = (E * 8) + (F * 8); 412772b676d7Smrg current->HSyncEnd = (E * 8) + (F * 8) + (C * 8); 412872b676d7Smrg current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8); 412972b676d7Smrg#ifdef TWDEBUG 413072b676d7Smrg xf86DrvMsg(0, X_INFO, 413172b676d7Smrg "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", 413272b676d7Smrg A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE); 413372b676d7Smrg#else 413472b676d7Smrg (void)VBS; (void)HBS; (void)A; 413572b676d7Smrg#endif 413672b676d7Smrg#endif 413772b676d7Smrg#ifdef SIS_LINUX_KERNEL 413872b676d7Smrg if(writeres) var->xres = xres = E * 8; 413972b676d7Smrg var->left_margin = D * 8; 414072b676d7Smrg var->right_margin = F * 8; 414172b676d7Smrg var->hsync_len = C * 8; 414272b676d7Smrg#endif 414372b676d7Smrg 414472b676d7Smrg /* Vertical */ 414572b676d7Smrg sr_data = crdata[13]; 414672b676d7Smrg cr_data = crdata[7]; 414772b676d7Smrg 414872b676d7Smrg /* Vertical total */ 414972b676d7Smrg VT = crdata[6] | 415072b676d7Smrg ((unsigned short)(cr_data & 0x01) << 8) | 415172b676d7Smrg ((unsigned short)(cr_data & 0x20) << 4) | 415272b676d7Smrg ((unsigned short)(sr_data & 0x01) << 10); 415372b676d7Smrg A = VT + 2; 415472b676d7Smrg 415572b676d7Smrg /* Vertical display enable end */ 415672b676d7Smrg VDE = crdata[10] | 415772b676d7Smrg ((unsigned short)(cr_data & 0x02) << 7) | 415872b676d7Smrg ((unsigned short)(cr_data & 0x40) << 3) | 415972b676d7Smrg ((unsigned short)(sr_data & 0x02) << 9); 416072b676d7Smrg E = VDE + 1; 416172b676d7Smrg 416272b676d7Smrg /* Vertical retrace (=sync) start */ 416372b676d7Smrg VRS = crdata[8] | 416472b676d7Smrg ((unsigned short)(cr_data & 0x04) << 6) | 416572b676d7Smrg ((unsigned short)(cr_data & 0x80) << 2) | 416672b676d7Smrg ((unsigned short)(sr_data & 0x08) << 7); 416772b676d7Smrg F = VRS + 1 - E; 416872b676d7Smrg 416972b676d7Smrg cr_data2 = (crdata[16] & 0x01) << 5; 417072b676d7Smrg 417172b676d7Smrg /* Vertical blank start */ 417272b676d7Smrg VBS = crdata[11] | 417372b676d7Smrg ((unsigned short)(cr_data & 0x08) << 5) | 417472b676d7Smrg ((unsigned short)(cr_data2 & 0x20) << 4) | 417572b676d7Smrg ((unsigned short)(sr_data & 0x04) << 8); 417672b676d7Smrg 417772b676d7Smrg /* Vertical blank end */ 417872b676d7Smrg VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4); 417972b676d7Smrg temp = VBE - ((E - 1) & 511); 418072b676d7Smrg B = (temp > 0) ? temp : (temp + 512); 418172b676d7Smrg 418272b676d7Smrg /* Vertical retrace (=sync) end */ 418372b676d7Smrg VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1); 418472b676d7Smrg temp = VRE - ((E + F - 1) & 31); 418572b676d7Smrg C = (temp > 0) ? temp : (temp + 32); 418672b676d7Smrg 418772b676d7Smrg D = B - F - C; 418872b676d7Smrg 418972b676d7Smrg#ifdef SIS_XORG_XF86 419072b676d7Smrg current->VDisplay = VDE + 1; 419172b676d7Smrg current->VSyncStart = VRS + 1; 419272b676d7Smrg current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1; 419372b676d7Smrg if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32; 419472b676d7Smrg current->VTotal = E + D + C + F; 419572b676d7Smrg#if 0 419672b676d7Smrg current->VDisplay = E; 419772b676d7Smrg current->VSyncStart = E + D; 419872b676d7Smrg current->VSyncEnd = E + D + C; 419972b676d7Smrg current->VTotal = E + D + C + F; 420072b676d7Smrg#endif 420172b676d7Smrg#ifdef TWDEBUG 420272b676d7Smrg xf86DrvMsg(0, X_INFO, 420372b676d7Smrg "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", 420472b676d7Smrg A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE); 420572b676d7Smrg#endif 420672b676d7Smrg#endif 420772b676d7Smrg#ifdef SIS_LINUX_KERNEL 420872b676d7Smrg if(writeres) var->yres = yres = E; 420972b676d7Smrg var->upper_margin = D; 421072b676d7Smrg var->lower_margin = F; 421172b676d7Smrg var->vsync_len = C; 421272b676d7Smrg#endif 421372b676d7Smrg 421472b676d7Smrg if((xres == 320) && ((yres == 200) || (yres == 240))) { 421572b676d7Smrg /* Terrible hack, but correct CRTC data for 421672b676d7Smrg * these modes only produces a black screen... 421772b676d7Smrg * (HRE is 0, leading into a too large C and 421872b676d7Smrg * a negative D. The CRT controller does not 421972b676d7Smrg * seem to like correcting HRE to 50) 422072b676d7Smrg */ 422172b676d7Smrg#ifdef SIS_XORG_XF86 422272b676d7Smrg current->HDisplay = 320; 422372b676d7Smrg current->HSyncStart = 328; 422472b676d7Smrg current->HSyncEnd = 376; 422572b676d7Smrg current->HTotal = 400; 422672b676d7Smrg#endif 422772b676d7Smrg#ifdef SIS_LINUX_KERNEL 422872b676d7Smrg var->left_margin = (400 - 376); 422972b676d7Smrg var->right_margin = (328 - 320); 423072b676d7Smrg var->hsync_len = (376 - 328); 423172b676d7Smrg#endif 423272b676d7Smrg 423372b676d7Smrg } 423472b676d7Smrg 423572b676d7Smrg} 423672b676d7Smrg 423772b676d7Smrg 423872b676d7Smrg 423972b676d7Smrg 4240