18c2ecf20Sopenharmony_ci/* $XFree86$ */
28c2ecf20Sopenharmony_ci/* $XdotOrg$ */
38c2ecf20Sopenharmony_ci/*
48c2ecf20Sopenharmony_ci * Mode initializing code (CRT1 section) for
58c2ecf20Sopenharmony_ci * for SiS 300/305/540/630/730,
68c2ecf20Sopenharmony_ci *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
78c2ecf20Sopenharmony_ci *     XGI Volari V3XT/V5/V8, Z7
88c2ecf20Sopenharmony_ci * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * If distributed as part of the Linux kernel, the following license terms
138c2ecf20Sopenharmony_ci * apply:
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * * This program is free software; you can redistribute it and/or modify
168c2ecf20Sopenharmony_ci * * it under the terms of the GNU General Public License as published by
178c2ecf20Sopenharmony_ci * * the Free Software Foundation; either version 2 of the named License,
188c2ecf20Sopenharmony_ci * * or any later version.
198c2ecf20Sopenharmony_ci * *
208c2ecf20Sopenharmony_ci * * This program is distributed in the hope that it will be useful,
218c2ecf20Sopenharmony_ci * * but WITHOUT ANY WARRANTY; without even the implied warranty of
228c2ecf20Sopenharmony_ci * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
238c2ecf20Sopenharmony_ci * * GNU General Public License for more details.
248c2ecf20Sopenharmony_ci * *
258c2ecf20Sopenharmony_ci * * You should have received a copy of the GNU General Public License
268c2ecf20Sopenharmony_ci * * along with this program; if not, write to the Free Software
278c2ecf20Sopenharmony_ci * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
288c2ecf20Sopenharmony_ci *
298c2ecf20Sopenharmony_ci * Otherwise, the following license terms apply:
308c2ecf20Sopenharmony_ci *
318c2ecf20Sopenharmony_ci * * Redistribution and use in source and binary forms, with or without
328c2ecf20Sopenharmony_ci * * modification, are permitted provided that the following conditions
338c2ecf20Sopenharmony_ci * * are met:
348c2ecf20Sopenharmony_ci * * 1) Redistributions of source code must retain the above copyright
358c2ecf20Sopenharmony_ci * *    notice, this list of conditions and the following disclaimer.
368c2ecf20Sopenharmony_ci * * 2) Redistributions in binary form must reproduce the above copyright
378c2ecf20Sopenharmony_ci * *    notice, this list of conditions and the following disclaimer in the
388c2ecf20Sopenharmony_ci * *    documentation and/or other materials provided with the distribution.
398c2ecf20Sopenharmony_ci * * 3) The name of the author may not be used to endorse or promote products
408c2ecf20Sopenharmony_ci * *    derived from this software without specific prior written permission.
418c2ecf20Sopenharmony_ci * *
428c2ecf20Sopenharmony_ci * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
438c2ecf20Sopenharmony_ci * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
448c2ecf20Sopenharmony_ci * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
458c2ecf20Sopenharmony_ci * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
468c2ecf20Sopenharmony_ci * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
478c2ecf20Sopenharmony_ci * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
488c2ecf20Sopenharmony_ci * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
498c2ecf20Sopenharmony_ci * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
508c2ecf20Sopenharmony_ci * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
518c2ecf20Sopenharmony_ci * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
528c2ecf20Sopenharmony_ci *
538c2ecf20Sopenharmony_ci * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
548c2ecf20Sopenharmony_ci *
558c2ecf20Sopenharmony_ci * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
568c2ecf20Sopenharmony_ci * Used by permission.
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci#include "init.h"
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
628c2ecf20Sopenharmony_ci#include "300vtbl.h"
638c2ecf20Sopenharmony_ci#endif
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
668c2ecf20Sopenharmony_ci#include "310vtbl.h"
678c2ecf20Sopenharmony_ci#endif
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci#if defined(ALLOC_PRAGMA)
708c2ecf20Sopenharmony_ci#pragma alloc_text(PAGE,SiSSetMode)
718c2ecf20Sopenharmony_ci#endif
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/*********************************************/
748c2ecf20Sopenharmony_ci/*         POINTER INITIALIZATION            */
758c2ecf20Sopenharmony_ci/*********************************************/
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
788c2ecf20Sopenharmony_cistatic void
798c2ecf20Sopenharmony_ciInitCommonPointer(struct SiS_Private *SiS_Pr)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci   SiS_Pr->SiS_SModeIDTable  = SiS_SModeIDTable;
828c2ecf20Sopenharmony_ci   SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
838c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
848c2ecf20Sopenharmony_ci   SiS_Pr->SiS_StandTable    = SiS_StandTable;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci   SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
878c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
888c2ecf20Sopenharmony_ci   SiS_Pr->SiS_HiTVSt1Timing  = SiS_HiTVSt1Timing;
898c2ecf20Sopenharmony_ci   SiS_Pr->SiS_HiTVSt2Timing  = SiS_HiTVSt2Timing;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci   SiS_Pr->SiS_HiTVExtTiming  = SiS_HiTVExtTiming;
928c2ecf20Sopenharmony_ci   SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
938c2ecf20Sopenharmony_ci   SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
948c2ecf20Sopenharmony_ci#if 0
958c2ecf20Sopenharmony_ci   SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
968c2ecf20Sopenharmony_ci   SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
978c2ecf20Sopenharmony_ci#endif
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci   SiS_Pr->SiS_StPALData   = SiS_StPALData;
1008c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtPALData  = SiS_ExtPALData;
1018c2ecf20Sopenharmony_ci   SiS_Pr->SiS_StNTSCData  = SiS_StNTSCData;
1028c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
1038c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St1HiTVData = SiS_StHiTVData;
1048c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
1058c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
1068c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St525iData  = SiS_StNTSCData;
1078c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St525pData  = SiS_St525pData;
1088c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St750pData  = SiS_St750pData;
1098c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData;
1108c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData;
1118c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Ext750pData = SiS_Ext750pData;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci   SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
1148c2ecf20Sopenharmony_ci   SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LCD1280x720Data      = SiS_LCD1280x720Data;
1178c2ecf20Sopenharmony_ci   SiS_Pr->SiS_StLCD1280x768_2Data  = SiS_StLCD1280x768_2Data;
1188c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
1198c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LCD1280x800Data      = SiS_LCD1280x800Data;
1208c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LCD1280x800_2Data    = SiS_LCD1280x800_2Data;
1218c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LCD1280x854Data      = SiS_LCD1280x854Data;
1228c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
1238c2ecf20Sopenharmony_ci   SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
1248c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
1258c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LCD1680x1050Data     = SiS_LCD1680x1050Data;
1268c2ecf20Sopenharmony_ci   SiS_Pr->SiS_StLCD1600x1200Data   = SiS_StLCD1600x1200Data;
1278c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
1288c2ecf20Sopenharmony_ci   SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS320x240Data_1   = SiS_LVDS320x240Data_1;
1318c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS320x240Data_2   = SiS_LVDS320x240Data_2;
1328c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
1338c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS800x600Data_1   = SiS_LVDS800x600Data_1;
1348c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS1024x600Data_1  = SiS_LVDS1024x600Data_1;
1358c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT1320x240_1     = SiS_LVDSCRT1320x240_1;
1388c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT1320x240_2     = SiS_LVDSCRT1320x240_2;
1398c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT1320x240_2_H   = SiS_LVDSCRT1320x240_2_H;
1408c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT1320x240_3     = SiS_LVDSCRT1320x240_3;
1418c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT1320x240_3_H   = SiS_LVDSCRT1320x240_3_H;
1428c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
1438c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
1448c2ecf20Sopenharmony_ci#if 0
1458c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
1468c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = SiS_LVDSCRT11024x600_1_H;
1478c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT11024x600_2    = SiS_LVDSCRT11024x600_2;
1488c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
1498c2ecf20Sopenharmony_ci#endif
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
1528c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* lowest value LVDS/LCDA */
1558c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* lowest value 301 */
1568c2ecf20Sopenharmony_ci}
1578c2ecf20Sopenharmony_ci#endif
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
1608c2ecf20Sopenharmony_cistatic void
1618c2ecf20Sopenharmony_ciInitTo300Pointer(struct SiS_Private *SiS_Pr)
1628c2ecf20Sopenharmony_ci{
1638c2ecf20Sopenharmony_ci   InitCommonPointer(SiS_Pr);
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
1668c2ecf20Sopenharmony_ci   SiS_Pr->SiS_EModeIDTable  = SiS300_EModeIDTable;
1678c2ecf20Sopenharmony_ci   SiS_Pr->SiS_RefIndex      = SiS300_RefIndex;
1688c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CRT1Table     = SiS300_CRT1Table;
1698c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_300) {
1708c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
1718c2ecf20Sopenharmony_ci   } else {
1728c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
1738c2ecf20Sopenharmony_ci   }
1748c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VCLKData      = SiS300_VCLKData;
1758c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VBVCLKData    = (struct SiS_VBVCLKData *)SiS300_VCLKData;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci   SiS_Pr->SiS_SR15  = SiS300_SR15;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelDelayTbl     = SiS300_PanelDelayTbl;
1808c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtLCD1024x768Data   = SiS300_ExtLCD1024x768Data;
1838c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St2LCD1024x768Data   = SiS300_St2LCD1024x768Data;
1848c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtLCD1280x1024Data  = SiS300_ExtLCD1280x1024Data;
1858c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St2LCD1280x1024Data  = SiS300_St2LCD1280x1024Data;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS300_CRT2Part2_1024x768_1;
1888c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CRT2Part2_1024x768_2  = SiS300_CRT2Part2_1024x768_2;
1898c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CRT2Part2_1024x768_3  = SiS300_CRT2Part2_1024x768_3;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVUPALData  = SiS300_CHTVUPALData;
1928c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVOPALData  = SiS300_CHTVOPALData;
1938c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData;    /* not supported on 300 series */
1948c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData;    /* not supported on 300 series */
1958c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData;  /* not supported on 300 series */
1968c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData;  /* not supported on 300 series */
1978c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS848x480Data_1   = SiS300_LVDS848x480Data_1;
2008c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDS848x480Data_2   = SiS300_LVDS848x480Data_2;
2018c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1;
2028c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1;
2038c2ecf20Sopenharmony_ci   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2;
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a;
2068c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a;
2078c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b;
2088c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
2118c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
2128c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1UPAL  = SiS300_CHTVCRT1UPAL;
2138c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1OPAL  = SiS300_CHTVCRT1OPAL;
2148c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL;
2158c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC;
2168c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC;
2178c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UPAL  = SiS300_CHTVReg_UPAL;
2188c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_OPAL  = SiS300_CHTVReg_OPAL;
2198c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC;  /* not supported on 300 series */
2208c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC;  /* not supported on 300 series */
2218c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL;   /* not supported on 300 series */
2228c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL;   /* not supported on 300 series */
2238c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL;
2248c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
2258c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
2268c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS300_CHTVVCLKUPAL;
2278c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS300_CHTVVCLKOPAL;
2288c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC;  /* not supported on 300 series */
2298c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC;  /* not supported on 300 series */
2308c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL;   /* not supported on 300 series */
2318c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
2328c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
2338c2ecf20Sopenharmony_ci}
2348c2ecf20Sopenharmony_ci#endif
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
2378c2ecf20Sopenharmony_cistatic void
2388c2ecf20Sopenharmony_ciInitTo310Pointer(struct SiS_Private *SiS_Pr)
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci   InitCommonPointer(SiS_Pr);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci   SiS_Pr->SiS_EModeIDTable  = SiS310_EModeIDTable;
2438c2ecf20Sopenharmony_ci   SiS_Pr->SiS_RefIndex      = SiS310_RefIndex;
2448c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CRT1Table     = SiS310_CRT1Table;
2458c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_340) {
2468c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340;  /* 340 + XGI */
2478c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType >= SIS_761) {
2488c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761;  /* 761 - preliminary */
2498c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType >= SIS_760) {
2508c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760;  /* 760 */
2518c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType >= SIS_661) {
2528c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660;  /* 661/741 */
2538c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType == SIS_330) {
2548c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330;  /* 330 */
2558c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType > SIS_315PRO) {
2568c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650;  /* 550, 650, 740 */
2578c2ecf20Sopenharmony_ci   } else {
2588c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315;  /* 315 */
2598c2ecf20Sopenharmony_ci   }
2608c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_340) {
2618c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
2628c2ecf20Sopenharmony_ci   } else {
2638c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
2648c2ecf20Sopenharmony_ci   }
2658c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VCLKData      = SiS310_VCLKData;
2668c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VBVCLKData    = SiS310_VBVCLKData;
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci   SiS_Pr->SiS_SR15  = SiS310_SR15;
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelDelayTbl     = SiS310_PanelDelayTbl;
2718c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St2LCD1024x768Data   = SiS310_St2LCD1024x768Data;
2748c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtLCD1024x768Data   = SiS310_ExtLCD1024x768Data;
2758c2ecf20Sopenharmony_ci   SiS_Pr->SiS_St2LCD1280x1024Data  = SiS310_St2LCD1280x1024Data;
2768c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ExtLCD1280x1024Data  = SiS310_ExtLCD1280x1024Data;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS310_CRT2Part2_1024x768_1;
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVUPALData  = SiS310_CHTVUPALData;
2818c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVOPALData  = SiS310_CHTVOPALData;
2828c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
2838c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData;
2848c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData;
2858c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
2868c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
2898c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
2908c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1UPAL  = SiS310_CHTVCRT1UPAL;
2918c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1OPAL  = SiS310_CHTVCRT1OPAL;
2928c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
2958c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
2968c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UPAL  = SiS310_CHTVReg_UPAL;
2978c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_OPAL  = SiS310_CHTVReg_OPAL;
2988c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM;
2998c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM;
3008c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN;
3018c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN;
3028c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL;
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
3058c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
3068c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
3078c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS310_CHTVVCLKOPAL;
3088c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
3098c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
3108c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
3118c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
3128c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
3138c2ecf20Sopenharmony_ci}
3148c2ecf20Sopenharmony_ci#endif
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cibool
3178c2ecf20Sopenharmony_ciSiSInitPtr(struct SiS_Private *SiS_Pr)
3188c2ecf20Sopenharmony_ci{
3198c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType < SIS_315H) {
3208c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
3218c2ecf20Sopenharmony_ci      InitTo300Pointer(SiS_Pr);
3228c2ecf20Sopenharmony_ci#else
3238c2ecf20Sopenharmony_ci      return false;
3248c2ecf20Sopenharmony_ci#endif
3258c2ecf20Sopenharmony_ci   } else {
3268c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
3278c2ecf20Sopenharmony_ci      InitTo310Pointer(SiS_Pr);
3288c2ecf20Sopenharmony_ci#else
3298c2ecf20Sopenharmony_ci      return false;
3308c2ecf20Sopenharmony_ci#endif
3318c2ecf20Sopenharmony_ci   }
3328c2ecf20Sopenharmony_ci   return true;
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci/*********************************************/
3368c2ecf20Sopenharmony_ci/*            HELPER: Get ModeID             */
3378c2ecf20Sopenharmony_ci/*********************************************/
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_cistatic
3408c2ecf20Sopenharmony_ciunsigned short
3418c2ecf20Sopenharmony_ciSiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
3428c2ecf20Sopenharmony_ci		int Depth, bool FSTN, int LCDwidth, int LCDheight)
3438c2ecf20Sopenharmony_ci{
3448c2ecf20Sopenharmony_ci   unsigned short ModeIndex = 0;
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci   switch(HDisplay)
3478c2ecf20Sopenharmony_ci   {
3488c2ecf20Sopenharmony_ci	case 320:
3498c2ecf20Sopenharmony_ci		if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
3508c2ecf20Sopenharmony_ci		else if(VDisplay == 240) {
3518c2ecf20Sopenharmony_ci			if((VBFlags & CRT2_LCD) && (FSTN))
3528c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_320x240_FSTN[Depth];
3538c2ecf20Sopenharmony_ci			else
3548c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_320x240[Depth];
3558c2ecf20Sopenharmony_ci		}
3568c2ecf20Sopenharmony_ci		break;
3578c2ecf20Sopenharmony_ci	case 400:
3588c2ecf20Sopenharmony_ci		if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDheight >= 600))) {
3598c2ecf20Sopenharmony_ci			if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
3608c2ecf20Sopenharmony_ci		}
3618c2ecf20Sopenharmony_ci		break;
3628c2ecf20Sopenharmony_ci	case 512:
3638c2ecf20Sopenharmony_ci		if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDheight >= 768))) {
3648c2ecf20Sopenharmony_ci			if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
3658c2ecf20Sopenharmony_ci		}
3668c2ecf20Sopenharmony_ci		break;
3678c2ecf20Sopenharmony_ci	case 640:
3688c2ecf20Sopenharmony_ci		if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
3698c2ecf20Sopenharmony_ci		else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
3708c2ecf20Sopenharmony_ci		break;
3718c2ecf20Sopenharmony_ci	case 720:
3728c2ecf20Sopenharmony_ci		if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
3738c2ecf20Sopenharmony_ci		else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
3748c2ecf20Sopenharmony_ci		break;
3758c2ecf20Sopenharmony_ci	case 768:
3768c2ecf20Sopenharmony_ci		if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
3778c2ecf20Sopenharmony_ci		break;
3788c2ecf20Sopenharmony_ci	case 800:
3798c2ecf20Sopenharmony_ci		if(VDisplay == 600)      ModeIndex = ModeIndex_800x600[Depth];
3808c2ecf20Sopenharmony_ci		else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
3818c2ecf20Sopenharmony_ci		break;
3828c2ecf20Sopenharmony_ci	case 848:
3838c2ecf20Sopenharmony_ci		if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
3848c2ecf20Sopenharmony_ci		break;
3858c2ecf20Sopenharmony_ci	case 856:
3868c2ecf20Sopenharmony_ci		if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
3878c2ecf20Sopenharmony_ci		break;
3888c2ecf20Sopenharmony_ci	case 960:
3898c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_315_VGA) {
3908c2ecf20Sopenharmony_ci			if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
3918c2ecf20Sopenharmony_ci			else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
3928c2ecf20Sopenharmony_ci		}
3938c2ecf20Sopenharmony_ci		break;
3948c2ecf20Sopenharmony_ci	case 1024:
3958c2ecf20Sopenharmony_ci		if(VDisplay == 576)      ModeIndex = ModeIndex_1024x576[Depth];
3968c2ecf20Sopenharmony_ci		else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
3978c2ecf20Sopenharmony_ci		else if(VGAEngine == SIS_300_VGA) {
3988c2ecf20Sopenharmony_ci			if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
3998c2ecf20Sopenharmony_ci		}
4008c2ecf20Sopenharmony_ci		break;
4018c2ecf20Sopenharmony_ci	case 1152:
4028c2ecf20Sopenharmony_ci		if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
4038c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_300_VGA) {
4048c2ecf20Sopenharmony_ci			if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
4058c2ecf20Sopenharmony_ci		}
4068c2ecf20Sopenharmony_ci		break;
4078c2ecf20Sopenharmony_ci	case 1280:
4088c2ecf20Sopenharmony_ci		switch(VDisplay) {
4098c2ecf20Sopenharmony_ci			case 720:
4108c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_1280x720[Depth];
4118c2ecf20Sopenharmony_ci				break;
4128c2ecf20Sopenharmony_ci			case 768:
4138c2ecf20Sopenharmony_ci				if(VGAEngine == SIS_300_VGA) {
4148c2ecf20Sopenharmony_ci					ModeIndex = ModeIndex_300_1280x768[Depth];
4158c2ecf20Sopenharmony_ci				} else {
4168c2ecf20Sopenharmony_ci					ModeIndex = ModeIndex_310_1280x768[Depth];
4178c2ecf20Sopenharmony_ci				}
4188c2ecf20Sopenharmony_ci				break;
4198c2ecf20Sopenharmony_ci			case 800:
4208c2ecf20Sopenharmony_ci				if(VGAEngine == SIS_315_VGA) {
4218c2ecf20Sopenharmony_ci					ModeIndex = ModeIndex_1280x800[Depth];
4228c2ecf20Sopenharmony_ci				}
4238c2ecf20Sopenharmony_ci				break;
4248c2ecf20Sopenharmony_ci			case 854:
4258c2ecf20Sopenharmony_ci				if(VGAEngine == SIS_315_VGA) {
4268c2ecf20Sopenharmony_ci					ModeIndex = ModeIndex_1280x854[Depth];
4278c2ecf20Sopenharmony_ci				}
4288c2ecf20Sopenharmony_ci				break;
4298c2ecf20Sopenharmony_ci			case 960:
4308c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_1280x960[Depth];
4318c2ecf20Sopenharmony_ci				break;
4328c2ecf20Sopenharmony_ci			case 1024:
4338c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_1280x1024[Depth];
4348c2ecf20Sopenharmony_ci				break;
4358c2ecf20Sopenharmony_ci		}
4368c2ecf20Sopenharmony_ci		break;
4378c2ecf20Sopenharmony_ci	case 1360:
4388c2ecf20Sopenharmony_ci		if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
4398c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_300_VGA) {
4408c2ecf20Sopenharmony_ci			if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
4418c2ecf20Sopenharmony_ci		}
4428c2ecf20Sopenharmony_ci		break;
4438c2ecf20Sopenharmony_ci	case 1400:
4448c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_315_VGA) {
4458c2ecf20Sopenharmony_ci			if(VDisplay == 1050) {
4468c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_1400x1050[Depth];
4478c2ecf20Sopenharmony_ci			}
4488c2ecf20Sopenharmony_ci		}
4498c2ecf20Sopenharmony_ci		break;
4508c2ecf20Sopenharmony_ci	case 1600:
4518c2ecf20Sopenharmony_ci		if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
4528c2ecf20Sopenharmony_ci		break;
4538c2ecf20Sopenharmony_ci	case 1680:
4548c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_315_VGA) {
4558c2ecf20Sopenharmony_ci			if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
4568c2ecf20Sopenharmony_ci		}
4578c2ecf20Sopenharmony_ci		break;
4588c2ecf20Sopenharmony_ci	case 1920:
4598c2ecf20Sopenharmony_ci		if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
4608c2ecf20Sopenharmony_ci		else if(VGAEngine == SIS_315_VGA) {
4618c2ecf20Sopenharmony_ci			if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
4628c2ecf20Sopenharmony_ci		}
4638c2ecf20Sopenharmony_ci		break;
4648c2ecf20Sopenharmony_ci	case 2048:
4658c2ecf20Sopenharmony_ci		if(VDisplay == 1536) {
4668c2ecf20Sopenharmony_ci			if(VGAEngine == SIS_300_VGA) {
4678c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_300_2048x1536[Depth];
4688c2ecf20Sopenharmony_ci			} else {
4698c2ecf20Sopenharmony_ci				ModeIndex = ModeIndex_310_2048x1536[Depth];
4708c2ecf20Sopenharmony_ci			}
4718c2ecf20Sopenharmony_ci		}
4728c2ecf20Sopenharmony_ci		break;
4738c2ecf20Sopenharmony_ci   }
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci   return ModeIndex;
4768c2ecf20Sopenharmony_ci}
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ciunsigned short
4798c2ecf20Sopenharmony_ciSiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
4808c2ecf20Sopenharmony_ci		int Depth, bool FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
4818c2ecf20Sopenharmony_ci		unsigned int VBFlags2)
4828c2ecf20Sopenharmony_ci{
4838c2ecf20Sopenharmony_ci   unsigned short ModeIndex = 0;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci   if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) {
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci      switch(HDisplay)
4888c2ecf20Sopenharmony_ci      {
4898c2ecf20Sopenharmony_ci	case 320:
4908c2ecf20Sopenharmony_ci	     if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
4918c2ecf20Sopenharmony_ci		if(VDisplay == 200) {
4928c2ecf20Sopenharmony_ci		   if(!FSTN) ModeIndex = ModeIndex_320x200[Depth];
4938c2ecf20Sopenharmony_ci		} else if(VDisplay == 240) {
4948c2ecf20Sopenharmony_ci		   if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
4958c2ecf20Sopenharmony_ci		   else if(VGAEngine == SIS_315_VGA) {
4968c2ecf20Sopenharmony_ci		      ModeIndex = ModeIndex_320x240_FSTN[Depth];
4978c2ecf20Sopenharmony_ci		   }
4988c2ecf20Sopenharmony_ci		}
4998c2ecf20Sopenharmony_ci	     }
5008c2ecf20Sopenharmony_ci	     break;
5018c2ecf20Sopenharmony_ci	case 400:
5028c2ecf20Sopenharmony_ci	     if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
5038c2ecf20Sopenharmony_ci		if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
5048c2ecf20Sopenharmony_ci		   if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
5058c2ecf20Sopenharmony_ci		}
5068c2ecf20Sopenharmony_ci	     }
5078c2ecf20Sopenharmony_ci	     break;
5088c2ecf20Sopenharmony_ci	case 512:
5098c2ecf20Sopenharmony_ci	     if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
5108c2ecf20Sopenharmony_ci		if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
5118c2ecf20Sopenharmony_ci		   if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
5128c2ecf20Sopenharmony_ci		      if(VDisplay == 384) {
5138c2ecf20Sopenharmony_ci		         ModeIndex = ModeIndex_512x384[Depth];
5148c2ecf20Sopenharmony_ci		      }
5158c2ecf20Sopenharmony_ci		   }
5168c2ecf20Sopenharmony_ci		}
5178c2ecf20Sopenharmony_ci	     }
5188c2ecf20Sopenharmony_ci	     break;
5198c2ecf20Sopenharmony_ci	case 640:
5208c2ecf20Sopenharmony_ci	     if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
5218c2ecf20Sopenharmony_ci	     else if(VDisplay == 400) {
5228c2ecf20Sopenharmony_ci		if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856))
5238c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_640x400[Depth];
5248c2ecf20Sopenharmony_ci	     }
5258c2ecf20Sopenharmony_ci	     break;
5268c2ecf20Sopenharmony_ci	case 800:
5278c2ecf20Sopenharmony_ci	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
5288c2ecf20Sopenharmony_ci	     break;
5298c2ecf20Sopenharmony_ci	case 848:
5308c2ecf20Sopenharmony_ci	     if(CustomT == CUT_PANEL848) {
5318c2ecf20Sopenharmony_ci	        if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
5328c2ecf20Sopenharmony_ci	     }
5338c2ecf20Sopenharmony_ci	     break;
5348c2ecf20Sopenharmony_ci	case 856:
5358c2ecf20Sopenharmony_ci	     if(CustomT == CUT_PANEL856) {
5368c2ecf20Sopenharmony_ci	        if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
5378c2ecf20Sopenharmony_ci	     }
5388c2ecf20Sopenharmony_ci	     break;
5398c2ecf20Sopenharmony_ci	case 1024:
5408c2ecf20Sopenharmony_ci	     if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
5418c2ecf20Sopenharmony_ci	     else if(VGAEngine == SIS_300_VGA) {
5428c2ecf20Sopenharmony_ci		if((VDisplay == 600) && (LCDheight == 600)) {
5438c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1024x600[Depth];
5448c2ecf20Sopenharmony_ci		}
5458c2ecf20Sopenharmony_ci	     }
5468c2ecf20Sopenharmony_ci	     break;
5478c2ecf20Sopenharmony_ci	case 1152:
5488c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_300_VGA) {
5498c2ecf20Sopenharmony_ci		if((VDisplay == 768) && (LCDheight == 768)) {
5508c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1152x768[Depth];
5518c2ecf20Sopenharmony_ci		}
5528c2ecf20Sopenharmony_ci	     }
5538c2ecf20Sopenharmony_ci	     break;
5548c2ecf20Sopenharmony_ci        case 1280:
5558c2ecf20Sopenharmony_ci	     if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
5568c2ecf20Sopenharmony_ci	     else if(VGAEngine == SIS_315_VGA) {
5578c2ecf20Sopenharmony_ci		if((VDisplay == 768) && (LCDheight == 768)) {
5588c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_310_1280x768[Depth];
5598c2ecf20Sopenharmony_ci		}
5608c2ecf20Sopenharmony_ci	     }
5618c2ecf20Sopenharmony_ci	     break;
5628c2ecf20Sopenharmony_ci	case 1360:
5638c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_300_VGA) {
5648c2ecf20Sopenharmony_ci		if(CustomT == CUT_BARCO1366) {
5658c2ecf20Sopenharmony_ci		   if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
5668c2ecf20Sopenharmony_ci		}
5678c2ecf20Sopenharmony_ci	     }
5688c2ecf20Sopenharmony_ci	     if(CustomT == CUT_PANEL848) {
5698c2ecf20Sopenharmony_ci		if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
5708c2ecf20Sopenharmony_ci	     }
5718c2ecf20Sopenharmony_ci	     break;
5728c2ecf20Sopenharmony_ci	case 1400:
5738c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
5748c2ecf20Sopenharmony_ci		if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
5758c2ecf20Sopenharmony_ci	     }
5768c2ecf20Sopenharmony_ci	     break;
5778c2ecf20Sopenharmony_ci	case 1600:
5788c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
5798c2ecf20Sopenharmony_ci		if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
5808c2ecf20Sopenharmony_ci	     }
5818c2ecf20Sopenharmony_ci	     break;
5828c2ecf20Sopenharmony_ci      }
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci   } else if(VBFlags2 & VB2_SISBRIDGE) {
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ci      switch(HDisplay)
5878c2ecf20Sopenharmony_ci      {
5888c2ecf20Sopenharmony_ci	case 320:
5898c2ecf20Sopenharmony_ci	     if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
5908c2ecf20Sopenharmony_ci	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
5918c2ecf20Sopenharmony_ci	     break;
5928c2ecf20Sopenharmony_ci	case 400:
5938c2ecf20Sopenharmony_ci	     if(LCDwidth >= 800 && LCDheight >= 600) {
5948c2ecf20Sopenharmony_ci		if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
5958c2ecf20Sopenharmony_ci	     }
5968c2ecf20Sopenharmony_ci	     break;
5978c2ecf20Sopenharmony_ci	case 512:
5988c2ecf20Sopenharmony_ci	     if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
5998c2ecf20Sopenharmony_ci		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
6008c2ecf20Sopenharmony_ci	     }
6018c2ecf20Sopenharmony_ci	     break;
6028c2ecf20Sopenharmony_ci	case 640:
6038c2ecf20Sopenharmony_ci	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
6048c2ecf20Sopenharmony_ci	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
6058c2ecf20Sopenharmony_ci	     break;
6068c2ecf20Sopenharmony_ci	case 720:
6078c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6088c2ecf20Sopenharmony_ci		if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
6098c2ecf20Sopenharmony_ci		else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
6108c2ecf20Sopenharmony_ci	     }
6118c2ecf20Sopenharmony_ci	     break;
6128c2ecf20Sopenharmony_ci	case 768:
6138c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6148c2ecf20Sopenharmony_ci		if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
6158c2ecf20Sopenharmony_ci	     }
6168c2ecf20Sopenharmony_ci	     break;
6178c2ecf20Sopenharmony_ci	case 800:
6188c2ecf20Sopenharmony_ci	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
6198c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6208c2ecf20Sopenharmony_ci		if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
6218c2ecf20Sopenharmony_ci	     }
6228c2ecf20Sopenharmony_ci	     break;
6238c2ecf20Sopenharmony_ci	case 848:
6248c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6258c2ecf20Sopenharmony_ci		if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
6268c2ecf20Sopenharmony_ci	     }
6278c2ecf20Sopenharmony_ci	     break;
6288c2ecf20Sopenharmony_ci	case 856:
6298c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6308c2ecf20Sopenharmony_ci		if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
6318c2ecf20Sopenharmony_ci	     }
6328c2ecf20Sopenharmony_ci	     break;
6338c2ecf20Sopenharmony_ci	case 960:
6348c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6358c2ecf20Sopenharmony_ci		if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
6368c2ecf20Sopenharmony_ci		else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
6378c2ecf20Sopenharmony_ci	     }
6388c2ecf20Sopenharmony_ci	     break;
6398c2ecf20Sopenharmony_ci	case 1024:
6408c2ecf20Sopenharmony_ci	     if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
6418c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6428c2ecf20Sopenharmony_ci		if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
6438c2ecf20Sopenharmony_ci	     }
6448c2ecf20Sopenharmony_ci	     break;
6458c2ecf20Sopenharmony_ci	case 1152:
6468c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6478c2ecf20Sopenharmony_ci		if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
6488c2ecf20Sopenharmony_ci	     }
6498c2ecf20Sopenharmony_ci	     break;
6508c2ecf20Sopenharmony_ci	case 1280:
6518c2ecf20Sopenharmony_ci	     switch(VDisplay) {
6528c2ecf20Sopenharmony_ci	     case 720:
6538c2ecf20Sopenharmony_ci		ModeIndex = ModeIndex_1280x720[Depth];
6548c2ecf20Sopenharmony_ci		break;
6558c2ecf20Sopenharmony_ci	     case 768:
6568c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_300_VGA) {
6578c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_300_1280x768[Depth];
6588c2ecf20Sopenharmony_ci		} else {
6598c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_310_1280x768[Depth];
6608c2ecf20Sopenharmony_ci		}
6618c2ecf20Sopenharmony_ci		break;
6628c2ecf20Sopenharmony_ci	     case 800:
6638c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_315_VGA) {
6648c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1280x800[Depth];
6658c2ecf20Sopenharmony_ci		}
6668c2ecf20Sopenharmony_ci		break;
6678c2ecf20Sopenharmony_ci	     case 854:
6688c2ecf20Sopenharmony_ci		if(VGAEngine == SIS_315_VGA) {
6698c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1280x854[Depth];
6708c2ecf20Sopenharmony_ci		}
6718c2ecf20Sopenharmony_ci		break;
6728c2ecf20Sopenharmony_ci	     case 960:
6738c2ecf20Sopenharmony_ci		ModeIndex = ModeIndex_1280x960[Depth];
6748c2ecf20Sopenharmony_ci		break;
6758c2ecf20Sopenharmony_ci	     case 1024:
6768c2ecf20Sopenharmony_ci		ModeIndex = ModeIndex_1280x1024[Depth];
6778c2ecf20Sopenharmony_ci		break;
6788c2ecf20Sopenharmony_ci	     }
6798c2ecf20Sopenharmony_ci	     break;
6808c2ecf20Sopenharmony_ci	case 1360:
6818c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {  /* OVER1280 only? */
6828c2ecf20Sopenharmony_ci		if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
6838c2ecf20Sopenharmony_ci	     }
6848c2ecf20Sopenharmony_ci	     break;
6858c2ecf20Sopenharmony_ci	case 1400:
6868c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6878c2ecf20Sopenharmony_ci		if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
6888c2ecf20Sopenharmony_ci		   if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
6898c2ecf20Sopenharmony_ci		}
6908c2ecf20Sopenharmony_ci	     }
6918c2ecf20Sopenharmony_ci	     break;
6928c2ecf20Sopenharmony_ci	case 1600:
6938c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
6948c2ecf20Sopenharmony_ci		if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
6958c2ecf20Sopenharmony_ci		   if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
6968c2ecf20Sopenharmony_ci		}
6978c2ecf20Sopenharmony_ci	     }
6988c2ecf20Sopenharmony_ci	     break;
6998c2ecf20Sopenharmony_ci#ifndef VB_FORBID_CRT2LCD_OVER_1600
7008c2ecf20Sopenharmony_ci	case 1680:
7018c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
7028c2ecf20Sopenharmony_ci		if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
7038c2ecf20Sopenharmony_ci		   if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
7048c2ecf20Sopenharmony_ci		}
7058c2ecf20Sopenharmony_ci	     }
7068c2ecf20Sopenharmony_ci	     break;
7078c2ecf20Sopenharmony_ci	case 1920:
7088c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
7098c2ecf20Sopenharmony_ci		if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
7108c2ecf20Sopenharmony_ci		   if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
7118c2ecf20Sopenharmony_ci		}
7128c2ecf20Sopenharmony_ci	     }
7138c2ecf20Sopenharmony_ci	     break;
7148c2ecf20Sopenharmony_ci	case 2048:
7158c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
7168c2ecf20Sopenharmony_ci		if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
7178c2ecf20Sopenharmony_ci		   if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
7188c2ecf20Sopenharmony_ci		}
7198c2ecf20Sopenharmony_ci	     }
7208c2ecf20Sopenharmony_ci	     break;
7218c2ecf20Sopenharmony_ci#endif
7228c2ecf20Sopenharmony_ci      }
7238c2ecf20Sopenharmony_ci   }
7248c2ecf20Sopenharmony_ci
7258c2ecf20Sopenharmony_ci   return ModeIndex;
7268c2ecf20Sopenharmony_ci}
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_ciunsigned short
7298c2ecf20Sopenharmony_ciSiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
7308c2ecf20Sopenharmony_ci			unsigned int VBFlags2)
7318c2ecf20Sopenharmony_ci{
7328c2ecf20Sopenharmony_ci   unsigned short ModeIndex = 0;
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_ci   if(VBFlags2 & VB2_CHRONTEL) {
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_ci      switch(HDisplay)
7378c2ecf20Sopenharmony_ci      {
7388c2ecf20Sopenharmony_ci	case 512:
7398c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
7408c2ecf20Sopenharmony_ci		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
7418c2ecf20Sopenharmony_ci	     }
7428c2ecf20Sopenharmony_ci	     break;
7438c2ecf20Sopenharmony_ci	case 640:
7448c2ecf20Sopenharmony_ci	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
7458c2ecf20Sopenharmony_ci	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
7468c2ecf20Sopenharmony_ci	     break;
7478c2ecf20Sopenharmony_ci	case 800:
7488c2ecf20Sopenharmony_ci	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
7498c2ecf20Sopenharmony_ci	     break;
7508c2ecf20Sopenharmony_ci	case 1024:
7518c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
7528c2ecf20Sopenharmony_ci		if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
7538c2ecf20Sopenharmony_ci	     }
7548c2ecf20Sopenharmony_ci	     break;
7558c2ecf20Sopenharmony_ci      }
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_ci   } else if(VBFlags2 & VB2_SISTVBRIDGE) {
7588c2ecf20Sopenharmony_ci
7598c2ecf20Sopenharmony_ci      switch(HDisplay)
7608c2ecf20Sopenharmony_ci      {
7618c2ecf20Sopenharmony_ci	case 320:
7628c2ecf20Sopenharmony_ci	     if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
7638c2ecf20Sopenharmony_ci	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
7648c2ecf20Sopenharmony_ci	     break;
7658c2ecf20Sopenharmony_ci	case 400:
7668c2ecf20Sopenharmony_ci	     if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
7678c2ecf20Sopenharmony_ci	     break;
7688c2ecf20Sopenharmony_ci	case 512:
7698c2ecf20Sopenharmony_ci	     if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
7708c2ecf20Sopenharmony_ci		 (VBFlags & TV_HIVISION) 					      ||
7718c2ecf20Sopenharmony_ci		 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
7728c2ecf20Sopenharmony_ci		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
7738c2ecf20Sopenharmony_ci	     }
7748c2ecf20Sopenharmony_ci	     break;
7758c2ecf20Sopenharmony_ci	case 640:
7768c2ecf20Sopenharmony_ci	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
7778c2ecf20Sopenharmony_ci	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
7788c2ecf20Sopenharmony_ci	     break;
7798c2ecf20Sopenharmony_ci	case 720:
7808c2ecf20Sopenharmony_ci	     if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
7818c2ecf20Sopenharmony_ci		if(VDisplay == 480) {
7828c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_720x480[Depth];
7838c2ecf20Sopenharmony_ci		} else if(VDisplay == 576) {
7848c2ecf20Sopenharmony_ci		   if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
7858c2ecf20Sopenharmony_ci		       ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
7868c2ecf20Sopenharmony_ci		      ModeIndex = ModeIndex_720x576[Depth];
7878c2ecf20Sopenharmony_ci		}
7888c2ecf20Sopenharmony_ci	     }
7898c2ecf20Sopenharmony_ci             break;
7908c2ecf20Sopenharmony_ci	case 768:
7918c2ecf20Sopenharmony_ci	     if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
7928c2ecf20Sopenharmony_ci		if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
7938c2ecf20Sopenharmony_ci		    ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
7948c2ecf20Sopenharmony_ci		   if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
7958c2ecf20Sopenharmony_ci		}
7968c2ecf20Sopenharmony_ci             }
7978c2ecf20Sopenharmony_ci	     break;
7988c2ecf20Sopenharmony_ci	case 800:
7998c2ecf20Sopenharmony_ci	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
8008c2ecf20Sopenharmony_ci	     else if(VDisplay == 480) {
8018c2ecf20Sopenharmony_ci		if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
8028c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_800x480[Depth];
8038c2ecf20Sopenharmony_ci		}
8048c2ecf20Sopenharmony_ci	     }
8058c2ecf20Sopenharmony_ci	     break;
8068c2ecf20Sopenharmony_ci	case 960:
8078c2ecf20Sopenharmony_ci	     if(VGAEngine == SIS_315_VGA) {
8088c2ecf20Sopenharmony_ci		if(VDisplay == 600) {
8098c2ecf20Sopenharmony_ci		   if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
8108c2ecf20Sopenharmony_ci		      ModeIndex = ModeIndex_960x600[Depth];
8118c2ecf20Sopenharmony_ci		   }
8128c2ecf20Sopenharmony_ci		}
8138c2ecf20Sopenharmony_ci	     }
8148c2ecf20Sopenharmony_ci	     break;
8158c2ecf20Sopenharmony_ci	case 1024:
8168c2ecf20Sopenharmony_ci	     if(VDisplay == 768) {
8178c2ecf20Sopenharmony_ci		if(VBFlags2 & VB2_30xBLV) {
8188c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1024x768[Depth];
8198c2ecf20Sopenharmony_ci		}
8208c2ecf20Sopenharmony_ci	     } else if(VDisplay == 576) {
8218c2ecf20Sopenharmony_ci		if( (VBFlags & TV_HIVISION) ||
8228c2ecf20Sopenharmony_ci		    ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
8238c2ecf20Sopenharmony_ci		    ((VBFlags2 & VB2_30xBLV) &&
8248c2ecf20Sopenharmony_ci		     ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
8258c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1024x576[Depth];
8268c2ecf20Sopenharmony_ci		}
8278c2ecf20Sopenharmony_ci	     }
8288c2ecf20Sopenharmony_ci	     break;
8298c2ecf20Sopenharmony_ci	case 1280:
8308c2ecf20Sopenharmony_ci	     if(VDisplay == 720) {
8318c2ecf20Sopenharmony_ci		if((VBFlags & TV_HIVISION) ||
8328c2ecf20Sopenharmony_ci		   ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
8338c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1280x720[Depth];
8348c2ecf20Sopenharmony_ci		}
8358c2ecf20Sopenharmony_ci	     } else if(VDisplay == 1024) {
8368c2ecf20Sopenharmony_ci		if((VBFlags & TV_HIVISION) ||
8378c2ecf20Sopenharmony_ci		   ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
8388c2ecf20Sopenharmony_ci		   ModeIndex = ModeIndex_1280x1024[Depth];
8398c2ecf20Sopenharmony_ci		}
8408c2ecf20Sopenharmony_ci	     }
8418c2ecf20Sopenharmony_ci	     break;
8428c2ecf20Sopenharmony_ci      }
8438c2ecf20Sopenharmony_ci   }
8448c2ecf20Sopenharmony_ci   return ModeIndex;
8458c2ecf20Sopenharmony_ci}
8468c2ecf20Sopenharmony_ci
8478c2ecf20Sopenharmony_ciunsigned short
8488c2ecf20Sopenharmony_ciSiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
8498c2ecf20Sopenharmony_ci			unsigned int VBFlags2)
8508c2ecf20Sopenharmony_ci{
8518c2ecf20Sopenharmony_ci   if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
8528c2ecf20Sopenharmony_ci
8538c2ecf20Sopenharmony_ci   if(HDisplay >= 1920) return 0;
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ci   switch(HDisplay)
8568c2ecf20Sopenharmony_ci   {
8578c2ecf20Sopenharmony_ci	case 1600:
8588c2ecf20Sopenharmony_ci		if(VDisplay == 1200) {
8598c2ecf20Sopenharmony_ci			if(VGAEngine != SIS_315_VGA) return 0;
8608c2ecf20Sopenharmony_ci			if(!(VBFlags2 & VB2_30xB)) return 0;
8618c2ecf20Sopenharmony_ci		}
8628c2ecf20Sopenharmony_ci		break;
8638c2ecf20Sopenharmony_ci	case 1680:
8648c2ecf20Sopenharmony_ci		if(VDisplay == 1050) {
8658c2ecf20Sopenharmony_ci			if(VGAEngine != SIS_315_VGA) return 0;
8668c2ecf20Sopenharmony_ci			if(!(VBFlags2 & VB2_30xB)) return 0;
8678c2ecf20Sopenharmony_ci		}
8688c2ecf20Sopenharmony_ci		break;
8698c2ecf20Sopenharmony_ci   }
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_ci   return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, false, 0, 0);
8728c2ecf20Sopenharmony_ci}
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci
8758c2ecf20Sopenharmony_ci/*********************************************/
8768c2ecf20Sopenharmony_ci/*          HELPER: SetReg, GetReg           */
8778c2ecf20Sopenharmony_ci/*********************************************/
8788c2ecf20Sopenharmony_ci
8798c2ecf20Sopenharmony_civoid
8808c2ecf20Sopenharmony_ciSiS_SetReg(SISIOADDRESS port, u8 index, u8 data)
8818c2ecf20Sopenharmony_ci{
8828c2ecf20Sopenharmony_ci	outb(index, port);
8838c2ecf20Sopenharmony_ci	outb(data, port + 1);
8848c2ecf20Sopenharmony_ci}
8858c2ecf20Sopenharmony_ci
8868c2ecf20Sopenharmony_civoid
8878c2ecf20Sopenharmony_ciSiS_SetRegByte(SISIOADDRESS port, u8 data)
8888c2ecf20Sopenharmony_ci{
8898c2ecf20Sopenharmony_ci	outb(data, port);
8908c2ecf20Sopenharmony_ci}
8918c2ecf20Sopenharmony_ci
8928c2ecf20Sopenharmony_civoid
8938c2ecf20Sopenharmony_ciSiS_SetRegShort(SISIOADDRESS port, u16 data)
8948c2ecf20Sopenharmony_ci{
8958c2ecf20Sopenharmony_ci	outw(data, port);
8968c2ecf20Sopenharmony_ci}
8978c2ecf20Sopenharmony_ci
8988c2ecf20Sopenharmony_civoid
8998c2ecf20Sopenharmony_ciSiS_SetRegLong(SISIOADDRESS port, u32 data)
9008c2ecf20Sopenharmony_ci{
9018c2ecf20Sopenharmony_ci	outl(data, port);
9028c2ecf20Sopenharmony_ci}
9038c2ecf20Sopenharmony_ci
9048c2ecf20Sopenharmony_ciu8
9058c2ecf20Sopenharmony_ciSiS_GetReg(SISIOADDRESS port, u8 index)
9068c2ecf20Sopenharmony_ci{
9078c2ecf20Sopenharmony_ci	outb(index, port);
9088c2ecf20Sopenharmony_ci	return inb(port + 1);
9098c2ecf20Sopenharmony_ci}
9108c2ecf20Sopenharmony_ci
9118c2ecf20Sopenharmony_ciu8
9128c2ecf20Sopenharmony_ciSiS_GetRegByte(SISIOADDRESS port)
9138c2ecf20Sopenharmony_ci{
9148c2ecf20Sopenharmony_ci	return inb(port);
9158c2ecf20Sopenharmony_ci}
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ciu16
9188c2ecf20Sopenharmony_ciSiS_GetRegShort(SISIOADDRESS port)
9198c2ecf20Sopenharmony_ci{
9208c2ecf20Sopenharmony_ci	return inw(port);
9218c2ecf20Sopenharmony_ci}
9228c2ecf20Sopenharmony_ci
9238c2ecf20Sopenharmony_ciu32
9248c2ecf20Sopenharmony_ciSiS_GetRegLong(SISIOADDRESS port)
9258c2ecf20Sopenharmony_ci{
9268c2ecf20Sopenharmony_ci	return inl(port);
9278c2ecf20Sopenharmony_ci}
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_civoid
9308c2ecf20Sopenharmony_ciSiS_SetRegANDOR(SISIOADDRESS Port, u8 Index, u8 DataAND, u8 DataOR)
9318c2ecf20Sopenharmony_ci{
9328c2ecf20Sopenharmony_ci   u8 temp;
9338c2ecf20Sopenharmony_ci
9348c2ecf20Sopenharmony_ci   temp = SiS_GetReg(Port, Index);
9358c2ecf20Sopenharmony_ci   temp = (temp & (DataAND)) | DataOR;
9368c2ecf20Sopenharmony_ci   SiS_SetReg(Port, Index, temp);
9378c2ecf20Sopenharmony_ci}
9388c2ecf20Sopenharmony_ci
9398c2ecf20Sopenharmony_civoid
9408c2ecf20Sopenharmony_ciSiS_SetRegAND(SISIOADDRESS Port, u8 Index, u8 DataAND)
9418c2ecf20Sopenharmony_ci{
9428c2ecf20Sopenharmony_ci   u8 temp;
9438c2ecf20Sopenharmony_ci
9448c2ecf20Sopenharmony_ci   temp = SiS_GetReg(Port, Index);
9458c2ecf20Sopenharmony_ci   temp &= DataAND;
9468c2ecf20Sopenharmony_ci   SiS_SetReg(Port, Index, temp);
9478c2ecf20Sopenharmony_ci}
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_civoid
9508c2ecf20Sopenharmony_ciSiS_SetRegOR(SISIOADDRESS Port, u8 Index, u8 DataOR)
9518c2ecf20Sopenharmony_ci{
9528c2ecf20Sopenharmony_ci   u8 temp;
9538c2ecf20Sopenharmony_ci
9548c2ecf20Sopenharmony_ci   temp = SiS_GetReg(Port, Index);
9558c2ecf20Sopenharmony_ci   temp |= DataOR;
9568c2ecf20Sopenharmony_ci   SiS_SetReg(Port, Index, temp);
9578c2ecf20Sopenharmony_ci}
9588c2ecf20Sopenharmony_ci
9598c2ecf20Sopenharmony_ci/*********************************************/
9608c2ecf20Sopenharmony_ci/*      HELPER: DisplayOn, DisplayOff        */
9618c2ecf20Sopenharmony_ci/*********************************************/
9628c2ecf20Sopenharmony_ci
9638c2ecf20Sopenharmony_civoid
9648c2ecf20Sopenharmony_ciSiS_DisplayOn(struct SiS_Private *SiS_Pr)
9658c2ecf20Sopenharmony_ci{
9668c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
9678c2ecf20Sopenharmony_ci}
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_civoid
9708c2ecf20Sopenharmony_ciSiS_DisplayOff(struct SiS_Private *SiS_Pr)
9718c2ecf20Sopenharmony_ci{
9728c2ecf20Sopenharmony_ci   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
9738c2ecf20Sopenharmony_ci}
9748c2ecf20Sopenharmony_ci
9758c2ecf20Sopenharmony_ci
9768c2ecf20Sopenharmony_ci/*********************************************/
9778c2ecf20Sopenharmony_ci/*        HELPER: Init Port Addresses        */
9788c2ecf20Sopenharmony_ci/*********************************************/
9798c2ecf20Sopenharmony_ci
9808c2ecf20Sopenharmony_civoid
9818c2ecf20Sopenharmony_ciSiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
9828c2ecf20Sopenharmony_ci{
9838c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
9848c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
9858c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
9868c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
9878c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
9888c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
9898c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
9908c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
9918c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
9928c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
9938c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
9948c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
9958c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
9968c2ecf20Sopenharmony_ci   SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
9978c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
9988c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
9998c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
10008c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
10018c2ecf20Sopenharmony_ci   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
10028c2ecf20Sopenharmony_ci   SiS_Pr->SiS_DDC_Port  = BaseAddr + 0x14;
10038c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VidCapt   = BaseAddr + SIS_VIDEO_CAPTURE;
10048c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VidPlay   = BaseAddr + SIS_VIDEO_PLAYBACK;
10058c2ecf20Sopenharmony_ci}
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci/*********************************************/
10088c2ecf20Sopenharmony_ci/*             HELPER: GetSysFlags           */
10098c2ecf20Sopenharmony_ci/*********************************************/
10108c2ecf20Sopenharmony_ci
10118c2ecf20Sopenharmony_cistatic void
10128c2ecf20Sopenharmony_ciSiS_GetSysFlags(struct SiS_Private *SiS_Pr)
10138c2ecf20Sopenharmony_ci{
10148c2ecf20Sopenharmony_ci   unsigned char cr5f, temp1, temp2;
10158c2ecf20Sopenharmony_ci
10168c2ecf20Sopenharmony_ci   /* 661 and newer: NEVER write non-zero to SR11[7:4] */
10178c2ecf20Sopenharmony_ci   /* (SR11 is used for DDC and in enable/disablebridge) */
10188c2ecf20Sopenharmony_ci   SiS_Pr->SiS_SensibleSR11 = false;
10198c2ecf20Sopenharmony_ci   SiS_Pr->SiS_MyCR63 = 0x63;
10208c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_330) {
10218c2ecf20Sopenharmony_ci      SiS_Pr->SiS_MyCR63 = 0x53;
10228c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType >= SIS_661) {
10238c2ecf20Sopenharmony_ci         SiS_Pr->SiS_SensibleSR11 = true;
10248c2ecf20Sopenharmony_ci      }
10258c2ecf20Sopenharmony_ci   }
10268c2ecf20Sopenharmony_ci
10278c2ecf20Sopenharmony_ci   /* You should use the macros, not these flags directly */
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci   SiS_Pr->SiS_SysFlags = 0;
10308c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_650) {
10318c2ecf20Sopenharmony_ci      cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
10328c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
10338c2ecf20Sopenharmony_ci      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
10348c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
10358c2ecf20Sopenharmony_ci      temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
10368c2ecf20Sopenharmony_ci      if((!temp1) || (temp2)) {
10378c2ecf20Sopenharmony_ci	 switch(cr5f) {
10388c2ecf20Sopenharmony_ci	    case 0x80:
10398c2ecf20Sopenharmony_ci	    case 0x90:
10408c2ecf20Sopenharmony_ci	    case 0xc0:
10418c2ecf20Sopenharmony_ci	       SiS_Pr->SiS_SysFlags |= SF_IsM650;
10428c2ecf20Sopenharmony_ci	       break;
10438c2ecf20Sopenharmony_ci	    case 0xa0:
10448c2ecf20Sopenharmony_ci	    case 0xb0:
10458c2ecf20Sopenharmony_ci	    case 0xe0:
10468c2ecf20Sopenharmony_ci	       SiS_Pr->SiS_SysFlags |= SF_Is651;
10478c2ecf20Sopenharmony_ci	       break;
10488c2ecf20Sopenharmony_ci	 }
10498c2ecf20Sopenharmony_ci      } else {
10508c2ecf20Sopenharmony_ci	 switch(cr5f) {
10518c2ecf20Sopenharmony_ci	    case 0x90:
10528c2ecf20Sopenharmony_ci	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
10538c2ecf20Sopenharmony_ci	       switch(temp1) {
10548c2ecf20Sopenharmony_ci		  case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
10558c2ecf20Sopenharmony_ci		  case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
10568c2ecf20Sopenharmony_ci		  default:   SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
10578c2ecf20Sopenharmony_ci	       }
10588c2ecf20Sopenharmony_ci	       break;
10598c2ecf20Sopenharmony_ci	    case 0xb0:
10608c2ecf20Sopenharmony_ci	       SiS_Pr->SiS_SysFlags |= SF_Is652;
10618c2ecf20Sopenharmony_ci	       break;
10628c2ecf20Sopenharmony_ci	    default:
10638c2ecf20Sopenharmony_ci	       SiS_Pr->SiS_SysFlags |= SF_IsM650;
10648c2ecf20Sopenharmony_ci	       break;
10658c2ecf20Sopenharmony_ci	 }
10668c2ecf20Sopenharmony_ci      }
10678c2ecf20Sopenharmony_ci   }
10688c2ecf20Sopenharmony_ci
10698c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
10708c2ecf20Sopenharmony_ci      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
10718c2ecf20Sopenharmony_ci         SiS_Pr->SiS_SysFlags |= SF_760LFB;
10728c2ecf20Sopenharmony_ci      }
10738c2ecf20Sopenharmony_ci      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
10748c2ecf20Sopenharmony_ci         SiS_Pr->SiS_SysFlags |= SF_760UMA;
10758c2ecf20Sopenharmony_ci      }
10768c2ecf20Sopenharmony_ci   }
10778c2ecf20Sopenharmony_ci}
10788c2ecf20Sopenharmony_ci
10798c2ecf20Sopenharmony_ci/*********************************************/
10808c2ecf20Sopenharmony_ci/*         HELPER: Init PCI & Engines        */
10818c2ecf20Sopenharmony_ci/*********************************************/
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_cistatic void
10848c2ecf20Sopenharmony_ciSiSInitPCIetc(struct SiS_Private *SiS_Pr)
10858c2ecf20Sopenharmony_ci{
10868c2ecf20Sopenharmony_ci   switch(SiS_Pr->ChipType) {
10878c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
10888c2ecf20Sopenharmony_ci   case SIS_300:
10898c2ecf20Sopenharmony_ci   case SIS_540:
10908c2ecf20Sopenharmony_ci   case SIS_630:
10918c2ecf20Sopenharmony_ci   case SIS_730:
10928c2ecf20Sopenharmony_ci      /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
10938c2ecf20Sopenharmony_ci       *     - RELOCATED VGA IO ENABLED (0x20)
10948c2ecf20Sopenharmony_ci       *     - MMIO ENABLED (0x01)
10958c2ecf20Sopenharmony_ci       * Leave other bits untouched.
10968c2ecf20Sopenharmony_ci       */
10978c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
10988c2ecf20Sopenharmony_ci      /*  - Enable 2D (0x40)
10998c2ecf20Sopenharmony_ci       *  - Enable 3D (0x02)
11008c2ecf20Sopenharmony_ci       *  - Enable 3D Vertex command fetch (0x10) ?
11018c2ecf20Sopenharmony_ci       *  - Enable 3D command parser (0x08) ?
11028c2ecf20Sopenharmony_ci       */
11038c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
11048c2ecf20Sopenharmony_ci      break;
11058c2ecf20Sopenharmony_ci#endif
11068c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
11078c2ecf20Sopenharmony_ci   case SIS_315H:
11088c2ecf20Sopenharmony_ci   case SIS_315:
11098c2ecf20Sopenharmony_ci   case SIS_315PRO:
11108c2ecf20Sopenharmony_ci   case SIS_650:
11118c2ecf20Sopenharmony_ci   case SIS_740:
11128c2ecf20Sopenharmony_ci   case SIS_330:
11138c2ecf20Sopenharmony_ci   case SIS_661:
11148c2ecf20Sopenharmony_ci   case SIS_741:
11158c2ecf20Sopenharmony_ci   case SIS_660:
11168c2ecf20Sopenharmony_ci   case SIS_760:
11178c2ecf20Sopenharmony_ci   case SIS_761:
11188c2ecf20Sopenharmony_ci   case SIS_340:
11198c2ecf20Sopenharmony_ci   case XGI_40:
11208c2ecf20Sopenharmony_ci      /* See above */
11218c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
11228c2ecf20Sopenharmony_ci      /*  - Enable 3D G/L transformation engine (0x80)
11238c2ecf20Sopenharmony_ci       *  - Enable 2D (0x40)
11248c2ecf20Sopenharmony_ci       *  - Enable 3D vertex command fetch (0x10)
11258c2ecf20Sopenharmony_ci       *  - Enable 3D command parser (0x08)
11268c2ecf20Sopenharmony_ci       *  - Enable 3D (0x02)
11278c2ecf20Sopenharmony_ci       */
11288c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
11298c2ecf20Sopenharmony_ci      break;
11308c2ecf20Sopenharmony_ci   case XGI_20:
11318c2ecf20Sopenharmony_ci   case SIS_550:
11328c2ecf20Sopenharmony_ci      /* See above */
11338c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
11348c2ecf20Sopenharmony_ci      /* No 3D engine ! */
11358c2ecf20Sopenharmony_ci      /*  - Enable 2D (0x40)
11368c2ecf20Sopenharmony_ci       *  - disable 3D
11378c2ecf20Sopenharmony_ci       */
11388c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
11398c2ecf20Sopenharmony_ci      break;
11408c2ecf20Sopenharmony_ci#endif
11418c2ecf20Sopenharmony_ci   default:
11428c2ecf20Sopenharmony_ci      break;
11438c2ecf20Sopenharmony_ci   }
11448c2ecf20Sopenharmony_ci}
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci/*********************************************/
11478c2ecf20Sopenharmony_ci/*             HELPER: SetLVDSetc            */
11488c2ecf20Sopenharmony_ci/*********************************************/
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_cistatic
11518c2ecf20Sopenharmony_civoid
11528c2ecf20Sopenharmony_ciSiSSetLVDSetc(struct SiS_Private *SiS_Pr)
11538c2ecf20Sopenharmony_ci{
11548c2ecf20Sopenharmony_ci   unsigned short temp;
11558c2ecf20Sopenharmony_ci
11568c2ecf20Sopenharmony_ci   SiS_Pr->SiS_IF_DEF_LVDS = 0;
11578c2ecf20Sopenharmony_ci   SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
11588c2ecf20Sopenharmony_ci   SiS_Pr->SiS_IF_DEF_CH70xx = 0;
11598c2ecf20Sopenharmony_ci   SiS_Pr->SiS_IF_DEF_CONEX = 0;
11608c2ecf20Sopenharmony_ci
11618c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ChrontelInit = 0;
11628c2ecf20Sopenharmony_ci
11638c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == XGI_20) return;
11648c2ecf20Sopenharmony_ci
11658c2ecf20Sopenharmony_ci   /* Check for SiS30x first */
11668c2ecf20Sopenharmony_ci   temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
11678c2ecf20Sopenharmony_ci   if((temp == 1) || (temp == 2)) return;
11688c2ecf20Sopenharmony_ci
11698c2ecf20Sopenharmony_ci   switch(SiS_Pr->ChipType) {
11708c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
11718c2ecf20Sopenharmony_ci   case SIS_540:
11728c2ecf20Sopenharmony_ci   case SIS_630:
11738c2ecf20Sopenharmony_ci   case SIS_730:
11748c2ecf20Sopenharmony_ci	temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
11758c2ecf20Sopenharmony_ci	if((temp >= 2) && (temp <= 5))	SiS_Pr->SiS_IF_DEF_LVDS = 1;
11768c2ecf20Sopenharmony_ci	if(temp == 3)			SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
11778c2ecf20Sopenharmony_ci	if((temp == 4) || (temp == 5)) {
11788c2ecf20Sopenharmony_ci		/* Save power status (and error check) - UNUSED */
11798c2ecf20Sopenharmony_ci		SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
11808c2ecf20Sopenharmony_ci		SiS_Pr->SiS_IF_DEF_CH70xx = 1;
11818c2ecf20Sopenharmony_ci	}
11828c2ecf20Sopenharmony_ci	break;
11838c2ecf20Sopenharmony_ci#endif
11848c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
11858c2ecf20Sopenharmony_ci   case SIS_550:
11868c2ecf20Sopenharmony_ci   case SIS_650:
11878c2ecf20Sopenharmony_ci   case SIS_740:
11888c2ecf20Sopenharmony_ci   case SIS_330:
11898c2ecf20Sopenharmony_ci	temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
11908c2ecf20Sopenharmony_ci	if((temp >= 2) && (temp <= 3))	SiS_Pr->SiS_IF_DEF_LVDS = 1;
11918c2ecf20Sopenharmony_ci	if(temp == 3)			SiS_Pr->SiS_IF_DEF_CH70xx = 2;
11928c2ecf20Sopenharmony_ci	break;
11938c2ecf20Sopenharmony_ci   case SIS_661:
11948c2ecf20Sopenharmony_ci   case SIS_741:
11958c2ecf20Sopenharmony_ci   case SIS_660:
11968c2ecf20Sopenharmony_ci   case SIS_760:
11978c2ecf20Sopenharmony_ci   case SIS_761:
11988c2ecf20Sopenharmony_ci   case SIS_340:
11998c2ecf20Sopenharmony_ci   case XGI_20:
12008c2ecf20Sopenharmony_ci   case XGI_40:
12018c2ecf20Sopenharmony_ci	temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
12028c2ecf20Sopenharmony_ci	if((temp >= 2) && (temp <= 3)) 	SiS_Pr->SiS_IF_DEF_LVDS = 1;
12038c2ecf20Sopenharmony_ci	if(temp == 3)			SiS_Pr->SiS_IF_DEF_CH70xx = 2;
12048c2ecf20Sopenharmony_ci	if(temp == 4)			SiS_Pr->SiS_IF_DEF_CONEX = 1;  /* Not yet supported */
12058c2ecf20Sopenharmony_ci	break;
12068c2ecf20Sopenharmony_ci#endif
12078c2ecf20Sopenharmony_ci   default:
12088c2ecf20Sopenharmony_ci	break;
12098c2ecf20Sopenharmony_ci   }
12108c2ecf20Sopenharmony_ci}
12118c2ecf20Sopenharmony_ci
12128c2ecf20Sopenharmony_ci/*********************************************/
12138c2ecf20Sopenharmony_ci/*          HELPER: Enable DSTN/FSTN         */
12148c2ecf20Sopenharmony_ci/*********************************************/
12158c2ecf20Sopenharmony_ci
12168c2ecf20Sopenharmony_civoid
12178c2ecf20Sopenharmony_ciSiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
12188c2ecf20Sopenharmony_ci{
12198c2ecf20Sopenharmony_ci   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
12208c2ecf20Sopenharmony_ci}
12218c2ecf20Sopenharmony_ci
12228c2ecf20Sopenharmony_civoid
12238c2ecf20Sopenharmony_ciSiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
12248c2ecf20Sopenharmony_ci{
12258c2ecf20Sopenharmony_ci   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
12268c2ecf20Sopenharmony_ci}
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_ci/*********************************************/
12298c2ecf20Sopenharmony_ci/*            HELPER: Get modeflag           */
12308c2ecf20Sopenharmony_ci/*********************************************/
12318c2ecf20Sopenharmony_ci
12328c2ecf20Sopenharmony_ciunsigned short
12338c2ecf20Sopenharmony_ciSiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
12348c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex)
12358c2ecf20Sopenharmony_ci{
12368c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
12378c2ecf20Sopenharmony_ci      return SiS_Pr->CModeFlag;
12388c2ecf20Sopenharmony_ci   } else if(ModeNo <= 0x13) {
12398c2ecf20Sopenharmony_ci      return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
12408c2ecf20Sopenharmony_ci   } else {
12418c2ecf20Sopenharmony_ci      return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
12428c2ecf20Sopenharmony_ci   }
12438c2ecf20Sopenharmony_ci}
12448c2ecf20Sopenharmony_ci
12458c2ecf20Sopenharmony_ci/*********************************************/
12468c2ecf20Sopenharmony_ci/*        HELPER: Determine ROM usage        */
12478c2ecf20Sopenharmony_ci/*********************************************/
12488c2ecf20Sopenharmony_ci
12498c2ecf20Sopenharmony_cibool
12508c2ecf20Sopenharmony_ciSiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
12518c2ecf20Sopenharmony_ci{
12528c2ecf20Sopenharmony_ci   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
12538c2ecf20Sopenharmony_ci   unsigned short romversoffs, romvmaj = 1, romvmin = 0;
12548c2ecf20Sopenharmony_ci
12558c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= XGI_20) {
12568c2ecf20Sopenharmony_ci      /* XGI ROMs don't qualify */
12578c2ecf20Sopenharmony_ci      return false;
12588c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType >= SIS_761) {
12598c2ecf20Sopenharmony_ci      /* I very much assume 761, 340 and newer will use new layout */
12608c2ecf20Sopenharmony_ci      return true;
12618c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType >= SIS_661) {
12628c2ecf20Sopenharmony_ci      if((ROMAddr[0x1a] == 'N') &&
12638c2ecf20Sopenharmony_ci	 (ROMAddr[0x1b] == 'e') &&
12648c2ecf20Sopenharmony_ci	 (ROMAddr[0x1c] == 'w') &&
12658c2ecf20Sopenharmony_ci	 (ROMAddr[0x1d] == 'V')) {
12668c2ecf20Sopenharmony_ci	 return true;
12678c2ecf20Sopenharmony_ci      }
12688c2ecf20Sopenharmony_ci      romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
12698c2ecf20Sopenharmony_ci      if(romversoffs) {
12708c2ecf20Sopenharmony_ci	 if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
12718c2ecf20Sopenharmony_ci	    romvmaj = ROMAddr[romversoffs] - '0';
12728c2ecf20Sopenharmony_ci	    romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
12738c2ecf20Sopenharmony_ci	 }
12748c2ecf20Sopenharmony_ci      }
12758c2ecf20Sopenharmony_ci      if((romvmaj != 0) || (romvmin >= 92)) {
12768c2ecf20Sopenharmony_ci	 return true;
12778c2ecf20Sopenharmony_ci      }
12788c2ecf20Sopenharmony_ci   } else if(IS_SIS650740) {
12798c2ecf20Sopenharmony_ci      if((ROMAddr[0x1a] == 'N') &&
12808c2ecf20Sopenharmony_ci	 (ROMAddr[0x1b] == 'e') &&
12818c2ecf20Sopenharmony_ci	 (ROMAddr[0x1c] == 'w') &&
12828c2ecf20Sopenharmony_ci	 (ROMAddr[0x1d] == 'V')) {
12838c2ecf20Sopenharmony_ci	 return true;
12848c2ecf20Sopenharmony_ci      }
12858c2ecf20Sopenharmony_ci   }
12868c2ecf20Sopenharmony_ci   return false;
12878c2ecf20Sopenharmony_ci}
12888c2ecf20Sopenharmony_ci
12898c2ecf20Sopenharmony_cistatic void
12908c2ecf20Sopenharmony_ciSiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
12918c2ecf20Sopenharmony_ci{
12928c2ecf20Sopenharmony_ci   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
12938c2ecf20Sopenharmony_ci   unsigned short romptr = 0;
12948c2ecf20Sopenharmony_ci
12958c2ecf20Sopenharmony_ci   SiS_Pr->SiS_UseROM = false;
12968c2ecf20Sopenharmony_ci   SiS_Pr->SiS_ROMNew = false;
12978c2ecf20Sopenharmony_ci   SiS_Pr->SiS_PWDOffset = 0;
12988c2ecf20Sopenharmony_ci
12998c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= XGI_20) return;
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_ci   if((ROMAddr) && (SiS_Pr->UseROM)) {
13028c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType == SIS_300) {
13038c2ecf20Sopenharmony_ci	 /* 300: We check if the code starts below 0x220 by
13048c2ecf20Sopenharmony_ci	  * checking the jmp instruction at the beginning
13058c2ecf20Sopenharmony_ci	  * of the BIOS image.
13068c2ecf20Sopenharmony_ci	  */
13078c2ecf20Sopenharmony_ci	 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
13088c2ecf20Sopenharmony_ci	    SiS_Pr->SiS_UseROM = true;
13098c2ecf20Sopenharmony_ci      } else if(SiS_Pr->ChipType < SIS_315H) {
13108c2ecf20Sopenharmony_ci	 /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
13118c2ecf20Sopenharmony_ci	  * the others do as well
13128c2ecf20Sopenharmony_ci	  */
13138c2ecf20Sopenharmony_ci	 SiS_Pr->SiS_UseROM = true;
13148c2ecf20Sopenharmony_ci      } else {
13158c2ecf20Sopenharmony_ci	 /* 315/330 series stick to the standard(s) */
13168c2ecf20Sopenharmony_ci	 SiS_Pr->SiS_UseROM = true;
13178c2ecf20Sopenharmony_ci	 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
13188c2ecf20Sopenharmony_ci	    SiS_Pr->SiS_EMIOffset = 14;
13198c2ecf20Sopenharmony_ci	    SiS_Pr->SiS_PWDOffset = 17;
13208c2ecf20Sopenharmony_ci	    SiS_Pr->SiS661LCD2TableSize = 36;
13218c2ecf20Sopenharmony_ci	    /* Find out about LCD data table entry size */
13228c2ecf20Sopenharmony_ci	    if((romptr = SISGETROMW(0x0102))) {
13238c2ecf20Sopenharmony_ci	       if(ROMAddr[romptr + (32 * 16)] == 0xff)
13248c2ecf20Sopenharmony_ci		  SiS_Pr->SiS661LCD2TableSize = 32;
13258c2ecf20Sopenharmony_ci	       else if(ROMAddr[romptr + (34 * 16)] == 0xff)
13268c2ecf20Sopenharmony_ci		  SiS_Pr->SiS661LCD2TableSize = 34;
13278c2ecf20Sopenharmony_ci	       else if(ROMAddr[romptr + (36 * 16)] == 0xff)	   /* 0.94, 2.05.00+ */
13288c2ecf20Sopenharmony_ci		  SiS_Pr->SiS661LCD2TableSize = 36;
13298c2ecf20Sopenharmony_ci	       else if( (ROMAddr[romptr + (38 * 16)] == 0xff) ||   /* 2.00.00 - 2.02.00 */
13308c2ecf20Sopenharmony_ci		 	(ROMAddr[0x6F] & 0x01) ) {		   /* 2.03.00 - <2.05.00 */
13318c2ecf20Sopenharmony_ci		  SiS_Pr->SiS661LCD2TableSize = 38;		   /* UMC data layout abandoned at 2.05.00 */
13328c2ecf20Sopenharmony_ci		  SiS_Pr->SiS_EMIOffset = 16;
13338c2ecf20Sopenharmony_ci		  SiS_Pr->SiS_PWDOffset = 19;
13348c2ecf20Sopenharmony_ci	       }
13358c2ecf20Sopenharmony_ci	    }
13368c2ecf20Sopenharmony_ci	 }
13378c2ecf20Sopenharmony_ci      }
13388c2ecf20Sopenharmony_ci   }
13398c2ecf20Sopenharmony_ci}
13408c2ecf20Sopenharmony_ci
13418c2ecf20Sopenharmony_ci/*********************************************/
13428c2ecf20Sopenharmony_ci/*        HELPER: SET SEGMENT REGISTERS      */
13438c2ecf20Sopenharmony_ci/*********************************************/
13448c2ecf20Sopenharmony_ci
13458c2ecf20Sopenharmony_cistatic void
13468c2ecf20Sopenharmony_ciSiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
13478c2ecf20Sopenharmony_ci{
13488c2ecf20Sopenharmony_ci   unsigned short temp;
13498c2ecf20Sopenharmony_ci
13508c2ecf20Sopenharmony_ci   value &= 0x00ff;
13518c2ecf20Sopenharmony_ci   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
13528c2ecf20Sopenharmony_ci   temp |= (value >> 4);
13538c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
13548c2ecf20Sopenharmony_ci   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0;
13558c2ecf20Sopenharmony_ci   temp |= (value & 0x0f);
13568c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
13578c2ecf20Sopenharmony_ci}
13588c2ecf20Sopenharmony_ci
13598c2ecf20Sopenharmony_cistatic void
13608c2ecf20Sopenharmony_ciSiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
13618c2ecf20Sopenharmony_ci{
13628c2ecf20Sopenharmony_ci   unsigned short temp;
13638c2ecf20Sopenharmony_ci
13648c2ecf20Sopenharmony_ci   value &= 0x00ff;
13658c2ecf20Sopenharmony_ci   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
13668c2ecf20Sopenharmony_ci   temp |= (value & 0xf0);
13678c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
13688c2ecf20Sopenharmony_ci   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f;
13698c2ecf20Sopenharmony_ci   temp |= (value << 4);
13708c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
13718c2ecf20Sopenharmony_ci}
13728c2ecf20Sopenharmony_ci
13738c2ecf20Sopenharmony_cistatic void
13748c2ecf20Sopenharmony_ciSiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
13758c2ecf20Sopenharmony_ci{
13768c2ecf20Sopenharmony_ci   SiS_SetSegRegLower(SiS_Pr, value);
13778c2ecf20Sopenharmony_ci   SiS_SetSegRegUpper(SiS_Pr, value);
13788c2ecf20Sopenharmony_ci}
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_cistatic void
13818c2ecf20Sopenharmony_ciSiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
13828c2ecf20Sopenharmony_ci{
13838c2ecf20Sopenharmony_ci   SiS_SetSegmentReg(SiS_Pr, 0);
13848c2ecf20Sopenharmony_ci}
13858c2ecf20Sopenharmony_ci
13868c2ecf20Sopenharmony_cistatic void
13878c2ecf20Sopenharmony_ciSiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
13888c2ecf20Sopenharmony_ci{
13898c2ecf20Sopenharmony_ci   unsigned short temp = value >> 8;
13908c2ecf20Sopenharmony_ci
13918c2ecf20Sopenharmony_ci   temp &= 0x07;
13928c2ecf20Sopenharmony_ci   temp |= (temp << 4);
13938c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
13948c2ecf20Sopenharmony_ci   SiS_SetSegmentReg(SiS_Pr, value);
13958c2ecf20Sopenharmony_ci}
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_cistatic void
13988c2ecf20Sopenharmony_ciSiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
13998c2ecf20Sopenharmony_ci{
14008c2ecf20Sopenharmony_ci   SiS_SetSegmentRegOver(SiS_Pr, 0);
14018c2ecf20Sopenharmony_ci}
14028c2ecf20Sopenharmony_ci
14038c2ecf20Sopenharmony_cistatic void
14048c2ecf20Sopenharmony_ciSiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
14058c2ecf20Sopenharmony_ci{
14068c2ecf20Sopenharmony_ci   if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
14078c2ecf20Sopenharmony_ci      SiS_ResetSegmentReg(SiS_Pr);
14088c2ecf20Sopenharmony_ci      SiS_ResetSegmentRegOver(SiS_Pr);
14098c2ecf20Sopenharmony_ci   }
14108c2ecf20Sopenharmony_ci}
14118c2ecf20Sopenharmony_ci
14128c2ecf20Sopenharmony_ci/*********************************************/
14138c2ecf20Sopenharmony_ci/*             HELPER: GetVBType             */
14148c2ecf20Sopenharmony_ci/*********************************************/
14158c2ecf20Sopenharmony_ci
14168c2ecf20Sopenharmony_cistatic
14178c2ecf20Sopenharmony_civoid
14188c2ecf20Sopenharmony_ciSiS_GetVBType(struct SiS_Private *SiS_Pr)
14198c2ecf20Sopenharmony_ci{
14208c2ecf20Sopenharmony_ci   unsigned short flag = 0, rev = 0, nolcd = 0;
14218c2ecf20Sopenharmony_ci   unsigned short p4_0f, p4_25, p4_27;
14228c2ecf20Sopenharmony_ci
14238c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VBType = 0;
14248c2ecf20Sopenharmony_ci
14258c2ecf20Sopenharmony_ci   if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
14268c2ecf20Sopenharmony_ci      return;
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == XGI_20)
14298c2ecf20Sopenharmony_ci      return;
14308c2ecf20Sopenharmony_ci
14318c2ecf20Sopenharmony_ci   flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ci   if(flag > 3)
14348c2ecf20Sopenharmony_ci      return;
14358c2ecf20Sopenharmony_ci
14368c2ecf20Sopenharmony_ci   rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_ci   if(flag >= 2) {
14398c2ecf20Sopenharmony_ci      SiS_Pr->SiS_VBType = VB_SIS302B;
14408c2ecf20Sopenharmony_ci   } else if(flag == 1) {
14418c2ecf20Sopenharmony_ci      if(rev >= 0xC0) {
14428c2ecf20Sopenharmony_ci	 SiS_Pr->SiS_VBType = VB_SIS301C;
14438c2ecf20Sopenharmony_ci      } else if(rev >= 0xB0) {
14448c2ecf20Sopenharmony_ci	 SiS_Pr->SiS_VBType = VB_SIS301B;
14458c2ecf20Sopenharmony_ci	 /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
14468c2ecf20Sopenharmony_ci	 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
14478c2ecf20Sopenharmony_ci	 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
14488c2ecf20Sopenharmony_ci      } else {
14498c2ecf20Sopenharmony_ci	 SiS_Pr->SiS_VBType = VB_SIS301;
14508c2ecf20Sopenharmony_ci      }
14518c2ecf20Sopenharmony_ci   }
14528c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
14538c2ecf20Sopenharmony_ci      if(rev >= 0xE0) {
14548c2ecf20Sopenharmony_ci	 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
14558c2ecf20Sopenharmony_ci	 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
14568c2ecf20Sopenharmony_ci	 else 	 	  SiS_Pr->SiS_VBType = VB_SIS301C;  /* VB_SIS302ELV; */
14578c2ecf20Sopenharmony_ci      } else if(rev >= 0xD0) {
14588c2ecf20Sopenharmony_ci	 SiS_Pr->SiS_VBType = VB_SIS301LV;
14598c2ecf20Sopenharmony_ci      }
14608c2ecf20Sopenharmony_ci   }
14618c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
14628c2ecf20Sopenharmony_ci      p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
14638c2ecf20Sopenharmony_ci      p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
14648c2ecf20Sopenharmony_ci      p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
14658c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
14668c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
14678c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
14688c2ecf20Sopenharmony_ci      if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
14698c2ecf20Sopenharmony_ci         SiS_Pr->SiS_VBType |= VB_UMC;
14708c2ecf20Sopenharmony_ci      }
14718c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
14728c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
14738c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
14748c2ecf20Sopenharmony_ci   }
14758c2ecf20Sopenharmony_ci}
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_ci/*********************************************/
14788c2ecf20Sopenharmony_ci/*           HELPER: Check RAM size          */
14798c2ecf20Sopenharmony_ci/*********************************************/
14808c2ecf20Sopenharmony_ci
14818c2ecf20Sopenharmony_cistatic bool
14828c2ecf20Sopenharmony_ciSiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
14838c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex)
14848c2ecf20Sopenharmony_ci{
14858c2ecf20Sopenharmony_ci   unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
14868c2ecf20Sopenharmony_ci   unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
14878c2ecf20Sopenharmony_ci   unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
14888c2ecf20Sopenharmony_ci
14898c2ecf20Sopenharmony_ci   if(!AdapterMemSize) return true;
14908c2ecf20Sopenharmony_ci
14918c2ecf20Sopenharmony_ci   if(AdapterMemSize < memorysize) return false;
14928c2ecf20Sopenharmony_ci   return true;
14938c2ecf20Sopenharmony_ci}
14948c2ecf20Sopenharmony_ci
14958c2ecf20Sopenharmony_ci/*********************************************/
14968c2ecf20Sopenharmony_ci/*           HELPER: Get DRAM type           */
14978c2ecf20Sopenharmony_ci/*********************************************/
14988c2ecf20Sopenharmony_ci
14998c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
15008c2ecf20Sopenharmony_cistatic unsigned char
15018c2ecf20Sopenharmony_ciSiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
15028c2ecf20Sopenharmony_ci{
15038c2ecf20Sopenharmony_ci   unsigned char data;
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_ci   if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
15068c2ecf20Sopenharmony_ci      data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
15078c2ecf20Sopenharmony_ci   } else {
15088c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType >= XGI_20) {
15098c2ecf20Sopenharmony_ci         /* Do I need this? SR17 seems to be zero anyway... */
15108c2ecf20Sopenharmony_ci	 data = 0;
15118c2ecf20Sopenharmony_ci      } else if(SiS_Pr->ChipType >= SIS_340) {
15128c2ecf20Sopenharmony_ci	 /* TODO */
15138c2ecf20Sopenharmony_ci	 data = 0;
15148c2ecf20Sopenharmony_ci      } else if(SiS_Pr->ChipType >= SIS_661) {
15158c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_ROMNew) {
15168c2ecf20Sopenharmony_ci	    data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
15178c2ecf20Sopenharmony_ci	 } else {
15188c2ecf20Sopenharmony_ci	    data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
15198c2ecf20Sopenharmony_ci	 }
15208c2ecf20Sopenharmony_ci      } else if(IS_SIS550650740) {
15218c2ecf20Sopenharmony_ci	 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
15228c2ecf20Sopenharmony_ci      } else {	/* 315, 330 */
15238c2ecf20Sopenharmony_ci	 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
15248c2ecf20Sopenharmony_ci	 if(SiS_Pr->ChipType == SIS_330) {
15258c2ecf20Sopenharmony_ci	    if(data > 1) {
15268c2ecf20Sopenharmony_ci	       switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
15278c2ecf20Sopenharmony_ci	       case 0x00: data = 1; break;
15288c2ecf20Sopenharmony_ci	       case 0x10: data = 3; break;
15298c2ecf20Sopenharmony_ci	       case 0x20: data = 3; break;
15308c2ecf20Sopenharmony_ci	       case 0x30: data = 2; break;
15318c2ecf20Sopenharmony_ci	       }
15328c2ecf20Sopenharmony_ci	    } else {
15338c2ecf20Sopenharmony_ci	       data = 0;
15348c2ecf20Sopenharmony_ci	    }
15358c2ecf20Sopenharmony_ci	 }
15368c2ecf20Sopenharmony_ci      }
15378c2ecf20Sopenharmony_ci   }
15388c2ecf20Sopenharmony_ci
15398c2ecf20Sopenharmony_ci   return data;
15408c2ecf20Sopenharmony_ci}
15418c2ecf20Sopenharmony_ci
15428c2ecf20Sopenharmony_cistatic unsigned short
15438c2ecf20Sopenharmony_ciSiS_GetMCLK(struct SiS_Private *SiS_Pr)
15448c2ecf20Sopenharmony_ci{
15458c2ecf20Sopenharmony_ci   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
15468c2ecf20Sopenharmony_ci   unsigned short index;
15478c2ecf20Sopenharmony_ci
15488c2ecf20Sopenharmony_ci   index = SiS_Get310DRAMType(SiS_Pr);
15498c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_661) {
15508c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_ROMNew) {
15518c2ecf20Sopenharmony_ci	 return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
15528c2ecf20Sopenharmony_ci      }
15538c2ecf20Sopenharmony_ci      return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
15548c2ecf20Sopenharmony_ci   } else if(index >= 4) {
15558c2ecf20Sopenharmony_ci      return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
15568c2ecf20Sopenharmony_ci   } else {
15578c2ecf20Sopenharmony_ci      return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
15588c2ecf20Sopenharmony_ci   }
15598c2ecf20Sopenharmony_ci}
15608c2ecf20Sopenharmony_ci#endif
15618c2ecf20Sopenharmony_ci
15628c2ecf20Sopenharmony_ci/*********************************************/
15638c2ecf20Sopenharmony_ci/*           HELPER: ClearBuffer             */
15648c2ecf20Sopenharmony_ci/*********************************************/
15658c2ecf20Sopenharmony_ci
15668c2ecf20Sopenharmony_cistatic void
15678c2ecf20Sopenharmony_ciSiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
15688c2ecf20Sopenharmony_ci{
15698c2ecf20Sopenharmony_ci   unsigned char  SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
15708c2ecf20Sopenharmony_ci   unsigned int   memsize = SiS_Pr->VideoMemorySize;
15718c2ecf20Sopenharmony_ci   unsigned short SISIOMEMTYPE *pBuffer;
15728c2ecf20Sopenharmony_ci   int i;
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci   if(!memaddr || !memsize) return;
15758c2ecf20Sopenharmony_ci
15768c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_ModeType >= ModeEGA) {
15778c2ecf20Sopenharmony_ci      if(ModeNo > 0x13) {
15788c2ecf20Sopenharmony_ci	 memset_io(memaddr, 0, memsize);
15798c2ecf20Sopenharmony_ci      } else {
15808c2ecf20Sopenharmony_ci	 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
15818c2ecf20Sopenharmony_ci	 for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
15828c2ecf20Sopenharmony_ci      }
15838c2ecf20Sopenharmony_ci   } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
15848c2ecf20Sopenharmony_ci      pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
15858c2ecf20Sopenharmony_ci      for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
15868c2ecf20Sopenharmony_ci   } else {
15878c2ecf20Sopenharmony_ci      memset_io(memaddr, 0, 0x8000);
15888c2ecf20Sopenharmony_ci   }
15898c2ecf20Sopenharmony_ci}
15908c2ecf20Sopenharmony_ci
15918c2ecf20Sopenharmony_ci/*********************************************/
15928c2ecf20Sopenharmony_ci/*           HELPER: SearchModeID            */
15938c2ecf20Sopenharmony_ci/*********************************************/
15948c2ecf20Sopenharmony_ci
15958c2ecf20Sopenharmony_cibool
15968c2ecf20Sopenharmony_ciSiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
15978c2ecf20Sopenharmony_ci		unsigned short *ModeIdIndex)
15988c2ecf20Sopenharmony_ci{
15998c2ecf20Sopenharmony_ci   unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
16008c2ecf20Sopenharmony_ci
16018c2ecf20Sopenharmony_ci   if((*ModeNo) <= 0x13) {
16028c2ecf20Sopenharmony_ci
16038c2ecf20Sopenharmony_ci      if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
16048c2ecf20Sopenharmony_ci
16058c2ecf20Sopenharmony_ci      for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
16068c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
16078c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return false;
16088c2ecf20Sopenharmony_ci      }
16098c2ecf20Sopenharmony_ci
16108c2ecf20Sopenharmony_ci      if((*ModeNo) == 0x07) {
16118c2ecf20Sopenharmony_ci	  if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
16128c2ecf20Sopenharmony_ci	  /* else 350 lines */
16138c2ecf20Sopenharmony_ci      }
16148c2ecf20Sopenharmony_ci      if((*ModeNo) <= 0x03) {
16158c2ecf20Sopenharmony_ci	 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
16168c2ecf20Sopenharmony_ci	 if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
16178c2ecf20Sopenharmony_ci	 /* else 350 lines  */
16188c2ecf20Sopenharmony_ci      }
16198c2ecf20Sopenharmony_ci      /* else 200 lines  */
16208c2ecf20Sopenharmony_ci
16218c2ecf20Sopenharmony_ci   } else {
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci      for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
16248c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
16258c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return false;
16268c2ecf20Sopenharmony_ci      }
16278c2ecf20Sopenharmony_ci
16288c2ecf20Sopenharmony_ci   }
16298c2ecf20Sopenharmony_ci   return true;
16308c2ecf20Sopenharmony_ci}
16318c2ecf20Sopenharmony_ci
16328c2ecf20Sopenharmony_ci/*********************************************/
16338c2ecf20Sopenharmony_ci/*            HELPER: GetModePtr             */
16348c2ecf20Sopenharmony_ci/*********************************************/
16358c2ecf20Sopenharmony_ci
16368c2ecf20Sopenharmony_ciunsigned short
16378c2ecf20Sopenharmony_ciSiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
16388c2ecf20Sopenharmony_ci{
16398c2ecf20Sopenharmony_ci   unsigned short index;
16408c2ecf20Sopenharmony_ci
16418c2ecf20Sopenharmony_ci   if(ModeNo <= 0x13) {
16428c2ecf20Sopenharmony_ci      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
16438c2ecf20Sopenharmony_ci   } else {
16448c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
16458c2ecf20Sopenharmony_ci      else index = 0x0F;
16468c2ecf20Sopenharmony_ci   }
16478c2ecf20Sopenharmony_ci   return index;
16488c2ecf20Sopenharmony_ci}
16498c2ecf20Sopenharmony_ci
16508c2ecf20Sopenharmony_ci/*********************************************/
16518c2ecf20Sopenharmony_ci/*         HELPERS: Get some indices         */
16528c2ecf20Sopenharmony_ci/*********************************************/
16538c2ecf20Sopenharmony_ci
16548c2ecf20Sopenharmony_ciunsigned short
16558c2ecf20Sopenharmony_ciSiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
16568c2ecf20Sopenharmony_ci{
16578c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
16588c2ecf20Sopenharmony_ci      if(UseWide == 1) {
16598c2ecf20Sopenharmony_ci         return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE;
16608c2ecf20Sopenharmony_ci      } else {
16618c2ecf20Sopenharmony_ci         return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM;
16628c2ecf20Sopenharmony_ci      }
16638c2ecf20Sopenharmony_ci   } else {
16648c2ecf20Sopenharmony_ci      return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK;
16658c2ecf20Sopenharmony_ci   }
16668c2ecf20Sopenharmony_ci}
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ciunsigned short
16698c2ecf20Sopenharmony_ciSiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide)
16708c2ecf20Sopenharmony_ci{
16718c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) {
16728c2ecf20Sopenharmony_ci      if(UseWide == 1) {
16738c2ecf20Sopenharmony_ci         return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE;
16748c2ecf20Sopenharmony_ci      } else {
16758c2ecf20Sopenharmony_ci         return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM;
16768c2ecf20Sopenharmony_ci      }
16778c2ecf20Sopenharmony_ci   } else {
16788c2ecf20Sopenharmony_ci      return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC;
16798c2ecf20Sopenharmony_ci   }
16808c2ecf20Sopenharmony_ci}
16818c2ecf20Sopenharmony_ci
16828c2ecf20Sopenharmony_ci/*********************************************/
16838c2ecf20Sopenharmony_ci/*           HELPER: LowModeTests            */
16848c2ecf20Sopenharmony_ci/*********************************************/
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_cistatic bool
16878c2ecf20Sopenharmony_ciSiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
16888c2ecf20Sopenharmony_ci{
16898c2ecf20Sopenharmony_ci   unsigned short temp, temp1, temp2;
16908c2ecf20Sopenharmony_ci
16918c2ecf20Sopenharmony_ci   if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
16928c2ecf20Sopenharmony_ci      return true;
16938c2ecf20Sopenharmony_ci   temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
16948c2ecf20Sopenharmony_ci   SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
16958c2ecf20Sopenharmony_ci   temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
16968c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
16978c2ecf20Sopenharmony_ci   temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
16988c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
16998c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
17008c2ecf20Sopenharmony_ci   if((SiS_Pr->ChipType >= SIS_315H) ||
17018c2ecf20Sopenharmony_ci      (SiS_Pr->ChipType == SIS_300)) {
17028c2ecf20Sopenharmony_ci      if(temp2 == 0x55) return false;
17038c2ecf20Sopenharmony_ci      else return true;
17048c2ecf20Sopenharmony_ci   } else {
17058c2ecf20Sopenharmony_ci      if(temp2 != 0x55) return true;
17068c2ecf20Sopenharmony_ci      else {
17078c2ecf20Sopenharmony_ci	 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
17088c2ecf20Sopenharmony_ci	 return false;
17098c2ecf20Sopenharmony_ci      }
17108c2ecf20Sopenharmony_ci   }
17118c2ecf20Sopenharmony_ci}
17128c2ecf20Sopenharmony_ci
17138c2ecf20Sopenharmony_cistatic void
17148c2ecf20Sopenharmony_ciSiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
17158c2ecf20Sopenharmony_ci{
17168c2ecf20Sopenharmony_ci   if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) {
17178c2ecf20Sopenharmony_ci      SiS_Pr->SiS_SetFlag |= LowModeTests;
17188c2ecf20Sopenharmony_ci   }
17198c2ecf20Sopenharmony_ci}
17208c2ecf20Sopenharmony_ci
17218c2ecf20Sopenharmony_ci/*********************************************/
17228c2ecf20Sopenharmony_ci/*        HELPER: OPEN/CLOSE CRT1 CRTC       */
17238c2ecf20Sopenharmony_ci/*********************************************/
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_cistatic void
17268c2ecf20Sopenharmony_ciSiS_OpenCRTC(struct SiS_Private *SiS_Pr)
17278c2ecf20Sopenharmony_ci{
17288c2ecf20Sopenharmony_ci   if(IS_SIS650) {
17298c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
17308c2ecf20Sopenharmony_ci      if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
17318c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
17328c2ecf20Sopenharmony_ci   } else if(IS_SIS661741660760) {
17338c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
17348c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
17358c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
17368c2ecf20Sopenharmony_ci      if(!SiS_Pr->SiS_ROMNew) {
17378c2ecf20Sopenharmony_ci	 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
17388c2ecf20Sopenharmony_ci      }
17398c2ecf20Sopenharmony_ci   }
17408c2ecf20Sopenharmony_ci}
17418c2ecf20Sopenharmony_ci
17428c2ecf20Sopenharmony_cistatic void
17438c2ecf20Sopenharmony_ciSiS_CloseCRTC(struct SiS_Private *SiS_Pr)
17448c2ecf20Sopenharmony_ci{
17458c2ecf20Sopenharmony_ci#if 0 /* This locks some CRTC registers. We don't want that. */
17468c2ecf20Sopenharmony_ci   unsigned short temp1 = 0, temp2 = 0;
17478c2ecf20Sopenharmony_ci
17488c2ecf20Sopenharmony_ci   if(IS_SIS661741660760) {
17498c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
17508c2ecf20Sopenharmony_ci         temp1 = 0xa0; temp2 = 0x08;
17518c2ecf20Sopenharmony_ci      }
17528c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1);
17538c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2);
17548c2ecf20Sopenharmony_ci   }
17558c2ecf20Sopenharmony_ci#endif
17568c2ecf20Sopenharmony_ci}
17578c2ecf20Sopenharmony_ci
17588c2ecf20Sopenharmony_cistatic void
17598c2ecf20Sopenharmony_ciSiS_HandleCRT1(struct SiS_Private *SiS_Pr)
17608c2ecf20Sopenharmony_ci{
17618c2ecf20Sopenharmony_ci   /* Enable CRT1 gating */
17628c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
17638c2ecf20Sopenharmony_ci#if 0
17648c2ecf20Sopenharmony_ci   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
17658c2ecf20Sopenharmony_ci      if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
17668c2ecf20Sopenharmony_ci         (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
17678c2ecf20Sopenharmony_ci         SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
17688c2ecf20Sopenharmony_ci      }
17698c2ecf20Sopenharmony_ci   }
17708c2ecf20Sopenharmony_ci#endif
17718c2ecf20Sopenharmony_ci}
17728c2ecf20Sopenharmony_ci
17738c2ecf20Sopenharmony_ci/*********************************************/
17748c2ecf20Sopenharmony_ci/*           HELPER: GetColorDepth           */
17758c2ecf20Sopenharmony_ci/*********************************************/
17768c2ecf20Sopenharmony_ci
17778c2ecf20Sopenharmony_ciunsigned short
17788c2ecf20Sopenharmony_ciSiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
17798c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex)
17808c2ecf20Sopenharmony_ci{
17818c2ecf20Sopenharmony_ci   static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
17828c2ecf20Sopenharmony_ci   unsigned short modeflag;
17838c2ecf20Sopenharmony_ci   short index;
17848c2ecf20Sopenharmony_ci
17858c2ecf20Sopenharmony_ci   /* Do NOT check UseCustomMode, will skrew up FIFO */
17868c2ecf20Sopenharmony_ci   if(ModeNo == 0xfe) {
17878c2ecf20Sopenharmony_ci      modeflag = SiS_Pr->CModeFlag;
17888c2ecf20Sopenharmony_ci   } else if(ModeNo <= 0x13) {
17898c2ecf20Sopenharmony_ci      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
17908c2ecf20Sopenharmony_ci   } else {
17918c2ecf20Sopenharmony_ci      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
17928c2ecf20Sopenharmony_ci   }
17938c2ecf20Sopenharmony_ci
17948c2ecf20Sopenharmony_ci   index = (modeflag & ModeTypeMask) - ModeEGA;
17958c2ecf20Sopenharmony_ci   if(index < 0) index = 0;
17968c2ecf20Sopenharmony_ci   return ColorDepth[index];
17978c2ecf20Sopenharmony_ci}
17988c2ecf20Sopenharmony_ci
17998c2ecf20Sopenharmony_ci/*********************************************/
18008c2ecf20Sopenharmony_ci/*             HELPER: GetOffset             */
18018c2ecf20Sopenharmony_ci/*********************************************/
18028c2ecf20Sopenharmony_ci
18038c2ecf20Sopenharmony_ciunsigned short
18048c2ecf20Sopenharmony_ciSiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
18058c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex, unsigned short RRTI)
18068c2ecf20Sopenharmony_ci{
18078c2ecf20Sopenharmony_ci   unsigned short xres, temp, colordepth, infoflag;
18088c2ecf20Sopenharmony_ci
18098c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
18108c2ecf20Sopenharmony_ci      infoflag = SiS_Pr->CInfoFlag;
18118c2ecf20Sopenharmony_ci      xres = SiS_Pr->CHDisplay;
18128c2ecf20Sopenharmony_ci   } else {
18138c2ecf20Sopenharmony_ci      infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
18148c2ecf20Sopenharmony_ci      xres = SiS_Pr->SiS_RefIndex[RRTI].XRes;
18158c2ecf20Sopenharmony_ci   }
18168c2ecf20Sopenharmony_ci
18178c2ecf20Sopenharmony_ci   colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex);
18188c2ecf20Sopenharmony_ci
18198c2ecf20Sopenharmony_ci   temp = xres / 16;
18208c2ecf20Sopenharmony_ci   if(infoflag & InterlaceMode) temp <<= 1;
18218c2ecf20Sopenharmony_ci   temp *= colordepth;
18228c2ecf20Sopenharmony_ci   if(xres % 16) temp += (colordepth >> 1);
18238c2ecf20Sopenharmony_ci
18248c2ecf20Sopenharmony_ci   return temp;
18258c2ecf20Sopenharmony_ci}
18268c2ecf20Sopenharmony_ci
18278c2ecf20Sopenharmony_ci/*********************************************/
18288c2ecf20Sopenharmony_ci/*                   SEQ                     */
18298c2ecf20Sopenharmony_ci/*********************************************/
18308c2ecf20Sopenharmony_ci
18318c2ecf20Sopenharmony_cistatic void
18328c2ecf20Sopenharmony_ciSiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
18338c2ecf20Sopenharmony_ci{
18348c2ecf20Sopenharmony_ci   unsigned char SRdata;
18358c2ecf20Sopenharmony_ci   int i;
18368c2ecf20Sopenharmony_ci
18378c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
18388c2ecf20Sopenharmony_ci
18398c2ecf20Sopenharmony_ci   /* or "display off"  */
18408c2ecf20Sopenharmony_ci   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20;
18418c2ecf20Sopenharmony_ci
18428c2ecf20Sopenharmony_ci   /* determine whether to force x8 dotclock */
18438c2ecf20Sopenharmony_ci   if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) {
18448c2ecf20Sopenharmony_ci
18458c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
18468c2ecf20Sopenharmony_ci         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)    SRdata |= 0x01;
18478c2ecf20Sopenharmony_ci      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01;
18488c2ecf20Sopenharmony_ci
18498c2ecf20Sopenharmony_ci   }
18508c2ecf20Sopenharmony_ci
18518c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
18528c2ecf20Sopenharmony_ci
18538c2ecf20Sopenharmony_ci   for(i = 2; i <= 4; i++) {
18548c2ecf20Sopenharmony_ci      SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1];
18558c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
18568c2ecf20Sopenharmony_ci   }
18578c2ecf20Sopenharmony_ci}
18588c2ecf20Sopenharmony_ci
18598c2ecf20Sopenharmony_ci/*********************************************/
18608c2ecf20Sopenharmony_ci/*                  MISC                     */
18618c2ecf20Sopenharmony_ci/*********************************************/
18628c2ecf20Sopenharmony_ci
18638c2ecf20Sopenharmony_cistatic void
18648c2ecf20Sopenharmony_ciSiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
18658c2ecf20Sopenharmony_ci{
18668c2ecf20Sopenharmony_ci   unsigned char Miscdata;
18678c2ecf20Sopenharmony_ci
18688c2ecf20Sopenharmony_ci   Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
18698c2ecf20Sopenharmony_ci
18708c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType < SIS_661) {
18718c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
18728c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
18738c2ecf20Sopenharmony_ci	   Miscdata |= 0x0C;
18748c2ecf20Sopenharmony_ci	 }
18758c2ecf20Sopenharmony_ci      }
18768c2ecf20Sopenharmony_ci   }
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata);
18798c2ecf20Sopenharmony_ci}
18808c2ecf20Sopenharmony_ci
18818c2ecf20Sopenharmony_ci/*********************************************/
18828c2ecf20Sopenharmony_ci/*                  CRTC                     */
18838c2ecf20Sopenharmony_ci/*********************************************/
18848c2ecf20Sopenharmony_ci
18858c2ecf20Sopenharmony_cistatic void
18868c2ecf20Sopenharmony_ciSiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
18878c2ecf20Sopenharmony_ci{
18888c2ecf20Sopenharmony_ci   unsigned char  CRTCdata;
18898c2ecf20Sopenharmony_ci   unsigned short i;
18908c2ecf20Sopenharmony_ci
18918c2ecf20Sopenharmony_ci   /* Unlock CRTC */
18928c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
18938c2ecf20Sopenharmony_ci
18948c2ecf20Sopenharmony_ci   for(i = 0; i <= 0x18; i++) {
18958c2ecf20Sopenharmony_ci      CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
18968c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
18978c2ecf20Sopenharmony_ci   }
18988c2ecf20Sopenharmony_ci
18998c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_661) {
19008c2ecf20Sopenharmony_ci      SiS_OpenCRTC(SiS_Pr);
19018c2ecf20Sopenharmony_ci      for(i = 0x13; i <= 0x14; i++) {
19028c2ecf20Sopenharmony_ci	 CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
19038c2ecf20Sopenharmony_ci	 SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
19048c2ecf20Sopenharmony_ci      }
19058c2ecf20Sopenharmony_ci   } else if( ( (SiS_Pr->ChipType == SIS_630) ||
19068c2ecf20Sopenharmony_ci	        (SiS_Pr->ChipType == SIS_730) )  &&
19078c2ecf20Sopenharmony_ci	      (SiS_Pr->ChipRevision >= 0x30) ) {
19088c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
19098c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
19108c2ecf20Sopenharmony_ci	    SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
19118c2ecf20Sopenharmony_ci	 }
19128c2ecf20Sopenharmony_ci      }
19138c2ecf20Sopenharmony_ci   }
19148c2ecf20Sopenharmony_ci}
19158c2ecf20Sopenharmony_ci
19168c2ecf20Sopenharmony_ci/*********************************************/
19178c2ecf20Sopenharmony_ci/*                   ATT                     */
19188c2ecf20Sopenharmony_ci/*********************************************/
19198c2ecf20Sopenharmony_ci
19208c2ecf20Sopenharmony_cistatic void
19218c2ecf20Sopenharmony_ciSiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
19228c2ecf20Sopenharmony_ci{
19238c2ecf20Sopenharmony_ci   unsigned char  ARdata;
19248c2ecf20Sopenharmony_ci   unsigned short i;
19258c2ecf20Sopenharmony_ci
19268c2ecf20Sopenharmony_ci   for(i = 0; i <= 0x13; i++) {
19278c2ecf20Sopenharmony_ci      ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
19288c2ecf20Sopenharmony_ci
19298c2ecf20Sopenharmony_ci      if(i == 0x13) {
19308c2ecf20Sopenharmony_ci	 /* Pixel shift. If screen on LCD or TV is shifted left or right,
19318c2ecf20Sopenharmony_ci	  * this might be the cause.
19328c2ecf20Sopenharmony_ci	  */
19338c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
19348c2ecf20Sopenharmony_ci	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0;
19358c2ecf20Sopenharmony_ci	 }
19368c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
19378c2ecf20Sopenharmony_ci	    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
19388c2ecf20Sopenharmony_ci	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
19398c2ecf20Sopenharmony_ci		  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
19408c2ecf20Sopenharmony_ci	       }
19418c2ecf20Sopenharmony_ci	    }
19428c2ecf20Sopenharmony_ci	 }
19438c2ecf20Sopenharmony_ci	 if(SiS_Pr->ChipType >= SIS_661) {
19448c2ecf20Sopenharmony_ci	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
19458c2ecf20Sopenharmony_ci	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
19468c2ecf20Sopenharmony_ci	    }
19478c2ecf20Sopenharmony_ci	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
19488c2ecf20Sopenharmony_ci	    if(SiS_Pr->ChipType >= SIS_315H) {
19498c2ecf20Sopenharmony_ci	       if(IS_SIS550650740660) {
19508c2ecf20Sopenharmony_ci		  /* 315, 330 don't do this */
19518c2ecf20Sopenharmony_ci		  if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
19528c2ecf20Sopenharmony_ci		     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
19538c2ecf20Sopenharmony_ci		  } else {
19548c2ecf20Sopenharmony_ci		     ARdata = 0;
19558c2ecf20Sopenharmony_ci		  }
19568c2ecf20Sopenharmony_ci	       }
19578c2ecf20Sopenharmony_ci	    } else {
19588c2ecf20Sopenharmony_ci	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0;
19598c2ecf20Sopenharmony_ci	    }
19608c2ecf20Sopenharmony_ci	 }
19618c2ecf20Sopenharmony_ci      }
19628c2ecf20Sopenharmony_ci      SiS_GetRegByte(SiS_Pr->SiS_P3da);		/* reset 3da  */
19638c2ecf20Sopenharmony_ci      SiS_SetRegByte(SiS_Pr->SiS_P3c0,i);	/* set index  */
19648c2ecf20Sopenharmony_ci      SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata);	/* set data   */
19658c2ecf20Sopenharmony_ci   }
19668c2ecf20Sopenharmony_ci
19678c2ecf20Sopenharmony_ci   SiS_GetRegByte(SiS_Pr->SiS_P3da);		/* reset 3da  */
19688c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14);	/* set index  */
19698c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00);	/* set data   */
19708c2ecf20Sopenharmony_ci
19718c2ecf20Sopenharmony_ci   SiS_GetRegByte(SiS_Pr->SiS_P3da);
19728c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20);	/* Enable Attribute  */
19738c2ecf20Sopenharmony_ci   SiS_GetRegByte(SiS_Pr->SiS_P3da);
19748c2ecf20Sopenharmony_ci}
19758c2ecf20Sopenharmony_ci
19768c2ecf20Sopenharmony_ci/*********************************************/
19778c2ecf20Sopenharmony_ci/*                   GRC                     */
19788c2ecf20Sopenharmony_ci/*********************************************/
19798c2ecf20Sopenharmony_ci
19808c2ecf20Sopenharmony_cistatic void
19818c2ecf20Sopenharmony_ciSiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex)
19828c2ecf20Sopenharmony_ci{
19838c2ecf20Sopenharmony_ci   unsigned char  GRdata;
19848c2ecf20Sopenharmony_ci   unsigned short i;
19858c2ecf20Sopenharmony_ci
19868c2ecf20Sopenharmony_ci   for(i = 0; i <= 0x08; i++) {
19878c2ecf20Sopenharmony_ci      GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
19888c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata);
19898c2ecf20Sopenharmony_ci   }
19908c2ecf20Sopenharmony_ci
19918c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_ModeType > ModeVGA) {
19928c2ecf20Sopenharmony_ci      /* 256 color disable */
19938c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);
19948c2ecf20Sopenharmony_ci   }
19958c2ecf20Sopenharmony_ci}
19968c2ecf20Sopenharmony_ci
19978c2ecf20Sopenharmony_ci/*********************************************/
19988c2ecf20Sopenharmony_ci/*          CLEAR EXTENDED REGISTERS         */
19998c2ecf20Sopenharmony_ci/*********************************************/
20008c2ecf20Sopenharmony_ci
20018c2ecf20Sopenharmony_cistatic void
20028c2ecf20Sopenharmony_ciSiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
20038c2ecf20Sopenharmony_ci{
20048c2ecf20Sopenharmony_ci   unsigned short i;
20058c2ecf20Sopenharmony_ci
20068c2ecf20Sopenharmony_ci   for(i = 0x0A; i <= 0x0E; i++) {
20078c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
20088c2ecf20Sopenharmony_ci   }
20098c2ecf20Sopenharmony_ci
20108c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_315H) {
20118c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
20128c2ecf20Sopenharmony_ci      if(ModeNo <= 0x13) {
20138c2ecf20Sopenharmony_ci	 if(ModeNo == 0x06 || ModeNo >= 0x0e) {
20148c2ecf20Sopenharmony_ci	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
20158c2ecf20Sopenharmony_ci	 }
20168c2ecf20Sopenharmony_ci      }
20178c2ecf20Sopenharmony_ci   }
20188c2ecf20Sopenharmony_ci}
20198c2ecf20Sopenharmony_ci
20208c2ecf20Sopenharmony_ci/*********************************************/
20218c2ecf20Sopenharmony_ci/*                 RESET VCLK                */
20228c2ecf20Sopenharmony_ci/*********************************************/
20238c2ecf20Sopenharmony_ci
20248c2ecf20Sopenharmony_cistatic void
20258c2ecf20Sopenharmony_ciSiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr)
20268c2ecf20Sopenharmony_ci{
20278c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_315H) {
20288c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType < SIS_661) {
20298c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
20308c2ecf20Sopenharmony_ci      }
20318c2ecf20Sopenharmony_ci   } else {
20328c2ecf20Sopenharmony_ci      if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
20338c2ecf20Sopenharmony_ci	 (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
20348c2ecf20Sopenharmony_ci	 return;
20358c2ecf20Sopenharmony_ci      }
20368c2ecf20Sopenharmony_ci   }
20378c2ecf20Sopenharmony_ci
20388c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20);
20398c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
20408c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
20418c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
20428c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
20438c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
20448c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
20458c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
20468c2ecf20Sopenharmony_ci}
20478c2ecf20Sopenharmony_ci
20488c2ecf20Sopenharmony_ci/*********************************************/
20498c2ecf20Sopenharmony_ci/*                  SYNC                     */
20508c2ecf20Sopenharmony_ci/*********************************************/
20518c2ecf20Sopenharmony_ci
20528c2ecf20Sopenharmony_cistatic void
20538c2ecf20Sopenharmony_ciSiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI)
20548c2ecf20Sopenharmony_ci{
20558c2ecf20Sopenharmony_ci   unsigned short sync;
20568c2ecf20Sopenharmony_ci
20578c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
20588c2ecf20Sopenharmony_ci      sync = SiS_Pr->CInfoFlag >> 8;
20598c2ecf20Sopenharmony_ci   } else {
20608c2ecf20Sopenharmony_ci      sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8;
20618c2ecf20Sopenharmony_ci   }
20628c2ecf20Sopenharmony_ci
20638c2ecf20Sopenharmony_ci   sync &= 0xC0;
20648c2ecf20Sopenharmony_ci   sync |= 0x2f;
20658c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
20668c2ecf20Sopenharmony_ci}
20678c2ecf20Sopenharmony_ci
20688c2ecf20Sopenharmony_ci/*********************************************/
20698c2ecf20Sopenharmony_ci/*                  CRTC/2                   */
20708c2ecf20Sopenharmony_ci/*********************************************/
20718c2ecf20Sopenharmony_ci
20728c2ecf20Sopenharmony_cistatic void
20738c2ecf20Sopenharmony_ciSiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
20748c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex, unsigned short RRTI)
20758c2ecf20Sopenharmony_ci{
20768c2ecf20Sopenharmony_ci   unsigned short temp, i, j, modeflag;
20778c2ecf20Sopenharmony_ci   unsigned char  *crt1data = NULL;
20788c2ecf20Sopenharmony_ci
20798c2ecf20Sopenharmony_ci   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
20808c2ecf20Sopenharmony_ci
20818c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
20828c2ecf20Sopenharmony_ci
20838c2ecf20Sopenharmony_ci      crt1data = &SiS_Pr->CCRT1CRTC[0];
20848c2ecf20Sopenharmony_ci
20858c2ecf20Sopenharmony_ci   } else {
20868c2ecf20Sopenharmony_ci
20878c2ecf20Sopenharmony_ci      temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide);
20888c2ecf20Sopenharmony_ci
20898c2ecf20Sopenharmony_ci      /* Alternate for 1600x1200 LCDA */
20908c2ecf20Sopenharmony_ci      if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57;
20918c2ecf20Sopenharmony_ci
20928c2ecf20Sopenharmony_ci      crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0];
20938c2ecf20Sopenharmony_ci
20948c2ecf20Sopenharmony_ci   }
20958c2ecf20Sopenharmony_ci
20968c2ecf20Sopenharmony_ci   /* unlock cr0-7 */
20978c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
20988c2ecf20Sopenharmony_ci
20998c2ecf20Sopenharmony_ci   for(i = 0, j = 0; i <= 7; i++, j++) {
21008c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
21018c2ecf20Sopenharmony_ci   }
21028c2ecf20Sopenharmony_ci   for(j = 0x10; i <= 10; i++, j++) {
21038c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
21048c2ecf20Sopenharmony_ci   }
21058c2ecf20Sopenharmony_ci   for(j = 0x15; i <= 12; i++, j++) {
21068c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]);
21078c2ecf20Sopenharmony_ci   }
21088c2ecf20Sopenharmony_ci   for(j = 0x0A; i <= 15; i++, j++) {
21098c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]);
21108c2ecf20Sopenharmony_ci   }
21118c2ecf20Sopenharmony_ci
21128c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0);
21138c2ecf20Sopenharmony_ci
21148c2ecf20Sopenharmony_ci   temp = (crt1data[16] & 0x01) << 5;
21158c2ecf20Sopenharmony_ci   if(modeflag & DoubleScanMode) temp |= 0x80;
21168c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
21178c2ecf20Sopenharmony_ci
21188c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_ModeType > ModeVGA) {
21198c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
21208c2ecf20Sopenharmony_ci   }
21218c2ecf20Sopenharmony_ci
21228c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
21238c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == XGI_20) {
21248c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
21258c2ecf20Sopenharmony_ci      if(!(temp = crt1data[5] & 0x1f)) {
21268c2ecf20Sopenharmony_ci         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb);
21278c2ecf20Sopenharmony_ci      }
21288c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f));
21298c2ecf20Sopenharmony_ci      temp = (crt1data[16] >> 5) + 3;
21308c2ecf20Sopenharmony_ci      if(temp > 7) temp -= 7;
21318c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5));
21328c2ecf20Sopenharmony_ci   }
21338c2ecf20Sopenharmony_ci#endif
21348c2ecf20Sopenharmony_ci}
21358c2ecf20Sopenharmony_ci
21368c2ecf20Sopenharmony_ci/*********************************************/
21378c2ecf20Sopenharmony_ci/*               OFFSET & PITCH              */
21388c2ecf20Sopenharmony_ci/*********************************************/
21398c2ecf20Sopenharmony_ci/*  (partly overruled by SetPitch() in XF86) */
21408c2ecf20Sopenharmony_ci/*********************************************/
21418c2ecf20Sopenharmony_ci
21428c2ecf20Sopenharmony_cistatic void
21438c2ecf20Sopenharmony_ciSiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
21448c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex, unsigned short RRTI)
21458c2ecf20Sopenharmony_ci{
21468c2ecf20Sopenharmony_ci   unsigned short temp, DisplayUnit, infoflag;
21478c2ecf20Sopenharmony_ci
21488c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
21498c2ecf20Sopenharmony_ci      infoflag = SiS_Pr->CInfoFlag;
21508c2ecf20Sopenharmony_ci   } else {
21518c2ecf20Sopenharmony_ci      infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
21528c2ecf20Sopenharmony_ci   }
21538c2ecf20Sopenharmony_ci
21548c2ecf20Sopenharmony_ci   DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
21558c2ecf20Sopenharmony_ci
21568c2ecf20Sopenharmony_ci   temp = (DisplayUnit >> 8) & 0x0f;
21578c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
21588c2ecf20Sopenharmony_ci
21598c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF);
21608c2ecf20Sopenharmony_ci
21618c2ecf20Sopenharmony_ci   if(infoflag & InterlaceMode) DisplayUnit >>= 1;
21628c2ecf20Sopenharmony_ci
21638c2ecf20Sopenharmony_ci   DisplayUnit <<= 5;
21648c2ecf20Sopenharmony_ci   temp = (DisplayUnit >> 8) + 1;
21658c2ecf20Sopenharmony_ci   if(DisplayUnit & 0xff) temp++;
21668c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == XGI_20) {
21678c2ecf20Sopenharmony_ci      if(ModeNo == 0x4a || ModeNo == 0x49) temp--;
21688c2ecf20Sopenharmony_ci   }
21698c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
21708c2ecf20Sopenharmony_ci}
21718c2ecf20Sopenharmony_ci
21728c2ecf20Sopenharmony_ci/*********************************************/
21738c2ecf20Sopenharmony_ci/*                  VCLK                     */
21748c2ecf20Sopenharmony_ci/*********************************************/
21758c2ecf20Sopenharmony_ci
21768c2ecf20Sopenharmony_cistatic void
21778c2ecf20Sopenharmony_ciSiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
21788c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex, unsigned short RRTI)
21798c2ecf20Sopenharmony_ci{
21808c2ecf20Sopenharmony_ci   unsigned short index = 0, clka, clkb;
21818c2ecf20Sopenharmony_ci
21828c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
21838c2ecf20Sopenharmony_ci      clka = SiS_Pr->CSR2B;
21848c2ecf20Sopenharmony_ci      clkb = SiS_Pr->CSR2C;
21858c2ecf20Sopenharmony_ci   } else {
21868c2ecf20Sopenharmony_ci      index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
21878c2ecf20Sopenharmony_ci      if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
21888c2ecf20Sopenharmony_ci	 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
21898c2ecf20Sopenharmony_ci	 /* Alternate for 1600x1200 LCDA */
21908c2ecf20Sopenharmony_ci	 if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72;
21918c2ecf20Sopenharmony_ci	 clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A;
21928c2ecf20Sopenharmony_ci	 clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B;
21938c2ecf20Sopenharmony_ci      } else {
21948c2ecf20Sopenharmony_ci	 clka = SiS_Pr->SiS_VCLKData[index].SR2B;
21958c2ecf20Sopenharmony_ci	 clkb = SiS_Pr->SiS_VCLKData[index].SR2C;
21968c2ecf20Sopenharmony_ci      }
21978c2ecf20Sopenharmony_ci   }
21988c2ecf20Sopenharmony_ci
21998c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
22008c2ecf20Sopenharmony_ci
22018c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka);
22028c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
22038c2ecf20Sopenharmony_ci
22048c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_315H) {
22058c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
22068c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
22078c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType == XGI_20) {
22088c2ecf20Sopenharmony_ci         unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
22098c2ecf20Sopenharmony_ci	 if(mf & HalfDCLK) {
22108c2ecf20Sopenharmony_ci	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b));
22118c2ecf20Sopenharmony_ci	    clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c);
22128c2ecf20Sopenharmony_ci	    clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0);
22138c2ecf20Sopenharmony_ci	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
22148c2ecf20Sopenharmony_ci	 }
22158c2ecf20Sopenharmony_ci      }
22168c2ecf20Sopenharmony_ci#endif
22178c2ecf20Sopenharmony_ci   } else {
22188c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
22198c2ecf20Sopenharmony_ci   }
22208c2ecf20Sopenharmony_ci}
22218c2ecf20Sopenharmony_ci
22228c2ecf20Sopenharmony_ci/*********************************************/
22238c2ecf20Sopenharmony_ci/*                  FIFO                     */
22248c2ecf20Sopenharmony_ci/*********************************************/
22258c2ecf20Sopenharmony_ci
22268c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
22278c2ecf20Sopenharmony_civoid
22288c2ecf20Sopenharmony_ciSiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
22298c2ecf20Sopenharmony_ci		unsigned short *idx2)
22308c2ecf20Sopenharmony_ci{
22318c2ecf20Sopenharmony_ci   unsigned short temp1, temp2;
22328c2ecf20Sopenharmony_ci   static const unsigned char ThTiming[8] = {
22338c2ecf20Sopenharmony_ci		1, 2, 2, 3, 0, 1, 1, 2
22348c2ecf20Sopenharmony_ci   };
22358c2ecf20Sopenharmony_ci
22368c2ecf20Sopenharmony_ci   temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1;
22378c2ecf20Sopenharmony_ci   (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]);
22388c2ecf20Sopenharmony_ci   (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03;
22398c2ecf20Sopenharmony_ci   (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c));
22408c2ecf20Sopenharmony_ci   (*idx1) <<= 1;
22418c2ecf20Sopenharmony_ci}
22428c2ecf20Sopenharmony_ci
22438c2ecf20Sopenharmony_cistatic unsigned short
22448c2ecf20Sopenharmony_ciSiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2)
22458c2ecf20Sopenharmony_ci{
22468c2ecf20Sopenharmony_ci   static const unsigned char ThLowA[8 * 3] = {
22478c2ecf20Sopenharmony_ci		61, 3,52, 5,68, 7,100,11,
22488c2ecf20Sopenharmony_ci		43, 3,42, 5,54, 7, 78,11,
22498c2ecf20Sopenharmony_ci		34, 3,37, 5,47, 7, 67,11
22508c2ecf20Sopenharmony_ci   };
22518c2ecf20Sopenharmony_ci
22528c2ecf20Sopenharmony_ci   return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]);
22538c2ecf20Sopenharmony_ci}
22548c2ecf20Sopenharmony_ci
22558c2ecf20Sopenharmony_ciunsigned short
22568c2ecf20Sopenharmony_ciSiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2)
22578c2ecf20Sopenharmony_ci{
22588c2ecf20Sopenharmony_ci   static const unsigned char ThLowB[8 * 3] = {
22598c2ecf20Sopenharmony_ci		81, 4,72, 6,88, 8,120,12,
22608c2ecf20Sopenharmony_ci		55, 4,54, 6,66, 8, 90,12,
22618c2ecf20Sopenharmony_ci		42, 4,45, 6,55, 8, 75,12
22628c2ecf20Sopenharmony_ci   };
22638c2ecf20Sopenharmony_ci
22648c2ecf20Sopenharmony_ci   return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]);
22658c2ecf20Sopenharmony_ci}
22668c2ecf20Sopenharmony_ci
22678c2ecf20Sopenharmony_cistatic unsigned short
22688c2ecf20Sopenharmony_ciSiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK,
22698c2ecf20Sopenharmony_ci		unsigned short colordepth, unsigned short key)
22708c2ecf20Sopenharmony_ci{
22718c2ecf20Sopenharmony_ci   unsigned short idx1, idx2;
22728c2ecf20Sopenharmony_ci   unsigned int   longtemp = VCLK * colordepth;
22738c2ecf20Sopenharmony_ci
22748c2ecf20Sopenharmony_ci   SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2);
22758c2ecf20Sopenharmony_ci
22768c2ecf20Sopenharmony_ci   if(key == 0) {
22778c2ecf20Sopenharmony_ci      longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2);
22788c2ecf20Sopenharmony_ci   } else {
22798c2ecf20Sopenharmony_ci      longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2);
22808c2ecf20Sopenharmony_ci   }
22818c2ecf20Sopenharmony_ci   idx1 = longtemp % (MCLK * 16);
22828c2ecf20Sopenharmony_ci   longtemp /= (MCLK * 16);
22838c2ecf20Sopenharmony_ci   if(idx1) longtemp++;
22848c2ecf20Sopenharmony_ci   return (unsigned short)longtemp;
22858c2ecf20Sopenharmony_ci}
22868c2ecf20Sopenharmony_ci
22878c2ecf20Sopenharmony_cistatic unsigned short
22888c2ecf20Sopenharmony_ciSiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK,
22898c2ecf20Sopenharmony_ci		unsigned short colordepth, unsigned short MCLK)
22908c2ecf20Sopenharmony_ci{
22918c2ecf20Sopenharmony_ci   unsigned short temp1, temp2;
22928c2ecf20Sopenharmony_ci
22938c2ecf20Sopenharmony_ci   temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
22948c2ecf20Sopenharmony_ci   temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
22958c2ecf20Sopenharmony_ci   if(temp1 < 4) temp1 = 4;
22968c2ecf20Sopenharmony_ci   temp1 -= 4;
22978c2ecf20Sopenharmony_ci   if(temp2 < temp1) temp2 = temp1;
22988c2ecf20Sopenharmony_ci   return temp2;
22998c2ecf20Sopenharmony_ci}
23008c2ecf20Sopenharmony_ci
23018c2ecf20Sopenharmony_cistatic void
23028c2ecf20Sopenharmony_ciSiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
23038c2ecf20Sopenharmony_ci		unsigned short RefreshRateTableIndex)
23048c2ecf20Sopenharmony_ci{
23058c2ecf20Sopenharmony_ci   unsigned short ThresholdLow = 0;
23068c2ecf20Sopenharmony_ci   unsigned short temp, index, VCLK, MCLK, colorth;
23078c2ecf20Sopenharmony_ci   static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 };
23088c2ecf20Sopenharmony_ci
23098c2ecf20Sopenharmony_ci   if(ModeNo > 0x13) {
23108c2ecf20Sopenharmony_ci
23118c2ecf20Sopenharmony_ci      /* Get VCLK  */
23128c2ecf20Sopenharmony_ci      if(SiS_Pr->UseCustomMode) {
23138c2ecf20Sopenharmony_ci	 VCLK = SiS_Pr->CSRClock;
23148c2ecf20Sopenharmony_ci      } else {
23158c2ecf20Sopenharmony_ci	 index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
23168c2ecf20Sopenharmony_ci	 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
23178c2ecf20Sopenharmony_ci      }
23188c2ecf20Sopenharmony_ci
23198c2ecf20Sopenharmony_ci      /* Get half colordepth */
23208c2ecf20Sopenharmony_ci      colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
23218c2ecf20Sopenharmony_ci
23228c2ecf20Sopenharmony_ci      /* Get MCLK  */
23238c2ecf20Sopenharmony_ci      index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07;
23248c2ecf20Sopenharmony_ci      MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
23258c2ecf20Sopenharmony_ci
23268c2ecf20Sopenharmony_ci      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3;
23278c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp);
23288c2ecf20Sopenharmony_ci
23298c2ecf20Sopenharmony_ci      do {
23308c2ecf20Sopenharmony_ci	 ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1;
23318c2ecf20Sopenharmony_ci	 if(ThresholdLow < 0x13) break;
23328c2ecf20Sopenharmony_ci	 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
23338c2ecf20Sopenharmony_ci	 ThresholdLow = 0x13;
23348c2ecf20Sopenharmony_ci	 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6;
23358c2ecf20Sopenharmony_ci	 if(!temp) break;
23368c2ecf20Sopenharmony_ci	 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6));
23378c2ecf20Sopenharmony_ci      } while(0);
23388c2ecf20Sopenharmony_ci
23398c2ecf20Sopenharmony_ci   } else ThresholdLow = 2;
23408c2ecf20Sopenharmony_ci
23418c2ecf20Sopenharmony_ci   /* Write CRT/CPU threshold low, CRT/Engine threshold high */
23428c2ecf20Sopenharmony_ci   temp = (ThresholdLow << 4) | 0x0f;
23438c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
23448c2ecf20Sopenharmony_ci
23458c2ecf20Sopenharmony_ci   temp = (ThresholdLow & 0x10) << 1;
23468c2ecf20Sopenharmony_ci   if(ModeNo > 0x13) temp |= 0x40;
23478c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
23488c2ecf20Sopenharmony_ci
23498c2ecf20Sopenharmony_ci   /* What is this? */
23508c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
23518c2ecf20Sopenharmony_ci
23528c2ecf20Sopenharmony_ci   /* Write CRT/CPU threshold high */
23538c2ecf20Sopenharmony_ci   temp = ThresholdLow + 3;
23548c2ecf20Sopenharmony_ci   if(temp > 0x0f) temp = 0x0f;
23558c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
23568c2ecf20Sopenharmony_ci}
23578c2ecf20Sopenharmony_ci
23588c2ecf20Sopenharmony_ciunsigned short
23598c2ecf20Sopenharmony_ciSiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index)
23608c2ecf20Sopenharmony_ci{
23618c2ecf20Sopenharmony_ci   static const unsigned char LatencyFactor[] = {
23628c2ecf20Sopenharmony_ci		97, 88, 86, 79, 77,  0,       /* 64  bit    BQ=2   */
23638c2ecf20Sopenharmony_ci		 0, 87, 85, 78, 76, 54,       /* 64  bit    BQ=1   */
23648c2ecf20Sopenharmony_ci		97, 88, 86, 79, 77,  0,       /* 128 bit    BQ=2   */
23658c2ecf20Sopenharmony_ci		 0, 79, 77, 70, 68, 48,       /* 128 bit    BQ=1   */
23668c2ecf20Sopenharmony_ci		80, 72, 69, 63, 61,  0,       /* 64  bit    BQ=2   */
23678c2ecf20Sopenharmony_ci		 0, 70, 68, 61, 59, 37,       /* 64  bit    BQ=1   */
23688c2ecf20Sopenharmony_ci		86, 77, 75, 68, 66,  0,       /* 128 bit    BQ=2   */
23698c2ecf20Sopenharmony_ci		 0, 68, 66, 59, 57, 37        /* 128 bit    BQ=1   */
23708c2ecf20Sopenharmony_ci   };
23718c2ecf20Sopenharmony_ci   static const unsigned char LatencyFactor730[] = {
23728c2ecf20Sopenharmony_ci		 69, 63, 61,
23738c2ecf20Sopenharmony_ci		 86, 79, 77,
23748c2ecf20Sopenharmony_ci		103, 96, 94,
23758c2ecf20Sopenharmony_ci		120,113,111,
23768c2ecf20Sopenharmony_ci		137,130,128
23778c2ecf20Sopenharmony_ci   };
23788c2ecf20Sopenharmony_ci
23798c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_730) {
23808c2ecf20Sopenharmony_ci      return (unsigned short)LatencyFactor730[index];
23818c2ecf20Sopenharmony_ci   } else {
23828c2ecf20Sopenharmony_ci      return (unsigned short)LatencyFactor[index];
23838c2ecf20Sopenharmony_ci   }
23848c2ecf20Sopenharmony_ci}
23858c2ecf20Sopenharmony_ci
23868c2ecf20Sopenharmony_cistatic unsigned short
23878c2ecf20Sopenharmony_ciSiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key)
23888c2ecf20Sopenharmony_ci{
23898c2ecf20Sopenharmony_ci   unsigned short index;
23908c2ecf20Sopenharmony_ci
23918c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_730) {
23928c2ecf20Sopenharmony_ci      index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6);
23938c2ecf20Sopenharmony_ci   } else {
23948c2ecf20Sopenharmony_ci      index = (key & 0xe0) >> 5;
23958c2ecf20Sopenharmony_ci      if(key & 0x10)    index +=  6;
23968c2ecf20Sopenharmony_ci      if(!(key & 0x01)) index += 24;
23978c2ecf20Sopenharmony_ci      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
23988c2ecf20Sopenharmony_ci   }
23998c2ecf20Sopenharmony_ci   return SiS_GetLatencyFactor630(SiS_Pr, index);
24008c2ecf20Sopenharmony_ci}
24018c2ecf20Sopenharmony_ci
24028c2ecf20Sopenharmony_cistatic void
24038c2ecf20Sopenharmony_ciSiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
24048c2ecf20Sopenharmony_ci                    unsigned short RefreshRateTableIndex)
24058c2ecf20Sopenharmony_ci{
24068c2ecf20Sopenharmony_ci   unsigned short  ThresholdLow = 0;
24078c2ecf20Sopenharmony_ci   unsigned short  i, data, VCLK, MCLK16, colorth = 0;
24088c2ecf20Sopenharmony_ci   unsigned int    templ, datal;
24098c2ecf20Sopenharmony_ci   const unsigned char *queuedata = NULL;
24108c2ecf20Sopenharmony_ci   static const unsigned char FQBQData[21] = {
24118c2ecf20Sopenharmony_ci		0x01,0x21,0x41,0x61,0x81,
24128c2ecf20Sopenharmony_ci		0x31,0x51,0x71,0x91,0xb1,
24138c2ecf20Sopenharmony_ci		0x00,0x20,0x40,0x60,0x80,
24148c2ecf20Sopenharmony_ci		0x30,0x50,0x70,0x90,0xb0,
24158c2ecf20Sopenharmony_ci		0xff
24168c2ecf20Sopenharmony_ci   };
24178c2ecf20Sopenharmony_ci   static const unsigned char FQBQData730[16] = {
24188c2ecf20Sopenharmony_ci		0x34,0x74,0xb4,
24198c2ecf20Sopenharmony_ci		0x23,0x63,0xa3,
24208c2ecf20Sopenharmony_ci		0x12,0x52,0x92,
24218c2ecf20Sopenharmony_ci		0x01,0x41,0x81,
24228c2ecf20Sopenharmony_ci		0x00,0x40,0x80,
24238c2ecf20Sopenharmony_ci		0xff
24248c2ecf20Sopenharmony_ci   };
24258c2ecf20Sopenharmony_ci   static const unsigned short colortharray[6] = {
24268c2ecf20Sopenharmony_ci		1, 1, 2, 2, 3, 4
24278c2ecf20Sopenharmony_ci   };
24288c2ecf20Sopenharmony_ci
24298c2ecf20Sopenharmony_ci   i = 0;
24308c2ecf20Sopenharmony_ci
24318c2ecf20Sopenharmony_ci	if (SiS_Pr->ChipType == SIS_730)
24328c2ecf20Sopenharmony_ci		queuedata = &FQBQData730[0];
24338c2ecf20Sopenharmony_ci	else
24348c2ecf20Sopenharmony_ci		queuedata = &FQBQData[0];
24358c2ecf20Sopenharmony_ci
24368c2ecf20Sopenharmony_ci   if(ModeNo > 0x13) {
24378c2ecf20Sopenharmony_ci
24388c2ecf20Sopenharmony_ci      /* Get VCLK  */
24398c2ecf20Sopenharmony_ci      if(SiS_Pr->UseCustomMode) {
24408c2ecf20Sopenharmony_ci	 VCLK = SiS_Pr->CSRClock;
24418c2ecf20Sopenharmony_ci      } else {
24428c2ecf20Sopenharmony_ci	 data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide);
24438c2ecf20Sopenharmony_ci	 VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK;
24448c2ecf20Sopenharmony_ci      }
24458c2ecf20Sopenharmony_ci
24468c2ecf20Sopenharmony_ci      /* Get MCLK * 16 */
24478c2ecf20Sopenharmony_ci      data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07;
24488c2ecf20Sopenharmony_ci      MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16;
24498c2ecf20Sopenharmony_ci
24508c2ecf20Sopenharmony_ci      /* Get half colordepth */
24518c2ecf20Sopenharmony_ci      colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)];
24528c2ecf20Sopenharmony_ci
24538c2ecf20Sopenharmony_ci      do {
24548c2ecf20Sopenharmony_ci	 templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth;
24558c2ecf20Sopenharmony_ci
24568c2ecf20Sopenharmony_ci	 datal = templ % MCLK16;
24578c2ecf20Sopenharmony_ci	 templ = (templ / MCLK16) + 1;
24588c2ecf20Sopenharmony_ci	 if(datal) templ++;
24598c2ecf20Sopenharmony_ci
24608c2ecf20Sopenharmony_ci	 if(templ > 0x13) {
24618c2ecf20Sopenharmony_ci	    if(queuedata[i + 1] == 0xFF) {
24628c2ecf20Sopenharmony_ci	       ThresholdLow = 0x13;
24638c2ecf20Sopenharmony_ci	       break;
24648c2ecf20Sopenharmony_ci	    }
24658c2ecf20Sopenharmony_ci	    i++;
24668c2ecf20Sopenharmony_ci	 } else {
24678c2ecf20Sopenharmony_ci	    ThresholdLow = templ;
24688c2ecf20Sopenharmony_ci	    break;
24698c2ecf20Sopenharmony_ci	 }
24708c2ecf20Sopenharmony_ci      } while(queuedata[i] != 0xFF);
24718c2ecf20Sopenharmony_ci
24728c2ecf20Sopenharmony_ci   } else {
24738c2ecf20Sopenharmony_ci
24748c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType != SIS_730) i = 9;
24758c2ecf20Sopenharmony_ci      ThresholdLow = 0x02;
24768c2ecf20Sopenharmony_ci
24778c2ecf20Sopenharmony_ci   }
24788c2ecf20Sopenharmony_ci
24798c2ecf20Sopenharmony_ci   /* Write CRT/CPU threshold low, CRT/Engine threshold high */
24808c2ecf20Sopenharmony_ci   data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
24818c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
24828c2ecf20Sopenharmony_ci
24838c2ecf20Sopenharmony_ci   data = (ThresholdLow & 0x10) << 1;
24848c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
24858c2ecf20Sopenharmony_ci
24868c2ecf20Sopenharmony_ci   /* What is this? */
24878c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
24888c2ecf20Sopenharmony_ci
24898c2ecf20Sopenharmony_ci   /* Write CRT/CPU threshold high (gap = 3) */
24908c2ecf20Sopenharmony_ci   data = ThresholdLow + 3;
24918c2ecf20Sopenharmony_ci   if(data > 0x0f) data = 0x0f;
24928c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
24938c2ecf20Sopenharmony_ci
24948c2ecf20Sopenharmony_ci  /* Write foreground and background queue */
24958c2ecf20Sopenharmony_ci   templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
24968c2ecf20Sopenharmony_ci
24978c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_730) {
24988c2ecf20Sopenharmony_ci
24998c2ecf20Sopenharmony_ci      templ &= 0xfffff9ff;
25008c2ecf20Sopenharmony_ci      templ |= ((queuedata[i] & 0xc0) << 3);
25018c2ecf20Sopenharmony_ci
25028c2ecf20Sopenharmony_ci   } else {
25038c2ecf20Sopenharmony_ci
25048c2ecf20Sopenharmony_ci      templ &= 0xf0ffffff;
25058c2ecf20Sopenharmony_ci      if( (ModeNo <= 0x13) &&
25068c2ecf20Sopenharmony_ci          (SiS_Pr->ChipType == SIS_630) &&
25078c2ecf20Sopenharmony_ci	  (SiS_Pr->ChipRevision >= 0x30) ) {
25088c2ecf20Sopenharmony_ci	 templ |= 0x0b000000;
25098c2ecf20Sopenharmony_ci      } else {
25108c2ecf20Sopenharmony_ci         templ |= ((queuedata[i] & 0xf0) << 20);
25118c2ecf20Sopenharmony_ci      }
25128c2ecf20Sopenharmony_ci
25138c2ecf20Sopenharmony_ci   }
25148c2ecf20Sopenharmony_ci
25158c2ecf20Sopenharmony_ci   sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
25168c2ecf20Sopenharmony_ci   templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
25178c2ecf20Sopenharmony_ci
25188c2ecf20Sopenharmony_ci   /* GUI grant timer (PCI config 0xA3) */
25198c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_730) {
25208c2ecf20Sopenharmony_ci
25218c2ecf20Sopenharmony_ci      templ &= 0x00ffffff;
25228c2ecf20Sopenharmony_ci      datal = queuedata[i] << 8;
25238c2ecf20Sopenharmony_ci      templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20);
25248c2ecf20Sopenharmony_ci
25258c2ecf20Sopenharmony_ci   } else {
25268c2ecf20Sopenharmony_ci
25278c2ecf20Sopenharmony_ci      templ &= 0xf0ffffff;
25288c2ecf20Sopenharmony_ci      templ |= ((queuedata[i] & 0x0f) << 24);
25298c2ecf20Sopenharmony_ci
25308c2ecf20Sopenharmony_ci   }
25318c2ecf20Sopenharmony_ci
25328c2ecf20Sopenharmony_ci   sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
25338c2ecf20Sopenharmony_ci}
25348c2ecf20Sopenharmony_ci#endif /* CONFIG_FB_SIS_300 */
25358c2ecf20Sopenharmony_ci
25368c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
25378c2ecf20Sopenharmony_cistatic void
25388c2ecf20Sopenharmony_ciSiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
25398c2ecf20Sopenharmony_ci{
25408c2ecf20Sopenharmony_ci   unsigned short modeflag;
25418c2ecf20Sopenharmony_ci
25428c2ecf20Sopenharmony_ci   /* disable auto-threshold */
25438c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
25448c2ecf20Sopenharmony_ci
25458c2ecf20Sopenharmony_ci   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
25468c2ecf20Sopenharmony_ci
25478c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
25488c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
25498c2ecf20Sopenharmony_ci   if(ModeNo > 0x13) {
25508c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType >= XGI_20) {
25518c2ecf20Sopenharmony_ci	 SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
25528c2ecf20Sopenharmony_ci	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
25538c2ecf20Sopenharmony_ci      } else if(SiS_Pr->ChipType >= SIS_661) {
25548c2ecf20Sopenharmony_ci	 if(!(modeflag & HalfDCLK)) {
25558c2ecf20Sopenharmony_ci	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
25568c2ecf20Sopenharmony_ci	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
25578c2ecf20Sopenharmony_ci	 }
25588c2ecf20Sopenharmony_ci      } else {
25598c2ecf20Sopenharmony_ci	 if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
25608c2ecf20Sopenharmony_ci	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
25618c2ecf20Sopenharmony_ci	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
25628c2ecf20Sopenharmony_ci	 }
25638c2ecf20Sopenharmony_ci      }
25648c2ecf20Sopenharmony_ci   }
25658c2ecf20Sopenharmony_ci}
25668c2ecf20Sopenharmony_ci#endif
25678c2ecf20Sopenharmony_ci
25688c2ecf20Sopenharmony_ci/*********************************************/
25698c2ecf20Sopenharmony_ci/*              MODE REGISTERS               */
25708c2ecf20Sopenharmony_ci/*********************************************/
25718c2ecf20Sopenharmony_ci
25728c2ecf20Sopenharmony_cistatic void
25738c2ecf20Sopenharmony_ciSiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
25748c2ecf20Sopenharmony_ci		unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex)
25758c2ecf20Sopenharmony_ci{
25768c2ecf20Sopenharmony_ci   unsigned short data = 0, VCLK = 0, index = 0;
25778c2ecf20Sopenharmony_ci
25788c2ecf20Sopenharmony_ci   if(ModeNo > 0x13) {
25798c2ecf20Sopenharmony_ci      if(SiS_Pr->UseCustomMode) {
25808c2ecf20Sopenharmony_ci         VCLK = SiS_Pr->CSRClock;
25818c2ecf20Sopenharmony_ci      } else {
25828c2ecf20Sopenharmony_ci         index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
25838c2ecf20Sopenharmony_ci         VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
25848c2ecf20Sopenharmony_ci      }
25858c2ecf20Sopenharmony_ci   }
25868c2ecf20Sopenharmony_ci
25878c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType < SIS_315H) {
25888c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
25898c2ecf20Sopenharmony_ci      if(VCLK > 150) data |= 0x80;
25908c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
25918c2ecf20Sopenharmony_ci
25928c2ecf20Sopenharmony_ci      data = 0x00;
25938c2ecf20Sopenharmony_ci      if(VCLK >= 150) data |= 0x08;
25948c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
25958c2ecf20Sopenharmony_ci#endif
25968c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType < XGI_20) {
25978c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
25988c2ecf20Sopenharmony_ci      if(VCLK >= 166) data |= 0x0c;
25998c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
26008c2ecf20Sopenharmony_ci
26018c2ecf20Sopenharmony_ci      if(VCLK >= 166) {
26028c2ecf20Sopenharmony_ci         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
26038c2ecf20Sopenharmony_ci      }
26048c2ecf20Sopenharmony_ci#endif
26058c2ecf20Sopenharmony_ci   } else {
26068c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
26078c2ecf20Sopenharmony_ci      if(VCLK >= 200) data |= 0x0c;
26088c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
26098c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
26108c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType != XGI_20) {
26118c2ecf20Sopenharmony_ci         data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7;
26128c2ecf20Sopenharmony_ci	 if(VCLK < 200) data |= 0x10;
26138c2ecf20Sopenharmony_ci	 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data);
26148c2ecf20Sopenharmony_ci      }
26158c2ecf20Sopenharmony_ci#endif
26168c2ecf20Sopenharmony_ci   }
26178c2ecf20Sopenharmony_ci
26188c2ecf20Sopenharmony_ci   /* DAC speed */
26198c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_661) {
26208c2ecf20Sopenharmony_ci
26218c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
26228c2ecf20Sopenharmony_ci
26238c2ecf20Sopenharmony_ci   } else {
26248c2ecf20Sopenharmony_ci
26258c2ecf20Sopenharmony_ci      data = 0x03;
26268c2ecf20Sopenharmony_ci      if(VCLK >= 260)      data = 0x00;
26278c2ecf20Sopenharmony_ci      else if(VCLK >= 160) data = 0x01;
26288c2ecf20Sopenharmony_ci      else if(VCLK >= 135) data = 0x02;
26298c2ecf20Sopenharmony_ci
26308c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType == SIS_540) {
26318c2ecf20Sopenharmony_ci         /* Was == 203 or < 234 which made no sense */
26328c2ecf20Sopenharmony_ci         if (VCLK < 234) data = 0x02;
26338c2ecf20Sopenharmony_ci      }
26348c2ecf20Sopenharmony_ci
26358c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType < SIS_315H) {
26368c2ecf20Sopenharmony_ci         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
26378c2ecf20Sopenharmony_ci      } else {
26388c2ecf20Sopenharmony_ci         if(SiS_Pr->ChipType > SIS_315PRO) {
26398c2ecf20Sopenharmony_ci            if(ModeNo > 0x13) data &= 0xfc;
26408c2ecf20Sopenharmony_ci         }
26418c2ecf20Sopenharmony_ci         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
26428c2ecf20Sopenharmony_ci      }
26438c2ecf20Sopenharmony_ci
26448c2ecf20Sopenharmony_ci   }
26458c2ecf20Sopenharmony_ci}
26468c2ecf20Sopenharmony_ci
26478c2ecf20Sopenharmony_cistatic void
26488c2ecf20Sopenharmony_ciSiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
26498c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex, unsigned short RRTI)
26508c2ecf20Sopenharmony_ci{
26518c2ecf20Sopenharmony_ci   unsigned short data, infoflag = 0, modeflag, resindex;
26528c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
26538c2ecf20Sopenharmony_ci   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
26548c2ecf20Sopenharmony_ci   unsigned short data2, data3;
26558c2ecf20Sopenharmony_ci#endif
26568c2ecf20Sopenharmony_ci
26578c2ecf20Sopenharmony_ci   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
26588c2ecf20Sopenharmony_ci
26598c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
26608c2ecf20Sopenharmony_ci      infoflag = SiS_Pr->CInfoFlag;
26618c2ecf20Sopenharmony_ci   } else {
26628c2ecf20Sopenharmony_ci      resindex = SiS_GetResInfo(SiS_Pr, ModeNo, ModeIdIndex);
26638c2ecf20Sopenharmony_ci      if(ModeNo > 0x13) {
26648c2ecf20Sopenharmony_ci	 infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag;
26658c2ecf20Sopenharmony_ci      }
26668c2ecf20Sopenharmony_ci   }
26678c2ecf20Sopenharmony_ci
26688c2ecf20Sopenharmony_ci   /* Disable DPMS */
26698c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
26708c2ecf20Sopenharmony_ci
26718c2ecf20Sopenharmony_ci   data = 0;
26728c2ecf20Sopenharmony_ci   if(ModeNo > 0x13) {
26738c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_ModeType > ModeEGA) {
26748c2ecf20Sopenharmony_ci         data |= 0x02;
26758c2ecf20Sopenharmony_ci         data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
26768c2ecf20Sopenharmony_ci      }
26778c2ecf20Sopenharmony_ci      if(infoflag & InterlaceMode) data |= 0x20;
26788c2ecf20Sopenharmony_ci   }
26798c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
26808c2ecf20Sopenharmony_ci
26818c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType != SIS_300) {
26828c2ecf20Sopenharmony_ci      data = 0;
26838c2ecf20Sopenharmony_ci      if(infoflag & InterlaceMode) {
26848c2ecf20Sopenharmony_ci	 /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */
26858c2ecf20Sopenharmony_ci	 int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) |
26868c2ecf20Sopenharmony_ci		    ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3;
26878c2ecf20Sopenharmony_ci	 int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) |
26888c2ecf20Sopenharmony_ci		    ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5;
26898c2ecf20Sopenharmony_ci	 data = hrs - (hto >> 1) + 3;
26908c2ecf20Sopenharmony_ci      }
26918c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data);
26928c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03));
26938c2ecf20Sopenharmony_ci   }
26948c2ecf20Sopenharmony_ci
26958c2ecf20Sopenharmony_ci   if(modeflag & HalfDCLK) {
26968c2ecf20Sopenharmony_ci      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
26978c2ecf20Sopenharmony_ci   }
26988c2ecf20Sopenharmony_ci
26998c2ecf20Sopenharmony_ci   data = 0;
27008c2ecf20Sopenharmony_ci   if(modeflag & LineCompareOff) data = 0x08;
27018c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_300) {
27028c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
27038c2ecf20Sopenharmony_ci   } else {
27048c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType >= XGI_20) data |= 0x20;
27058c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_ModeType == ModeEGA) {
27068c2ecf20Sopenharmony_ci	 if(ModeNo > 0x13) {
27078c2ecf20Sopenharmony_ci	    data |= 0x40;
27088c2ecf20Sopenharmony_ci	 }
27098c2ecf20Sopenharmony_ci      }
27108c2ecf20Sopenharmony_ci      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
27118c2ecf20Sopenharmony_ci   }
27128c2ecf20Sopenharmony_ci
27138c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
27148c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_315H) {
27158c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
27168c2ecf20Sopenharmony_ci   }
27178c2ecf20Sopenharmony_ci
27188c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == SIS_315PRO) {
27198c2ecf20Sopenharmony_ci
27208c2ecf20Sopenharmony_ci      data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)];
27218c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_ModeType == ModeText) {
27228c2ecf20Sopenharmony_ci	 data &= 0xc7;
27238c2ecf20Sopenharmony_ci      } else {
27248c2ecf20Sopenharmony_ci	 data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1;
27258c2ecf20Sopenharmony_ci	 if(infoflag & InterlaceMode) data2 >>= 1;
27268c2ecf20Sopenharmony_ci	 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
27278c2ecf20Sopenharmony_ci	 if(data3) data2 /= data3;
27288c2ecf20Sopenharmony_ci	 if(data2 >= 0x50) {
27298c2ecf20Sopenharmony_ci	    data &= 0x0f;
27308c2ecf20Sopenharmony_ci	    data |= 0x50;
27318c2ecf20Sopenharmony_ci	 }
27328c2ecf20Sopenharmony_ci      }
27338c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
27348c2ecf20Sopenharmony_ci
27358c2ecf20Sopenharmony_ci   } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) {
27368c2ecf20Sopenharmony_ci
27378c2ecf20Sopenharmony_ci      data = SiS_Get310DRAMType(SiS_Pr);
27388c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType == SIS_330) {
27398c2ecf20Sopenharmony_ci	 data = SiS_Pr->SiS_SR15[(2 * 4) + data];
27408c2ecf20Sopenharmony_ci      } else {
27418c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_ROMNew)	     data = ROMAddr[0xf6];
27428c2ecf20Sopenharmony_ci	 else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
27438c2ecf20Sopenharmony_ci	 else			     data = 0xba;
27448c2ecf20Sopenharmony_ci      }
27458c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_ModeType <= ModeEGA) {
27468c2ecf20Sopenharmony_ci	 data &= 0xc7;
27478c2ecf20Sopenharmony_ci      } else {
27488c2ecf20Sopenharmony_ci	 if(SiS_Pr->UseCustomMode) {
27498c2ecf20Sopenharmony_ci	    data2 = SiS_Pr->CSRClock;
27508c2ecf20Sopenharmony_ci	 } else {
27518c2ecf20Sopenharmony_ci	    data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
27528c2ecf20Sopenharmony_ci	    data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
27538c2ecf20Sopenharmony_ci	 }
27548c2ecf20Sopenharmony_ci
27558c2ecf20Sopenharmony_ci	 data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1;
27568c2ecf20Sopenharmony_ci	 if(data3) data2 *= data3;
27578c2ecf20Sopenharmony_ci
27588c2ecf20Sopenharmony_ci	 data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2;
27598c2ecf20Sopenharmony_ci
27608c2ecf20Sopenharmony_ci	 if(SiS_Pr->ChipType == SIS_330) {
27618c2ecf20Sopenharmony_ci	    if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
27628c2ecf20Sopenharmony_ci	       if     (data2 >= 0x19c) data = 0xba;
27638c2ecf20Sopenharmony_ci	       else if(data2 >= 0x140) data = 0x7a;
27648c2ecf20Sopenharmony_ci	       else if(data2 >= 0x101) data = 0x3a;
27658c2ecf20Sopenharmony_ci	       else if(data2 >= 0xf5)  data = 0x32;
27668c2ecf20Sopenharmony_ci	       else if(data2 >= 0xe2)  data = 0x2a;
27678c2ecf20Sopenharmony_ci	       else if(data2 >= 0xc4)  data = 0x22;
27688c2ecf20Sopenharmony_ci	       else if(data2 >= 0xac)  data = 0x1a;
27698c2ecf20Sopenharmony_ci	       else if(data2 >= 0x9e)  data = 0x12;
27708c2ecf20Sopenharmony_ci	       else if(data2 >= 0x8e)  data = 0x0a;
27718c2ecf20Sopenharmony_ci	       else                    data = 0x02;
27728c2ecf20Sopenharmony_ci	    } else {
27738c2ecf20Sopenharmony_ci	       if(data2 >= 0x127)      data = 0xba;
27748c2ecf20Sopenharmony_ci	       else                    data = 0x7a;
27758c2ecf20Sopenharmony_ci	    }
27768c2ecf20Sopenharmony_ci	 } else {  /* 76x+LFB */
27778c2ecf20Sopenharmony_ci	    if     (data2 >= 0x190) data = 0xba;
27788c2ecf20Sopenharmony_ci	    else if(data2 >= 0xff)  data = 0x7a;
27798c2ecf20Sopenharmony_ci	    else if(data2 >= 0xd3)  data = 0x3a;
27808c2ecf20Sopenharmony_ci	    else if(data2 >= 0xa9)  data = 0x1a;
27818c2ecf20Sopenharmony_ci	    else if(data2 >= 0x93)  data = 0x0a;
27828c2ecf20Sopenharmony_ci	    else                    data = 0x02;
27838c2ecf20Sopenharmony_ci	 }
27848c2ecf20Sopenharmony_ci      }
27858c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
27868c2ecf20Sopenharmony_ci
27878c2ecf20Sopenharmony_ci   }
27888c2ecf20Sopenharmony_ci      /* XGI: Nothing. */
27898c2ecf20Sopenharmony_ci      /* TODO: Check SiS340 */
27908c2ecf20Sopenharmony_ci#endif
27918c2ecf20Sopenharmony_ci
27928c2ecf20Sopenharmony_ci   data = 0x60;
27938c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_ModeType != ModeText) {
27948c2ecf20Sopenharmony_ci      data ^= 0x60;
27958c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_ModeType != ModeEGA) {
27968c2ecf20Sopenharmony_ci         data ^= 0xA0;
27978c2ecf20Sopenharmony_ci      }
27988c2ecf20Sopenharmony_ci   }
27998c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
28008c2ecf20Sopenharmony_ci
28018c2ecf20Sopenharmony_ci   SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
28028c2ecf20Sopenharmony_ci
28038c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
28048c2ecf20Sopenharmony_ci   if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
28058c2ecf20Sopenharmony_ci       (SiS_Pr->ChipType == XGI_40)) {
28068c2ecf20Sopenharmony_ci      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
28078c2ecf20Sopenharmony_ci         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
28088c2ecf20Sopenharmony_ci      } else {
28098c2ecf20Sopenharmony_ci         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
28108c2ecf20Sopenharmony_ci      }
28118c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType == XGI_20) {
28128c2ecf20Sopenharmony_ci      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
28138c2ecf20Sopenharmony_ci         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33);
28148c2ecf20Sopenharmony_ci      } else {
28158c2ecf20Sopenharmony_ci         SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73);
28168c2ecf20Sopenharmony_ci      }
28178c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02);
28188c2ecf20Sopenharmony_ci   }
28198c2ecf20Sopenharmony_ci#endif
28208c2ecf20Sopenharmony_ci}
28218c2ecf20Sopenharmony_ci
28228c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
28238c2ecf20Sopenharmony_cistatic void
28248c2ecf20Sopenharmony_ciSiS_SetupDualChip(struct SiS_Private *SiS_Pr)
28258c2ecf20Sopenharmony_ci{
28268c2ecf20Sopenharmony_ci#if 0
28278c2ecf20Sopenharmony_ci   /* TODO: Find out about IOAddress2 */
28288c2ecf20Sopenharmony_ci   SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12;
28298c2ecf20Sopenharmony_ci   SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14;
28308c2ecf20Sopenharmony_ci   SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e;
28318c2ecf20Sopenharmony_ci   int i;
28328c2ecf20Sopenharmony_ci
28338c2ecf20Sopenharmony_ci   if((SiS_Pr->ChipRevision != 0) ||
28348c2ecf20Sopenharmony_ci      (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04)))
28358c2ecf20Sopenharmony_ci      return;
28368c2ecf20Sopenharmony_ci
28378c2ecf20Sopenharmony_ci   for(i = 0; i <= 4; i++) {					/* SR00 - SR04 */
28388c2ecf20Sopenharmony_ci      SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i));
28398c2ecf20Sopenharmony_ci   }
28408c2ecf20Sopenharmony_ci   for(i = 0; i <= 8; i++) {					/* GR00 - GR08 */
28418c2ecf20Sopenharmony_ci      SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i));
28428c2ecf20Sopenharmony_ci   }
28438c2ecf20Sopenharmony_ci   SiS_SetReg(P2_3c4,0x05,0x86);
28448c2ecf20Sopenharmony_ci   SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06));	/* SR06 */
28458c2ecf20Sopenharmony_ci   SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21));	/* SR21 */
28468c2ecf20Sopenharmony_ci   SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc));	/* MISC */
28478c2ecf20Sopenharmony_ci   SiS_SetReg(P2_3c4,0x05,0x00);
28488c2ecf20Sopenharmony_ci#endif
28498c2ecf20Sopenharmony_ci}
28508c2ecf20Sopenharmony_ci#endif
28518c2ecf20Sopenharmony_ci
28528c2ecf20Sopenharmony_ci/*********************************************/
28538c2ecf20Sopenharmony_ci/*                 LOAD DAC                  */
28548c2ecf20Sopenharmony_ci/*********************************************/
28558c2ecf20Sopenharmony_ci
28568c2ecf20Sopenharmony_cistatic void
28578c2ecf20Sopenharmony_ciSiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag,
28588c2ecf20Sopenharmony_ci             unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh)
28598c2ecf20Sopenharmony_ci{
28608c2ecf20Sopenharmony_ci   unsigned short d1, d2, d3;
28618c2ecf20Sopenharmony_ci
28628c2ecf20Sopenharmony_ci   switch(dl) {
28638c2ecf20Sopenharmony_ci   case  0: d1 = dh; d2 = ah; d3 = al; break;
28648c2ecf20Sopenharmony_ci   case  1: d1 = ah; d2 = al; d3 = dh; break;
28658c2ecf20Sopenharmony_ci   default: d1 = al; d2 = dh; d3 = ah;
28668c2ecf20Sopenharmony_ci   }
28678c2ecf20Sopenharmony_ci   SiS_SetRegByte(DACData, (d1 << shiftflag));
28688c2ecf20Sopenharmony_ci   SiS_SetRegByte(DACData, (d2 << shiftflag));
28698c2ecf20Sopenharmony_ci   SiS_SetRegByte(DACData, (d3 << shiftflag));
28708c2ecf20Sopenharmony_ci}
28718c2ecf20Sopenharmony_ci
28728c2ecf20Sopenharmony_civoid
28738c2ecf20Sopenharmony_ciSiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
28748c2ecf20Sopenharmony_ci{
28758c2ecf20Sopenharmony_ci   unsigned short data, data2, time, i, j, k, m, n, o;
28768c2ecf20Sopenharmony_ci   unsigned short si, di, bx, sf;
28778c2ecf20Sopenharmony_ci   SISIOADDRESS DACAddr, DACData;
28788c2ecf20Sopenharmony_ci   const unsigned char *table = NULL;
28798c2ecf20Sopenharmony_ci
28808c2ecf20Sopenharmony_ci   data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag;
28818c2ecf20Sopenharmony_ci
28828c2ecf20Sopenharmony_ci   j = time = 64;
28838c2ecf20Sopenharmony_ci   if(data == 0x00)      table = SiS_MDA_DAC;
28848c2ecf20Sopenharmony_ci   else if(data == 0x08) table = SiS_CGA_DAC;
28858c2ecf20Sopenharmony_ci   else if(data == 0x10) table = SiS_EGA_DAC;
28868c2ecf20Sopenharmony_ci   else if(data == 0x18) {
28878c2ecf20Sopenharmony_ci      j = 16;
28888c2ecf20Sopenharmony_ci      time = 256;
28898c2ecf20Sopenharmony_ci      table = SiS_VGA_DAC;
28908c2ecf20Sopenharmony_ci   }
28918c2ecf20Sopenharmony_ci
28928c2ecf20Sopenharmony_ci   if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&        /* 301B-DH LCD */
28938c2ecf20Sopenharmony_ci         (SiS_Pr->SiS_VBType & VB_NoLCD) )        ||
28948c2ecf20Sopenharmony_ci       (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)       ||   /* LCDA */
28958c2ecf20Sopenharmony_ci       (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {  /* Programming CRT1 */
28968c2ecf20Sopenharmony_ci      SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
28978c2ecf20Sopenharmony_ci      DACAddr = SiS_Pr->SiS_P3c8;
28988c2ecf20Sopenharmony_ci      DACData = SiS_Pr->SiS_P3c9;
28998c2ecf20Sopenharmony_ci      sf = 0;
29008c2ecf20Sopenharmony_ci   } else {
29018c2ecf20Sopenharmony_ci      DACAddr = SiS_Pr->SiS_Part5Port;
29028c2ecf20Sopenharmony_ci      DACData = SiS_Pr->SiS_Part5Port + 1;
29038c2ecf20Sopenharmony_ci      sf = 2;
29048c2ecf20Sopenharmony_ci   }
29058c2ecf20Sopenharmony_ci
29068c2ecf20Sopenharmony_ci   SiS_SetRegByte(DACAddr,0x00);
29078c2ecf20Sopenharmony_ci
29088c2ecf20Sopenharmony_ci   for(i = 0; i < j; i++) {
29098c2ecf20Sopenharmony_ci      data = table[i];
29108c2ecf20Sopenharmony_ci      for(k = 0; k < 3; k++) {
29118c2ecf20Sopenharmony_ci	data2 = 0;
29128c2ecf20Sopenharmony_ci	if(data & 0x01) data2 += 0x2A;
29138c2ecf20Sopenharmony_ci	if(data & 0x02) data2 += 0x15;
29148c2ecf20Sopenharmony_ci	SiS_SetRegByte(DACData, (data2 << sf));
29158c2ecf20Sopenharmony_ci	data >>= 2;
29168c2ecf20Sopenharmony_ci      }
29178c2ecf20Sopenharmony_ci   }
29188c2ecf20Sopenharmony_ci
29198c2ecf20Sopenharmony_ci   if(time == 256) {
29208c2ecf20Sopenharmony_ci      for(i = 16; i < 32; i++) {
29218c2ecf20Sopenharmony_ci	 data = table[i] << sf;
29228c2ecf20Sopenharmony_ci	 for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
29238c2ecf20Sopenharmony_ci      }
29248c2ecf20Sopenharmony_ci      si = 32;
29258c2ecf20Sopenharmony_ci      for(m = 0; m < 9; m++) {
29268c2ecf20Sopenharmony_ci	 di = si;
29278c2ecf20Sopenharmony_ci	 bx = si + 4;
29288c2ecf20Sopenharmony_ci	 for(n = 0; n < 3; n++) {
29298c2ecf20Sopenharmony_ci	    for(o = 0; o < 5; o++) {
29308c2ecf20Sopenharmony_ci	       SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]);
29318c2ecf20Sopenharmony_ci	       si++;
29328c2ecf20Sopenharmony_ci	    }
29338c2ecf20Sopenharmony_ci	    si -= 2;
29348c2ecf20Sopenharmony_ci	    for(o = 0; o < 3; o++) {
29358c2ecf20Sopenharmony_ci	       SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]);
29368c2ecf20Sopenharmony_ci	       si--;
29378c2ecf20Sopenharmony_ci	    }
29388c2ecf20Sopenharmony_ci	 }            /* for n < 3 */
29398c2ecf20Sopenharmony_ci	 si += 5;
29408c2ecf20Sopenharmony_ci      }               /* for m < 9 */
29418c2ecf20Sopenharmony_ci   }
29428c2ecf20Sopenharmony_ci}
29438c2ecf20Sopenharmony_ci
29448c2ecf20Sopenharmony_ci/*********************************************/
29458c2ecf20Sopenharmony_ci/*         SET CRT1 REGISTER GROUP           */
29468c2ecf20Sopenharmony_ci/*********************************************/
29478c2ecf20Sopenharmony_ci
29488c2ecf20Sopenharmony_cistatic void
29498c2ecf20Sopenharmony_ciSiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
29508c2ecf20Sopenharmony_ci{
29518c2ecf20Sopenharmony_ci   unsigned short StandTableIndex, RefreshRateTableIndex;
29528c2ecf20Sopenharmony_ci
29538c2ecf20Sopenharmony_ci   SiS_Pr->SiS_CRT1Mode = ModeNo;
29548c2ecf20Sopenharmony_ci
29558c2ecf20Sopenharmony_ci   StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
29568c2ecf20Sopenharmony_ci
29578c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_SetFlag & LowModeTests) {
29588c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
29598c2ecf20Sopenharmony_ci         SiS_DisableBridge(SiS_Pr);
29608c2ecf20Sopenharmony_ci      }
29618c2ecf20Sopenharmony_ci   }
29628c2ecf20Sopenharmony_ci
29638c2ecf20Sopenharmony_ci   SiS_ResetSegmentRegisters(SiS_Pr);
29648c2ecf20Sopenharmony_ci
29658c2ecf20Sopenharmony_ci   SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
29668c2ecf20Sopenharmony_ci   SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
29678c2ecf20Sopenharmony_ci   SiS_SetCRTCRegs(SiS_Pr, StandTableIndex);
29688c2ecf20Sopenharmony_ci   SiS_SetATTRegs(SiS_Pr, StandTableIndex);
29698c2ecf20Sopenharmony_ci   SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
29708c2ecf20Sopenharmony_ci   SiS_ClearExt1Regs(SiS_Pr, ModeNo);
29718c2ecf20Sopenharmony_ci   SiS_ResetCRT1VCLK(SiS_Pr);
29728c2ecf20Sopenharmony_ci
29738c2ecf20Sopenharmony_ci   SiS_Pr->SiS_SelectCRT2Rate = 0;
29748c2ecf20Sopenharmony_ci   SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
29758c2ecf20Sopenharmony_ci
29768c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
29778c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
29788c2ecf20Sopenharmony_ci         SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
29798c2ecf20Sopenharmony_ci      }
29808c2ecf20Sopenharmony_ci   }
29818c2ecf20Sopenharmony_ci
29828c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
29838c2ecf20Sopenharmony_ci      SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
29848c2ecf20Sopenharmony_ci   }
29858c2ecf20Sopenharmony_ci
29868c2ecf20Sopenharmony_ci   RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
29878c2ecf20Sopenharmony_ci
29888c2ecf20Sopenharmony_ci   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
29898c2ecf20Sopenharmony_ci      SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
29908c2ecf20Sopenharmony_ci   }
29918c2ecf20Sopenharmony_ci
29928c2ecf20Sopenharmony_ci   if(RefreshRateTableIndex != 0xFFFF) {
29938c2ecf20Sopenharmony_ci      SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
29948c2ecf20Sopenharmony_ci      SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
29958c2ecf20Sopenharmony_ci      SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
29968c2ecf20Sopenharmony_ci      SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
29978c2ecf20Sopenharmony_ci   }
29988c2ecf20Sopenharmony_ci
29998c2ecf20Sopenharmony_ci   switch(SiS_Pr->ChipType) {
30008c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
30018c2ecf20Sopenharmony_ci   case SIS_300:
30028c2ecf20Sopenharmony_ci      SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
30038c2ecf20Sopenharmony_ci      break;
30048c2ecf20Sopenharmony_ci   case SIS_540:
30058c2ecf20Sopenharmony_ci   case SIS_630:
30068c2ecf20Sopenharmony_ci   case SIS_730:
30078c2ecf20Sopenharmony_ci      SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex);
30088c2ecf20Sopenharmony_ci      break;
30098c2ecf20Sopenharmony_ci#endif
30108c2ecf20Sopenharmony_ci   default:
30118c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
30128c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType == XGI_20) {
30138c2ecf20Sopenharmony_ci         unsigned char sr2b = 0, sr2c = 0;
30148c2ecf20Sopenharmony_ci         switch(ModeNo) {
30158c2ecf20Sopenharmony_ci	 case 0x00:
30168c2ecf20Sopenharmony_ci	 case 0x01: sr2b = 0x4e; sr2c = 0xe9; break;
30178c2ecf20Sopenharmony_ci	 case 0x04:
30188c2ecf20Sopenharmony_ci	 case 0x05:
30198c2ecf20Sopenharmony_ci	 case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break;
30208c2ecf20Sopenharmony_ci	 }
30218c2ecf20Sopenharmony_ci	 if(sr2b) {
30228c2ecf20Sopenharmony_ci            SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b);
30238c2ecf20Sopenharmony_ci	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c);
30248c2ecf20Sopenharmony_ci	    SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c));
30258c2ecf20Sopenharmony_ci	 }
30268c2ecf20Sopenharmony_ci      }
30278c2ecf20Sopenharmony_ci      SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex);
30288c2ecf20Sopenharmony_ci#endif
30298c2ecf20Sopenharmony_ci      break;
30308c2ecf20Sopenharmony_ci   }
30318c2ecf20Sopenharmony_ci
30328c2ecf20Sopenharmony_ci   SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
30338c2ecf20Sopenharmony_ci
30348c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
30358c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType == XGI_40) {
30368c2ecf20Sopenharmony_ci      SiS_SetupDualChip(SiS_Pr);
30378c2ecf20Sopenharmony_ci   }
30388c2ecf20Sopenharmony_ci#endif
30398c2ecf20Sopenharmony_ci
30408c2ecf20Sopenharmony_ci   SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
30418c2ecf20Sopenharmony_ci
30428c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_flag_clearbuffer) {
30438c2ecf20Sopenharmony_ci      SiS_ClearBuffer(SiS_Pr, ModeNo);
30448c2ecf20Sopenharmony_ci   }
30458c2ecf20Sopenharmony_ci
30468c2ecf20Sopenharmony_ci   if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
30478c2ecf20Sopenharmony_ci      SiS_WaitRetrace1(SiS_Pr);
30488c2ecf20Sopenharmony_ci      SiS_DisplayOn(SiS_Pr);
30498c2ecf20Sopenharmony_ci   }
30508c2ecf20Sopenharmony_ci}
30518c2ecf20Sopenharmony_ci
30528c2ecf20Sopenharmony_ci/*********************************************/
30538c2ecf20Sopenharmony_ci/*       HELPER: VIDEO BRIDGE PROG CLK       */
30548c2ecf20Sopenharmony_ci/*********************************************/
30558c2ecf20Sopenharmony_ci
30568c2ecf20Sopenharmony_cistatic void
30578c2ecf20Sopenharmony_ciSiS_InitVB(struct SiS_Private *SiS_Pr)
30588c2ecf20Sopenharmony_ci{
30598c2ecf20Sopenharmony_ci   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
30608c2ecf20Sopenharmony_ci
30618c2ecf20Sopenharmony_ci   SiS_Pr->Init_P4_0E = 0;
30628c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_ROMNew) {
30638c2ecf20Sopenharmony_ci      SiS_Pr->Init_P4_0E = ROMAddr[0x82];
30648c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType >= XGI_40) {
30658c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_XGIROM) {
30668c2ecf20Sopenharmony_ci         SiS_Pr->Init_P4_0E = ROMAddr[0x80];
30678c2ecf20Sopenharmony_ci      }
30688c2ecf20Sopenharmony_ci   }
30698c2ecf20Sopenharmony_ci}
30708c2ecf20Sopenharmony_ci
30718c2ecf20Sopenharmony_cistatic void
30728c2ecf20Sopenharmony_ciSiS_ResetVB(struct SiS_Private *SiS_Pr)
30738c2ecf20Sopenharmony_ci{
30748c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
30758c2ecf20Sopenharmony_ci   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
30768c2ecf20Sopenharmony_ci   unsigned short temp;
30778c2ecf20Sopenharmony_ci
30788c2ecf20Sopenharmony_ci   /* VB programming clock */
30798c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_UseROM) {
30808c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType < SIS_330) {
30818c2ecf20Sopenharmony_ci	 temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
30828c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
30838c2ecf20Sopenharmony_ci	 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
30848c2ecf20Sopenharmony_ci      } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) {
30858c2ecf20Sopenharmony_ci	 temp = ROMAddr[0x7e] | 0x40;
30868c2ecf20Sopenharmony_ci	 if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
30878c2ecf20Sopenharmony_ci	 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
30888c2ecf20Sopenharmony_ci      }
30898c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType >= XGI_40) {
30908c2ecf20Sopenharmony_ci      temp = 0x40;
30918c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e];
30928c2ecf20Sopenharmony_ci      /* Can we do this on any chipset? */
30938c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
30948c2ecf20Sopenharmony_ci   }
30958c2ecf20Sopenharmony_ci#endif
30968c2ecf20Sopenharmony_ci}
30978c2ecf20Sopenharmony_ci
30988c2ecf20Sopenharmony_ci/*********************************************/
30998c2ecf20Sopenharmony_ci/*    HELPER: SET VIDEO/CAPTURE REGISTERS    */
31008c2ecf20Sopenharmony_ci/*********************************************/
31018c2ecf20Sopenharmony_ci
31028c2ecf20Sopenharmony_cistatic void
31038c2ecf20Sopenharmony_ciSiS_StrangeStuff(struct SiS_Private *SiS_Pr)
31048c2ecf20Sopenharmony_ci{
31058c2ecf20Sopenharmony_ci   /* SiS65x and XGI set up some sort of "lock mode" for text
31068c2ecf20Sopenharmony_ci    * which locks CRT2 in some way to CRT1 timing. Disable
31078c2ecf20Sopenharmony_ci    * this here.
31088c2ecf20Sopenharmony_ci    */
31098c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
31108c2ecf20Sopenharmony_ci   if((IS_SIS651) || (IS_SISM650) ||
31118c2ecf20Sopenharmony_ci      SiS_Pr->ChipType == SIS_340 ||
31128c2ecf20Sopenharmony_ci      SiS_Pr->ChipType == XGI_40) {
31138c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);   /* Fiddle with capture regs */
31148c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
31158c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86);   /* (BIOS does NOT unlock) */
31168c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
31178c2ecf20Sopenharmony_ci      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
31188c2ecf20Sopenharmony_ci   }
31198c2ecf20Sopenharmony_ci   /* !!! This does not support modes < 0x13 !!! */
31208c2ecf20Sopenharmony_ci#endif
31218c2ecf20Sopenharmony_ci}
31228c2ecf20Sopenharmony_ci
31238c2ecf20Sopenharmony_ci/*********************************************/
31248c2ecf20Sopenharmony_ci/*     HELPER: SET AGP TIMING FOR SiS760     */
31258c2ecf20Sopenharmony_ci/*********************************************/
31268c2ecf20Sopenharmony_ci
31278c2ecf20Sopenharmony_cistatic void
31288c2ecf20Sopenharmony_ciSiS_Handle760(struct SiS_Private *SiS_Pr)
31298c2ecf20Sopenharmony_ci{
31308c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
31318c2ecf20Sopenharmony_ci   unsigned int somebase;
31328c2ecf20Sopenharmony_ci   unsigned char temp1, temp2, temp3;
31338c2ecf20Sopenharmony_ci
31348c2ecf20Sopenharmony_ci   if( (SiS_Pr->ChipType != SIS_760)                         ||
31358c2ecf20Sopenharmony_ci       ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) ||
31368c2ecf20Sopenharmony_ci       (!(SiS_Pr->SiS_SysFlags & SF_760LFB))                 ||
31378c2ecf20Sopenharmony_ci       (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
31388c2ecf20Sopenharmony_ci      return;
31398c2ecf20Sopenharmony_ci
31408c2ecf20Sopenharmony_ci   somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
31418c2ecf20Sopenharmony_ci   somebase &= 0xffff;
31428c2ecf20Sopenharmony_ci
31438c2ecf20Sopenharmony_ci   if(somebase == 0) return;
31448c2ecf20Sopenharmony_ci
31458c2ecf20Sopenharmony_ci   temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7;
31468c2ecf20Sopenharmony_ci
31478c2ecf20Sopenharmony_ci   if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
31488c2ecf20Sopenharmony_ci      temp1 = 0x21;
31498c2ecf20Sopenharmony_ci      temp2 = 0x03;
31508c2ecf20Sopenharmony_ci      temp3 |= 0x08;
31518c2ecf20Sopenharmony_ci   } else {
31528c2ecf20Sopenharmony_ci      temp1 = 0x25;
31538c2ecf20Sopenharmony_ci      temp2 = 0x0b;
31548c2ecf20Sopenharmony_ci   }
31558c2ecf20Sopenharmony_ci
31568c2ecf20Sopenharmony_ci   sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
31578c2ecf20Sopenharmony_ci   sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
31588c2ecf20Sopenharmony_ci
31598c2ecf20Sopenharmony_ci   SiS_SetRegByte((somebase + 0x85), temp3);
31608c2ecf20Sopenharmony_ci#endif
31618c2ecf20Sopenharmony_ci}
31628c2ecf20Sopenharmony_ci
31638c2ecf20Sopenharmony_ci/*********************************************/
31648c2ecf20Sopenharmony_ci/*                 SiSSetMode()              */
31658c2ecf20Sopenharmony_ci/*********************************************/
31668c2ecf20Sopenharmony_ci
31678c2ecf20Sopenharmony_cibool
31688c2ecf20Sopenharmony_ciSiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
31698c2ecf20Sopenharmony_ci{
31708c2ecf20Sopenharmony_ci   SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
31718c2ecf20Sopenharmony_ci   unsigned short RealModeNo, ModeIdIndex;
31728c2ecf20Sopenharmony_ci   unsigned char  backupreg = 0;
31738c2ecf20Sopenharmony_ci   unsigned short KeepLockReg;
31748c2ecf20Sopenharmony_ci
31758c2ecf20Sopenharmony_ci   SiS_Pr->UseCustomMode = false;
31768c2ecf20Sopenharmony_ci   SiS_Pr->CRT1UsesCustomMode = false;
31778c2ecf20Sopenharmony_ci
31788c2ecf20Sopenharmony_ci   SiS_Pr->SiS_flag_clearbuffer = 0;
31798c2ecf20Sopenharmony_ci
31808c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
31818c2ecf20Sopenharmony_ci      ModeNo = 0xfe;
31828c2ecf20Sopenharmony_ci   } else {
31838c2ecf20Sopenharmony_ci      if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
31848c2ecf20Sopenharmony_ci      ModeNo &= 0x7f;
31858c2ecf20Sopenharmony_ci   }
31868c2ecf20Sopenharmony_ci
31878c2ecf20Sopenharmony_ci   /* Don't use FSTN mode for CRT1 */
31888c2ecf20Sopenharmony_ci   RealModeNo = ModeNo;
31898c2ecf20Sopenharmony_ci   if(ModeNo == 0x5b) ModeNo = 0x56;
31908c2ecf20Sopenharmony_ci
31918c2ecf20Sopenharmony_ci   SiSInitPtr(SiS_Pr);
31928c2ecf20Sopenharmony_ci   SiSRegInit(SiS_Pr, BaseAddr);
31938c2ecf20Sopenharmony_ci   SiS_GetSysFlags(SiS_Pr);
31948c2ecf20Sopenharmony_ci
31958c2ecf20Sopenharmony_ci   SiS_Pr->SiS_VGAINFO = 0x11;
31968c2ecf20Sopenharmony_ci
31978c2ecf20Sopenharmony_ci   KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
31988c2ecf20Sopenharmony_ci   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
31998c2ecf20Sopenharmony_ci
32008c2ecf20Sopenharmony_ci   SiSInitPCIetc(SiS_Pr);
32018c2ecf20Sopenharmony_ci   SiSSetLVDSetc(SiS_Pr);
32028c2ecf20Sopenharmony_ci   SiSDetermineROMUsage(SiS_Pr);
32038c2ecf20Sopenharmony_ci
32048c2ecf20Sopenharmony_ci   SiS_UnLockCRT2(SiS_Pr);
32058c2ecf20Sopenharmony_ci
32068c2ecf20Sopenharmony_ci   if(!SiS_Pr->UseCustomMode) {
32078c2ecf20Sopenharmony_ci      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
32088c2ecf20Sopenharmony_ci   } else {
32098c2ecf20Sopenharmony_ci      ModeIdIndex = 0;
32108c2ecf20Sopenharmony_ci   }
32118c2ecf20Sopenharmony_ci
32128c2ecf20Sopenharmony_ci   SiS_GetVBType(SiS_Pr);
32138c2ecf20Sopenharmony_ci
32148c2ecf20Sopenharmony_ci   /* Init/restore some VB registers */
32158c2ecf20Sopenharmony_ci   SiS_InitVB(SiS_Pr);
32168c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
32178c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType >= SIS_315H) {
32188c2ecf20Sopenharmony_ci         SiS_ResetVB(SiS_Pr);
32198c2ecf20Sopenharmony_ci	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
32208c2ecf20Sopenharmony_ci	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
32218c2ecf20Sopenharmony_ci         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
32228c2ecf20Sopenharmony_ci      } else {
32238c2ecf20Sopenharmony_ci         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
32248c2ecf20Sopenharmony_ci      }
32258c2ecf20Sopenharmony_ci   }
32268c2ecf20Sopenharmony_ci
32278c2ecf20Sopenharmony_ci   /* Get VB information (connectors, connected devices) */
32288c2ecf20Sopenharmony_ci   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1);
32298c2ecf20Sopenharmony_ci   SiS_SetYPbPr(SiS_Pr);
32308c2ecf20Sopenharmony_ci   SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
32318c2ecf20Sopenharmony_ci   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
32328c2ecf20Sopenharmony_ci   SiS_SetLowModeTest(SiS_Pr, ModeNo);
32338c2ecf20Sopenharmony_ci
32348c2ecf20Sopenharmony_ci   /* Check memory size (kernel framebuffer driver only) */
32358c2ecf20Sopenharmony_ci   if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
32368c2ecf20Sopenharmony_ci      return false;
32378c2ecf20Sopenharmony_ci   }
32388c2ecf20Sopenharmony_ci
32398c2ecf20Sopenharmony_ci   SiS_OpenCRTC(SiS_Pr);
32408c2ecf20Sopenharmony_ci
32418c2ecf20Sopenharmony_ci   if(SiS_Pr->UseCustomMode) {
32428c2ecf20Sopenharmony_ci      SiS_Pr->CRT1UsesCustomMode = true;
32438c2ecf20Sopenharmony_ci      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
32448c2ecf20Sopenharmony_ci      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
32458c2ecf20Sopenharmony_ci   } else {
32468c2ecf20Sopenharmony_ci      SiS_Pr->CRT1UsesCustomMode = false;
32478c2ecf20Sopenharmony_ci   }
32488c2ecf20Sopenharmony_ci
32498c2ecf20Sopenharmony_ci   /* Set mode on CRT1 */
32508c2ecf20Sopenharmony_ci   if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
32518c2ecf20Sopenharmony_ci       (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
32528c2ecf20Sopenharmony_ci      SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
32538c2ecf20Sopenharmony_ci   }
32548c2ecf20Sopenharmony_ci
32558c2ecf20Sopenharmony_ci   /* Set mode on CRT2 */
32568c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
32578c2ecf20Sopenharmony_ci      if( (SiS_Pr->SiS_VBType & VB_SISVB)    ||
32588c2ecf20Sopenharmony_ci	  (SiS_Pr->SiS_IF_DEF_LVDS     == 1) ||
32598c2ecf20Sopenharmony_ci	  (SiS_Pr->SiS_IF_DEF_CH70xx   != 0) ||
32608c2ecf20Sopenharmony_ci	  (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
32618c2ecf20Sopenharmony_ci	 SiS_SetCRT2Group(SiS_Pr, RealModeNo);
32628c2ecf20Sopenharmony_ci      }
32638c2ecf20Sopenharmony_ci   }
32648c2ecf20Sopenharmony_ci
32658c2ecf20Sopenharmony_ci   SiS_HandleCRT1(SiS_Pr);
32668c2ecf20Sopenharmony_ci
32678c2ecf20Sopenharmony_ci   SiS_StrangeStuff(SiS_Pr);
32688c2ecf20Sopenharmony_ci
32698c2ecf20Sopenharmony_ci   SiS_DisplayOn(SiS_Pr);
32708c2ecf20Sopenharmony_ci   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
32718c2ecf20Sopenharmony_ci
32728c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
32738c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType >= SIS_315H) {
32748c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
32758c2ecf20Sopenharmony_ci	 if(!(SiS_IsDualEdge(SiS_Pr))) {
32768c2ecf20Sopenharmony_ci	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
32778c2ecf20Sopenharmony_ci	 }
32788c2ecf20Sopenharmony_ci      }
32798c2ecf20Sopenharmony_ci   }
32808c2ecf20Sopenharmony_ci#endif
32818c2ecf20Sopenharmony_ci
32828c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
32838c2ecf20Sopenharmony_ci      if(SiS_Pr->ChipType >= SIS_315H) {
32848c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
32858c2ecf20Sopenharmony_ci	 if(!SiS_Pr->SiS_ROMNew) {
32868c2ecf20Sopenharmony_ci	    if(SiS_IsVAMode(SiS_Pr)) {
32878c2ecf20Sopenharmony_ci	       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
32888c2ecf20Sopenharmony_ci	    } else {
32898c2ecf20Sopenharmony_ci	       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
32908c2ecf20Sopenharmony_ci	    }
32918c2ecf20Sopenharmony_ci	 }
32928c2ecf20Sopenharmony_ci
32938c2ecf20Sopenharmony_ci	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
32948c2ecf20Sopenharmony_ci
32958c2ecf20Sopenharmony_ci	 if((IS_SIS650) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
32968c2ecf20Sopenharmony_ci	    if((ModeNo == 0x03) || (ModeNo == 0x10)) {
32978c2ecf20Sopenharmony_ci	       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
32988c2ecf20Sopenharmony_ci	       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
32998c2ecf20Sopenharmony_ci	    }
33008c2ecf20Sopenharmony_ci	 }
33018c2ecf20Sopenharmony_ci
33028c2ecf20Sopenharmony_ci	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
33038c2ecf20Sopenharmony_ci	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
33048c2ecf20Sopenharmony_ci	 }
33058c2ecf20Sopenharmony_ci#endif
33068c2ecf20Sopenharmony_ci      } else if((SiS_Pr->ChipType == SIS_630) ||
33078c2ecf20Sopenharmony_ci	        (SiS_Pr->ChipType == SIS_730)) {
33088c2ecf20Sopenharmony_ci	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
33098c2ecf20Sopenharmony_ci      }
33108c2ecf20Sopenharmony_ci   }
33118c2ecf20Sopenharmony_ci
33128c2ecf20Sopenharmony_ci   SiS_CloseCRTC(SiS_Pr);
33138c2ecf20Sopenharmony_ci
33148c2ecf20Sopenharmony_ci   SiS_Handle760(SiS_Pr);
33158c2ecf20Sopenharmony_ci
33168c2ecf20Sopenharmony_ci   /* We never lock registers in XF86 */
33178c2ecf20Sopenharmony_ci   if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
33188c2ecf20Sopenharmony_ci
33198c2ecf20Sopenharmony_ci   return true;
33208c2ecf20Sopenharmony_ci}
33218c2ecf20Sopenharmony_ci
33228c2ecf20Sopenharmony_ci#ifndef GETBITSTR
33238c2ecf20Sopenharmony_ci#define GENBITSMASK(mask)   	GENMASK(1?mask,0?mask)
33248c2ecf20Sopenharmony_ci#define GETBITS(var,mask)   	(((var) & GENBITSMASK(mask)) >> (0?mask))
33258c2ecf20Sopenharmony_ci#define GETBITSTR(val,from,to)  ((GETBITS(val,from)) << (0?to))
33268c2ecf20Sopenharmony_ci#endif
33278c2ecf20Sopenharmony_ci
33288c2ecf20Sopenharmony_civoid
33298c2ecf20Sopenharmony_ciSiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth)
33308c2ecf20Sopenharmony_ci{
33318c2ecf20Sopenharmony_ci   int x = 1; /* Fix sync */
33328c2ecf20Sopenharmony_ci
33338c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[0]  =  ((SiS_Pr->CHTotal >> 3) - 5) & 0xff;		/* CR0 */
33348c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[1]  =  (SiS_Pr->CHDisplay >> 3) - 1;			/* CR1 */
33358c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[2]  =  (SiS_Pr->CHBlankStart >> 3) - 1;			/* CR2 */
33368c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[3]  =  (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;	/* CR3 */
33378c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[4]  =  (SiS_Pr->CHSyncStart >> 3) + 3;			/* CR4 */
33388c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[5]  =  ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |	/* CR5 */
33398c2ecf20Sopenharmony_ci			    (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
33408c2ecf20Sopenharmony_ci
33418c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[6]  =  (SiS_Pr->CVTotal       - 2) & 0xFF;			/* CR6 */
33428c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[7]  =  (((SiS_Pr->CVTotal     - 2) & 0x100) >> 8)		/* CR7 */
33438c2ecf20Sopenharmony_ci			  | (((SiS_Pr->CVDisplay   - 1) & 0x100) >> 7)
33448c2ecf20Sopenharmony_ci			  | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6)
33458c2ecf20Sopenharmony_ci			  | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5)
33468c2ecf20Sopenharmony_ci			  | 0x10
33478c2ecf20Sopenharmony_ci			  | (((SiS_Pr->CVTotal     - 2) & 0x200) >> 4)
33488c2ecf20Sopenharmony_ci			  | (((SiS_Pr->CVDisplay   - 1) & 0x200) >> 3)
33498c2ecf20Sopenharmony_ci			  | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2);
33508c2ecf20Sopenharmony_ci
33518c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); 	/* CR9 */
33528c2ecf20Sopenharmony_ci
33538c2ecf20Sopenharmony_ci   if(depth != 8) {
33548c2ecf20Sopenharmony_ci      if(SiS_Pr->CHDisplay >= 1600)      SiS_Pr->CCRT1CRTC[16] |= 0x60;		/* SRE */
33558c2ecf20Sopenharmony_ci      else if(SiS_Pr->CHDisplay >= 640)  SiS_Pr->CCRT1CRTC[16] |= 0x40;
33568c2ecf20Sopenharmony_ci   }
33578c2ecf20Sopenharmony_ci
33588c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[8] =  (SiS_Pr->CVSyncStart  - x) & 0xFF;			/* CR10 */
33598c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[9] =  ((SiS_Pr->CVSyncEnd   - x) & 0x0F) | 0x80;		/* CR11 */
33608c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay    - 1) & 0xFF;			/* CR12 */
33618c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF;			/* CR15 */
33628c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd   - 1) & 0xFF;			/* CR16 */
33638c2ecf20Sopenharmony_ci
33648c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[13] =							/* SRA */
33658c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CVTotal     -2), 10:10, 0:0) |
33668c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
33678c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
33688c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) |
33698c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
33708c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
33718c2ecf20Sopenharmony_ci
33728c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[14] =							/* SRB */
33738c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
33748c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
33758c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
33768c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
33778c2ecf20Sopenharmony_ci
33788c2ecf20Sopenharmony_ci
33798c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[15] =							/* SRC */
33808c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
33818c2ecf20Sopenharmony_ci			GETBITSTR((SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
33828c2ecf20Sopenharmony_ci}
33838c2ecf20Sopenharmony_ci
33848c2ecf20Sopenharmony_civoid
33858c2ecf20Sopenharmony_ciSiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
33868c2ecf20Sopenharmony_ci		unsigned short ModeIdIndex)
33878c2ecf20Sopenharmony_ci{
33888c2ecf20Sopenharmony_ci   unsigned short modeflag, tempax, tempbx = 0, remaining = 0;
33898c2ecf20Sopenharmony_ci   unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE;
33908c2ecf20Sopenharmony_ci   int i, j;
33918c2ecf20Sopenharmony_ci
33928c2ecf20Sopenharmony_ci   /* 1:1 data: use data set by setcrt1crtc() */
33938c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
33948c2ecf20Sopenharmony_ci
33958c2ecf20Sopenharmony_ci   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
33968c2ecf20Sopenharmony_ci
33978c2ecf20Sopenharmony_ci   if(modeflag & HalfDCLK) VGAHDE >>= 1;
33988c2ecf20Sopenharmony_ci
33998c2ecf20Sopenharmony_ci   SiS_Pr->CHDisplay = VGAHDE;
34008c2ecf20Sopenharmony_ci   SiS_Pr->CHBlankStart = VGAHDE;
34018c2ecf20Sopenharmony_ci
34028c2ecf20Sopenharmony_ci   SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
34038c2ecf20Sopenharmony_ci   SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
34048c2ecf20Sopenharmony_ci
34058c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType < SIS_315H) {
34068c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
34078c2ecf20Sopenharmony_ci      tempbx = SiS_Pr->SiS_VGAHT;
34088c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
34098c2ecf20Sopenharmony_ci         tempbx = SiS_Pr->PanelHT;
34108c2ecf20Sopenharmony_ci      }
34118c2ecf20Sopenharmony_ci      if(modeflag & HalfDCLK) tempbx >>= 1;
34128c2ecf20Sopenharmony_ci      remaining = tempbx % 8;
34138c2ecf20Sopenharmony_ci#endif
34148c2ecf20Sopenharmony_ci   } else {
34158c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
34168c2ecf20Sopenharmony_ci      /* OK for LCDA, LVDS */
34178c2ecf20Sopenharmony_ci      tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
34188c2ecf20Sopenharmony_ci      tempax = SiS_Pr->SiS_VGAHDE;  /* not /2 ! */
34198c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
34208c2ecf20Sopenharmony_ci         tempax = SiS_Pr->PanelXRes;
34218c2ecf20Sopenharmony_ci      }
34228c2ecf20Sopenharmony_ci      tempbx += tempax;
34238c2ecf20Sopenharmony_ci      if(modeflag & HalfDCLK) tempbx -= VGAHDE;
34248c2ecf20Sopenharmony_ci#endif
34258c2ecf20Sopenharmony_ci   }
34268c2ecf20Sopenharmony_ci   SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
34278c2ecf20Sopenharmony_ci
34288c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType < SIS_315H) {
34298c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
34308c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
34318c2ecf20Sopenharmony_ci	 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
34328c2ecf20Sopenharmony_ci	 SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
34338c2ecf20Sopenharmony_ci	 if(modeflag & HalfDCLK) {
34348c2ecf20Sopenharmony_ci	    SiS_Pr->CHSyncStart >>= 1;
34358c2ecf20Sopenharmony_ci	    SiS_Pr->CHSyncEnd >>= 1;
34368c2ecf20Sopenharmony_ci	 }
34378c2ecf20Sopenharmony_ci      } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
34388c2ecf20Sopenharmony_ci	 tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1;
34398c2ecf20Sopenharmony_ci	 tempbx = (SiS_Pr->PanelHRS + 1) & ~1;
34408c2ecf20Sopenharmony_ci	 if(modeflag & HalfDCLK) {
34418c2ecf20Sopenharmony_ci	    tempax >>= 1;
34428c2ecf20Sopenharmony_ci	    tempbx >>= 1;
34438c2ecf20Sopenharmony_ci	 }
34448c2ecf20Sopenharmony_ci	 SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7;
34458c2ecf20Sopenharmony_ci	 tempax = SiS_Pr->PanelHRE + 7;
34468c2ecf20Sopenharmony_ci	 if(modeflag & HalfDCLK) tempax >>= 1;
34478c2ecf20Sopenharmony_ci	 SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7;
34488c2ecf20Sopenharmony_ci      } else {
34498c2ecf20Sopenharmony_ci	 SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE;
34508c2ecf20Sopenharmony_ci	 if(modeflag & HalfDCLK) {
34518c2ecf20Sopenharmony_ci	    SiS_Pr->CHSyncStart >>= 1;
34528c2ecf20Sopenharmony_ci	    tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1;
34538c2ecf20Sopenharmony_ci	    SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax;
34548c2ecf20Sopenharmony_ci	 } else {
34558c2ecf20Sopenharmony_ci	    SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7;
34568c2ecf20Sopenharmony_ci	    SiS_Pr->CHSyncStart += 8;
34578c2ecf20Sopenharmony_ci	 }
34588c2ecf20Sopenharmony_ci      }
34598c2ecf20Sopenharmony_ci#endif
34608c2ecf20Sopenharmony_ci   } else {
34618c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_315
34628c2ecf20Sopenharmony_ci      tempax = VGAHDE;
34638c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
34648c2ecf20Sopenharmony_ci	 tempbx = SiS_Pr->PanelXRes;
34658c2ecf20Sopenharmony_ci	 if(modeflag & HalfDCLK) tempbx >>= 1;
34668c2ecf20Sopenharmony_ci	 tempax += ((tempbx - tempax) >> 1);
34678c2ecf20Sopenharmony_ci      }
34688c2ecf20Sopenharmony_ci      tempax += SiS_Pr->PanelHRS;
34698c2ecf20Sopenharmony_ci      SiS_Pr->CHSyncStart = tempax;
34708c2ecf20Sopenharmony_ci      tempax += SiS_Pr->PanelHRE;
34718c2ecf20Sopenharmony_ci      SiS_Pr->CHSyncEnd = tempax;
34728c2ecf20Sopenharmony_ci#endif
34738c2ecf20Sopenharmony_ci   }
34748c2ecf20Sopenharmony_ci
34758c2ecf20Sopenharmony_ci   tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
34768c2ecf20Sopenharmony_ci   tempax = SiS_Pr->SiS_VGAVDE;
34778c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
34788c2ecf20Sopenharmony_ci      tempax = SiS_Pr->PanelYRes;
34798c2ecf20Sopenharmony_ci   } else if(SiS_Pr->ChipType < SIS_315H) {
34808c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_SIS_300
34818c2ecf20Sopenharmony_ci      /* Stupid hack for 640x400/320x200 */
34828c2ecf20Sopenharmony_ci      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
34838c2ecf20Sopenharmony_ci	 if((tempax + tempbx) == 438) tempbx += 16;
34848c2ecf20Sopenharmony_ci      } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) ||
34858c2ecf20Sopenharmony_ci		(SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) {
34868c2ecf20Sopenharmony_ci	 tempax = 0;
34878c2ecf20Sopenharmony_ci	 tempbx = SiS_Pr->SiS_VGAVT;
34888c2ecf20Sopenharmony_ci      }
34898c2ecf20Sopenharmony_ci#endif
34908c2ecf20Sopenharmony_ci   }
34918c2ecf20Sopenharmony_ci   SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
34928c2ecf20Sopenharmony_ci
34938c2ecf20Sopenharmony_ci   tempax = SiS_Pr->SiS_VGAVDE;
34948c2ecf20Sopenharmony_ci   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
34958c2ecf20Sopenharmony_ci      tempax += (SiS_Pr->PanelYRes - tempax) >> 1;
34968c2ecf20Sopenharmony_ci   }
34978c2ecf20Sopenharmony_ci   tempax += SiS_Pr->PanelVRS;
34988c2ecf20Sopenharmony_ci   SiS_Pr->CVSyncStart = tempax;
34998c2ecf20Sopenharmony_ci   tempax += SiS_Pr->PanelVRE;
35008c2ecf20Sopenharmony_ci   SiS_Pr->CVSyncEnd = tempax;
35018c2ecf20Sopenharmony_ci   if(SiS_Pr->ChipType < SIS_315H) {
35028c2ecf20Sopenharmony_ci      SiS_Pr->CVSyncStart--;
35038c2ecf20Sopenharmony_ci      SiS_Pr->CVSyncEnd--;
35048c2ecf20Sopenharmony_ci   }
35058c2ecf20Sopenharmony_ci
35068c2ecf20Sopenharmony_ci   SiS_CalcCRRegisters(SiS_Pr, 8);
35078c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[15] &= ~0xF8;
35088c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[15] |= (remaining << 4);
35098c2ecf20Sopenharmony_ci   SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
35108c2ecf20Sopenharmony_ci
35118c2ecf20Sopenharmony_ci   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
35128c2ecf20Sopenharmony_ci
35138c2ecf20Sopenharmony_ci   for(i = 0, j = 0; i <= 7; i++, j++) {
35148c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
35158c2ecf20Sopenharmony_ci   }
35168c2ecf20Sopenharmony_ci   for(j = 0x10; i <= 10; i++, j++) {
35178c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
35188c2ecf20Sopenharmony_ci   }
35198c2ecf20Sopenharmony_ci   for(j = 0x15; i <= 12; i++, j++) {
35208c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
35218c2ecf20Sopenharmony_ci   }
35228c2ecf20Sopenharmony_ci   for(j = 0x0A; i <= 15; i++, j++) {
35238c2ecf20Sopenharmony_ci      SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
35248c2ecf20Sopenharmony_ci   }
35258c2ecf20Sopenharmony_ci
35268c2ecf20Sopenharmony_ci   tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0;
35278c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax);
35288c2ecf20Sopenharmony_ci
35298c2ecf20Sopenharmony_ci   tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
35308c2ecf20Sopenharmony_ci   if(modeflag & DoubleScanMode) tempax |= 0x80;
35318c2ecf20Sopenharmony_ci   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
35328c2ecf20Sopenharmony_ci
35338c2ecf20Sopenharmony_ci}
35348c2ecf20Sopenharmony_ci
35358c2ecf20Sopenharmony_civoid
35368c2ecf20Sopenharmony_ciSiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
35378c2ecf20Sopenharmony_ci			int xres, int yres,
35388c2ecf20Sopenharmony_ci			struct fb_var_screeninfo *var, bool writeres
35398c2ecf20Sopenharmony_ci)
35408c2ecf20Sopenharmony_ci{
35418c2ecf20Sopenharmony_ci   unsigned short HRE, HBE, HRS, HBS, HDE, HT;
35428c2ecf20Sopenharmony_ci   unsigned short VRE, VBE, VRS, VBS, VDE, VT;
35438c2ecf20Sopenharmony_ci   unsigned char  sr_data, cr_data, cr_data2;
35448c2ecf20Sopenharmony_ci   int            A, B, C, D, E, F, temp;
35458c2ecf20Sopenharmony_ci
35468c2ecf20Sopenharmony_ci   sr_data = crdata[14];
35478c2ecf20Sopenharmony_ci
35488c2ecf20Sopenharmony_ci   /* Horizontal total */
35498c2ecf20Sopenharmony_ci   HT =  crdata[0] | ((unsigned short)(sr_data & 0x03) << 8);
35508c2ecf20Sopenharmony_ci   A = HT + 5;
35518c2ecf20Sopenharmony_ci
35528c2ecf20Sopenharmony_ci   /* Horizontal display enable end */
35538c2ecf20Sopenharmony_ci   HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6);
35548c2ecf20Sopenharmony_ci   E = HDE + 1;
35558c2ecf20Sopenharmony_ci
35568c2ecf20Sopenharmony_ci   /* Horizontal retrace (=sync) start */
35578c2ecf20Sopenharmony_ci   HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2);
35588c2ecf20Sopenharmony_ci   F = HRS - E - 3;
35598c2ecf20Sopenharmony_ci
35608c2ecf20Sopenharmony_ci   /* Horizontal blank start */
35618c2ecf20Sopenharmony_ci   HBS = crdata[2] | ((unsigned short)(sr_data & 0x30) << 4);
35628c2ecf20Sopenharmony_ci
35638c2ecf20Sopenharmony_ci   sr_data = crdata[15];
35648c2ecf20Sopenharmony_ci   cr_data = crdata[5];
35658c2ecf20Sopenharmony_ci
35668c2ecf20Sopenharmony_ci   /* Horizontal blank end */
35678c2ecf20Sopenharmony_ci   HBE = (crdata[3] & 0x1f) |
35688c2ecf20Sopenharmony_ci         ((unsigned short)(cr_data & 0x80) >> 2) |
35698c2ecf20Sopenharmony_ci         ((unsigned short)(sr_data & 0x03) << 6);
35708c2ecf20Sopenharmony_ci
35718c2ecf20Sopenharmony_ci   /* Horizontal retrace (=sync) end */
35728c2ecf20Sopenharmony_ci   HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3);
35738c2ecf20Sopenharmony_ci
35748c2ecf20Sopenharmony_ci   temp = HBE - ((E - 1) & 255);
35758c2ecf20Sopenharmony_ci   B = (temp > 0) ? temp : (temp + 256);
35768c2ecf20Sopenharmony_ci
35778c2ecf20Sopenharmony_ci   temp = HRE - ((E + F + 3) & 63);
35788c2ecf20Sopenharmony_ci   C = (temp > 0) ? temp : (temp + 64);
35798c2ecf20Sopenharmony_ci
35808c2ecf20Sopenharmony_ci   D = B - F - C;
35818c2ecf20Sopenharmony_ci
35828c2ecf20Sopenharmony_ci   if(writeres) var->xres = xres = E * 8;
35838c2ecf20Sopenharmony_ci   var->left_margin = D * 8;
35848c2ecf20Sopenharmony_ci   var->right_margin = F * 8;
35858c2ecf20Sopenharmony_ci   var->hsync_len = C * 8;
35868c2ecf20Sopenharmony_ci
35878c2ecf20Sopenharmony_ci   /* Vertical */
35888c2ecf20Sopenharmony_ci   sr_data = crdata[13];
35898c2ecf20Sopenharmony_ci   cr_data = crdata[7];
35908c2ecf20Sopenharmony_ci
35918c2ecf20Sopenharmony_ci   /* Vertical total */
35928c2ecf20Sopenharmony_ci   VT  = crdata[6] |
35938c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data & 0x01) << 8) |
35948c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data & 0x20) << 4) |
35958c2ecf20Sopenharmony_ci	 ((unsigned short)(sr_data & 0x01) << 10);
35968c2ecf20Sopenharmony_ci   A = VT + 2;
35978c2ecf20Sopenharmony_ci
35988c2ecf20Sopenharmony_ci   /* Vertical display enable end */
35998c2ecf20Sopenharmony_ci   VDE = crdata[10] |
36008c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data & 0x02) << 7) |
36018c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data & 0x40) << 3) |
36028c2ecf20Sopenharmony_ci	 ((unsigned short)(sr_data & 0x02) << 9);
36038c2ecf20Sopenharmony_ci   E = VDE + 1;
36048c2ecf20Sopenharmony_ci
36058c2ecf20Sopenharmony_ci   /* Vertical retrace (=sync) start */
36068c2ecf20Sopenharmony_ci   VRS = crdata[8] |
36078c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data & 0x04) << 6) |
36088c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data & 0x80) << 2) |
36098c2ecf20Sopenharmony_ci	 ((unsigned short)(sr_data & 0x08) << 7);
36108c2ecf20Sopenharmony_ci   F = VRS + 1 - E;
36118c2ecf20Sopenharmony_ci
36128c2ecf20Sopenharmony_ci   cr_data2 = (crdata[16] & 0x01) << 5;
36138c2ecf20Sopenharmony_ci
36148c2ecf20Sopenharmony_ci   /* Vertical blank start */
36158c2ecf20Sopenharmony_ci   VBS = crdata[11] |
36168c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data  & 0x08) << 5) |
36178c2ecf20Sopenharmony_ci	 ((unsigned short)(cr_data2 & 0x20) << 4) |
36188c2ecf20Sopenharmony_ci	 ((unsigned short)(sr_data  & 0x04) << 8);
36198c2ecf20Sopenharmony_ci
36208c2ecf20Sopenharmony_ci   /* Vertical blank end */
36218c2ecf20Sopenharmony_ci   VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4);
36228c2ecf20Sopenharmony_ci   temp = VBE - ((E - 1) & 511);
36238c2ecf20Sopenharmony_ci   B = (temp > 0) ? temp : (temp + 512);
36248c2ecf20Sopenharmony_ci
36258c2ecf20Sopenharmony_ci   /* Vertical retrace (=sync) end */
36268c2ecf20Sopenharmony_ci   VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1);
36278c2ecf20Sopenharmony_ci   temp = VRE - ((E + F - 1) & 31);
36288c2ecf20Sopenharmony_ci   C = (temp > 0) ? temp : (temp + 32);
36298c2ecf20Sopenharmony_ci
36308c2ecf20Sopenharmony_ci   D = B - F - C;
36318c2ecf20Sopenharmony_ci
36328c2ecf20Sopenharmony_ci   if(writeres) var->yres = yres = E;
36338c2ecf20Sopenharmony_ci   var->upper_margin = D;
36348c2ecf20Sopenharmony_ci   var->lower_margin = F;
36358c2ecf20Sopenharmony_ci   var->vsync_len = C;
36368c2ecf20Sopenharmony_ci
36378c2ecf20Sopenharmony_ci   if((xres == 320) && ((yres == 200) || (yres == 240))) {
36388c2ecf20Sopenharmony_ci	/* Terrible hack, but correct CRTC data for
36398c2ecf20Sopenharmony_ci	 * these modes only produces a black screen...
36408c2ecf20Sopenharmony_ci	 * (HRE is 0, leading into a too large C and
36418c2ecf20Sopenharmony_ci	 * a negative D. The CRT controller does not
36428c2ecf20Sopenharmony_ci	 * seem to like correcting HRE to 50)
36438c2ecf20Sopenharmony_ci	 */
36448c2ecf20Sopenharmony_ci      var->left_margin = (400 - 376);
36458c2ecf20Sopenharmony_ci      var->right_margin = (328 - 320);
36468c2ecf20Sopenharmony_ci      var->hsync_len = (376 - 328);
36478c2ecf20Sopenharmony_ci
36488c2ecf20Sopenharmony_ci   }
36498c2ecf20Sopenharmony_ci
36508c2ecf20Sopenharmony_ci}
36518c2ecf20Sopenharmony_ci
36528c2ecf20Sopenharmony_ci
36538c2ecf20Sopenharmony_ci
36548c2ecf20Sopenharmony_ci
3655