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