162306a36Sopenharmony_ci/* $XFree86$ */ 262306a36Sopenharmony_ci/* $XdotOrg$ */ 362306a36Sopenharmony_ci/* 462306a36Sopenharmony_ci * Mode initializing code (CRT1 section) for 562306a36Sopenharmony_ci * for SiS 300/305/540/630/730, 662306a36Sopenharmony_ci * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX], 762306a36Sopenharmony_ci * XGI Volari V3XT/V5/V8, Z7 862306a36Sopenharmony_ci * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x) 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * If distributed as part of the Linux kernel, the following license terms 1362306a36Sopenharmony_ci * apply: 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * * This program is free software; you can redistribute it and/or modify 1662306a36Sopenharmony_ci * * it under the terms of the GNU General Public License as published by 1762306a36Sopenharmony_ci * * the Free Software Foundation; either version 2 of the named License, 1862306a36Sopenharmony_ci * * or any later version. 1962306a36Sopenharmony_ci * * 2062306a36Sopenharmony_ci * * This program is distributed in the hope that it will be useful, 2162306a36Sopenharmony_ci * * but WITHOUT ANY WARRANTY; without even the implied warranty of 2262306a36Sopenharmony_ci * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2362306a36Sopenharmony_ci * * GNU General Public License for more details. 2462306a36Sopenharmony_ci * * 2562306a36Sopenharmony_ci * * You should have received a copy of the GNU General Public License 2662306a36Sopenharmony_ci * * along with this program; if not, write to the Free Software 2762306a36Sopenharmony_ci * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * Otherwise, the following license terms apply: 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * * Redistribution and use in source and binary forms, with or without 3262306a36Sopenharmony_ci * * modification, are permitted provided that the following conditions 3362306a36Sopenharmony_ci * * are met: 3462306a36Sopenharmony_ci * * 1) Redistributions of source code must retain the above copyright 3562306a36Sopenharmony_ci * * notice, this list of conditions and the following disclaimer. 3662306a36Sopenharmony_ci * * 2) Redistributions in binary form must reproduce the above copyright 3762306a36Sopenharmony_ci * * notice, this list of conditions and the following disclaimer in the 3862306a36Sopenharmony_ci * * documentation and/or other materials provided with the distribution. 3962306a36Sopenharmony_ci * * 3) The name of the author may not be used to endorse or promote products 4062306a36Sopenharmony_ci * * derived from this software without specific prior written permission. 4162306a36Sopenharmony_ci * * 4262306a36Sopenharmony_ci * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 4362306a36Sopenharmony_ci * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 4462306a36Sopenharmony_ci * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 4562306a36Sopenharmony_ci * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 4662306a36Sopenharmony_ci * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4762306a36Sopenharmony_ci * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 4862306a36Sopenharmony_ci * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 4962306a36Sopenharmony_ci * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5062306a36Sopenharmony_ci * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 5162306a36Sopenharmony_ci * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * Author: Thomas Winischhofer <thomas@winischhofer.net> 5462306a36Sopenharmony_ci * 5562306a36Sopenharmony_ci * Formerly based on non-functional code-fragements for 300 series by SiS, Inc. 5662306a36Sopenharmony_ci * Used by permission. 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#include "init.h" 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 6262306a36Sopenharmony_ci#include "300vtbl.h" 6362306a36Sopenharmony_ci#endif 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 6662306a36Sopenharmony_ci#include "310vtbl.h" 6762306a36Sopenharmony_ci#endif 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#if defined(ALLOC_PRAGMA) 7062306a36Sopenharmony_ci#pragma alloc_text(PAGE,SiSSetMode) 7162306a36Sopenharmony_ci#endif 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/*********************************************/ 7462306a36Sopenharmony_ci/* POINTER INITIALIZATION */ 7562306a36Sopenharmony_ci/*********************************************/ 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 7862306a36Sopenharmony_cistatic void 7962306a36Sopenharmony_ciInitCommonPointer(struct SiS_Private *SiS_Pr) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci SiS_Pr->SiS_SModeIDTable = SiS_SModeIDTable; 8262306a36Sopenharmony_ci SiS_Pr->SiS_StResInfo = SiS_StResInfo; 8362306a36Sopenharmony_ci SiS_Pr->SiS_ModeResInfo = SiS_ModeResInfo; 8462306a36Sopenharmony_ci SiS_Pr->SiS_StandTable = SiS_StandTable; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci SiS_Pr->SiS_NTSCTiming = SiS_NTSCTiming; 8762306a36Sopenharmony_ci SiS_Pr->SiS_PALTiming = SiS_PALTiming; 8862306a36Sopenharmony_ci SiS_Pr->SiS_HiTVSt1Timing = SiS_HiTVSt1Timing; 8962306a36Sopenharmony_ci SiS_Pr->SiS_HiTVSt2Timing = SiS_HiTVSt2Timing; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci SiS_Pr->SiS_HiTVExtTiming = SiS_HiTVExtTiming; 9262306a36Sopenharmony_ci SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data; 9362306a36Sopenharmony_ci SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu; 9462306a36Sopenharmony_ci#if 0 9562306a36Sopenharmony_ci SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming; 9662306a36Sopenharmony_ci SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text; 9762306a36Sopenharmony_ci#endif 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci SiS_Pr->SiS_StPALData = SiS_StPALData; 10062306a36Sopenharmony_ci SiS_Pr->SiS_ExtPALData = SiS_ExtPALData; 10162306a36Sopenharmony_ci SiS_Pr->SiS_StNTSCData = SiS_StNTSCData; 10262306a36Sopenharmony_ci SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData; 10362306a36Sopenharmony_ci SiS_Pr->SiS_St1HiTVData = SiS_StHiTVData; 10462306a36Sopenharmony_ci SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData; 10562306a36Sopenharmony_ci SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData; 10662306a36Sopenharmony_ci SiS_Pr->SiS_St525iData = SiS_StNTSCData; 10762306a36Sopenharmony_ci SiS_Pr->SiS_St525pData = SiS_St525pData; 10862306a36Sopenharmony_ci SiS_Pr->SiS_St750pData = SiS_St750pData; 10962306a36Sopenharmony_ci SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData; 11062306a36Sopenharmony_ci SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData; 11162306a36Sopenharmony_ci SiS_Pr->SiS_Ext750pData = SiS_Ext750pData; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect; 11462306a36Sopenharmony_ci SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci SiS_Pr->SiS_LCD1280x720Data = SiS_LCD1280x720Data; 11762306a36Sopenharmony_ci SiS_Pr->SiS_StLCD1280x768_2Data = SiS_StLCD1280x768_2Data; 11862306a36Sopenharmony_ci SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data; 11962306a36Sopenharmony_ci SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data; 12062306a36Sopenharmony_ci SiS_Pr->SiS_LCD1280x800_2Data = SiS_LCD1280x800_2Data; 12162306a36Sopenharmony_ci SiS_Pr->SiS_LCD1280x854Data = SiS_LCD1280x854Data; 12262306a36Sopenharmony_ci SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data; 12362306a36Sopenharmony_ci SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data; 12462306a36Sopenharmony_ci SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data; 12562306a36Sopenharmony_ci SiS_Pr->SiS_LCD1680x1050Data = SiS_LCD1680x1050Data; 12662306a36Sopenharmony_ci SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data; 12762306a36Sopenharmony_ci SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data; 12862306a36Sopenharmony_ci SiS_Pr->SiS_NoScaleData = SiS_NoScaleData; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci SiS_Pr->SiS_LVDS320x240Data_1 = SiS_LVDS320x240Data_1; 13162306a36Sopenharmony_ci SiS_Pr->SiS_LVDS320x240Data_2 = SiS_LVDS320x240Data_2; 13262306a36Sopenharmony_ci SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1; 13362306a36Sopenharmony_ci SiS_Pr->SiS_LVDS800x600Data_1 = SiS_LVDS800x600Data_1; 13462306a36Sopenharmony_ci SiS_Pr->SiS_LVDS1024x600Data_1 = SiS_LVDS1024x600Data_1; 13562306a36Sopenharmony_ci SiS_Pr->SiS_LVDS1024x768Data_1 = SiS_LVDS1024x768Data_1; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT1320x240_1 = SiS_LVDSCRT1320x240_1; 13862306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT1320x240_2 = SiS_LVDSCRT1320x240_2; 13962306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT1320x240_2_H = SiS_LVDSCRT1320x240_2_H; 14062306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT1320x240_3 = SiS_LVDSCRT1320x240_3; 14162306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT1320x240_3_H = SiS_LVDSCRT1320x240_3_H; 14262306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1; 14362306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H; 14462306a36Sopenharmony_ci#if 0 14562306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1; 14662306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT11024x600_1_H = SiS_LVDSCRT11024x600_1_H; 14762306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT11024x600_2 = SiS_LVDSCRT11024x600_2; 14862306a36Sopenharmony_ci SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H; 14962306a36Sopenharmony_ci#endif 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData; 15262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */ 15562306a36Sopenharmony_ci SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */ 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci#endif 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 16062306a36Sopenharmony_cistatic void 16162306a36Sopenharmony_ciInitTo300Pointer(struct SiS_Private *SiS_Pr) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci InitCommonPointer(SiS_Pr); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable; 16662306a36Sopenharmony_ci SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable; 16762306a36Sopenharmony_ci SiS_Pr->SiS_RefIndex = SiS300_RefIndex; 16862306a36Sopenharmony_ci SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table; 16962306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_300) { 17062306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */ 17162306a36Sopenharmony_ci } else { 17262306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */ 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci SiS_Pr->SiS_VCLKData = SiS300_VCLKData; 17562306a36Sopenharmony_ci SiS_Pr->SiS_VBVCLKData = (struct SiS_VBVCLKData *)SiS300_VCLKData; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci SiS_Pr->SiS_SR15 = SiS300_SR15; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl; 18062306a36Sopenharmony_ci SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci SiS_Pr->SiS_ExtLCD1024x768Data = SiS300_ExtLCD1024x768Data; 18362306a36Sopenharmony_ci SiS_Pr->SiS_St2LCD1024x768Data = SiS300_St2LCD1024x768Data; 18462306a36Sopenharmony_ci SiS_Pr->SiS_ExtLCD1280x1024Data = SiS300_ExtLCD1280x1024Data; 18562306a36Sopenharmony_ci SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1; 18862306a36Sopenharmony_ci SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2; 18962306a36Sopenharmony_ci SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData; 19262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData; 19362306a36Sopenharmony_ci SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */ 19462306a36Sopenharmony_ci SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */ 19562306a36Sopenharmony_ci SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData; /* not supported on 300 series */ 19662306a36Sopenharmony_ci SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */ 19762306a36Sopenharmony_ci SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci SiS_Pr->SiS_LVDS848x480Data_1 = SiS300_LVDS848x480Data_1; 20062306a36Sopenharmony_ci SiS_Pr->SiS_LVDS848x480Data_2 = SiS300_LVDS848x480Data_2; 20162306a36Sopenharmony_ci SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1; 20262306a36Sopenharmony_ci SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1; 20362306a36Sopenharmony_ci SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a; 20662306a36Sopenharmony_ci SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a; 20762306a36Sopenharmony_ci SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b; 20862306a36Sopenharmony_ci SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC; 21162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC; 21262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1UPAL = SiS300_CHTVCRT1UPAL; 21362306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1OPAL = SiS300_CHTVCRT1OPAL; 21462306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL; 21562306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC; 21662306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC; 21762306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UPAL = SiS300_CHTVReg_UPAL; 21862306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_OPAL = SiS300_CHTVReg_OPAL; 21962306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC; /* not supported on 300 series */ 22062306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC; /* not supported on 300 series */ 22162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL; /* not supported on 300 series */ 22262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL; /* not supported on 300 series */ 22362306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL; 22462306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC; 22562306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC; 22662306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL; 22762306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKOPAL = SiS300_CHTVVCLKOPAL; 22862306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC; /* not supported on 300 series */ 22962306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC; /* not supported on 300 series */ 23062306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL; /* not supported on 300 series */ 23162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */ 23262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL; 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci#endif 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 23762306a36Sopenharmony_cistatic void 23862306a36Sopenharmony_ciInitTo310Pointer(struct SiS_Private *SiS_Pr) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci InitCommonPointer(SiS_Pr); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable; 24362306a36Sopenharmony_ci SiS_Pr->SiS_RefIndex = SiS310_RefIndex; 24462306a36Sopenharmony_ci SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table; 24562306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_340) { 24662306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340; /* 340 + XGI */ 24762306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_761) { 24862306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761; /* 761 - preliminary */ 24962306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_760) { 25062306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */ 25162306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_661) { 25262306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */ 25362306a36Sopenharmony_ci } else if(SiS_Pr->ChipType == SIS_330) { 25462306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */ 25562306a36Sopenharmony_ci } else if(SiS_Pr->ChipType > SIS_315PRO) { 25662306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */ 25762306a36Sopenharmony_ci } else { 25862306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */ 25962306a36Sopenharmony_ci } 26062306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_340) { 26162306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340; 26262306a36Sopenharmony_ci } else { 26362306a36Sopenharmony_ci SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1; 26462306a36Sopenharmony_ci } 26562306a36Sopenharmony_ci SiS_Pr->SiS_VCLKData = SiS310_VCLKData; 26662306a36Sopenharmony_ci SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci SiS_Pr->SiS_SR15 = SiS310_SR15; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl; 27162306a36Sopenharmony_ci SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci SiS_Pr->SiS_St2LCD1024x768Data = SiS310_St2LCD1024x768Data; 27462306a36Sopenharmony_ci SiS_Pr->SiS_ExtLCD1024x768Data = SiS310_ExtLCD1024x768Data; 27562306a36Sopenharmony_ci SiS_Pr->SiS_St2LCD1280x1024Data = SiS310_St2LCD1280x1024Data; 27662306a36Sopenharmony_ci SiS_Pr->SiS_ExtLCD1280x1024Data = SiS310_ExtLCD1280x1024Data; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData; 28162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData; 28262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData; 28362306a36Sopenharmony_ci SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData; 28462306a36Sopenharmony_ci SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData; 28562306a36Sopenharmony_ci SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData; 28662306a36Sopenharmony_ci SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC; 28962306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC; 29062306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL; 29162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL; 29262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC; 29562306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC; 29662306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UPAL = SiS310_CHTVReg_UPAL; 29762306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_OPAL = SiS310_CHTVReg_OPAL; 29862306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM; 29962306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM; 30062306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN; 30162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN; 30262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC; 30562306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC; 30662306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUPAL = SiS310_CHTVVCLKUPAL; 30762306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKOPAL = SiS310_CHTVVCLKOPAL; 30862306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM; 30962306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM; 31062306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN; 31162306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN; 31262306a36Sopenharmony_ci SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL; 31362306a36Sopenharmony_ci} 31462306a36Sopenharmony_ci#endif 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cibool 31762306a36Sopenharmony_ciSiSInitPtr(struct SiS_Private *SiS_Pr) 31862306a36Sopenharmony_ci{ 31962306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_315H) { 32062306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 32162306a36Sopenharmony_ci InitTo300Pointer(SiS_Pr); 32262306a36Sopenharmony_ci#else 32362306a36Sopenharmony_ci return false; 32462306a36Sopenharmony_ci#endif 32562306a36Sopenharmony_ci } else { 32662306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 32762306a36Sopenharmony_ci InitTo310Pointer(SiS_Pr); 32862306a36Sopenharmony_ci#else 32962306a36Sopenharmony_ci return false; 33062306a36Sopenharmony_ci#endif 33162306a36Sopenharmony_ci } 33262306a36Sopenharmony_ci return true; 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/*********************************************/ 33662306a36Sopenharmony_ci/* HELPER: Get ModeID */ 33762306a36Sopenharmony_ci/*********************************************/ 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistatic 34062306a36Sopenharmony_ciunsigned short 34162306a36Sopenharmony_ciSiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, 34262306a36Sopenharmony_ci int Depth, bool FSTN, int LCDwidth, int LCDheight) 34362306a36Sopenharmony_ci{ 34462306a36Sopenharmony_ci unsigned short ModeIndex = 0; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci switch(HDisplay) 34762306a36Sopenharmony_ci { 34862306a36Sopenharmony_ci case 320: 34962306a36Sopenharmony_ci if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 35062306a36Sopenharmony_ci else if(VDisplay == 240) { 35162306a36Sopenharmony_ci if((VBFlags & CRT2_LCD) && (FSTN)) 35262306a36Sopenharmony_ci ModeIndex = ModeIndex_320x240_FSTN[Depth]; 35362306a36Sopenharmony_ci else 35462306a36Sopenharmony_ci ModeIndex = ModeIndex_320x240[Depth]; 35562306a36Sopenharmony_ci } 35662306a36Sopenharmony_ci break; 35762306a36Sopenharmony_ci case 400: 35862306a36Sopenharmony_ci if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDheight >= 600))) { 35962306a36Sopenharmony_ci if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci break; 36262306a36Sopenharmony_ci case 512: 36362306a36Sopenharmony_ci if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDheight >= 768))) { 36462306a36Sopenharmony_ci if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 36562306a36Sopenharmony_ci } 36662306a36Sopenharmony_ci break; 36762306a36Sopenharmony_ci case 640: 36862306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 36962306a36Sopenharmony_ci else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 37062306a36Sopenharmony_ci break; 37162306a36Sopenharmony_ci case 720: 37262306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth]; 37362306a36Sopenharmony_ci else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth]; 37462306a36Sopenharmony_ci break; 37562306a36Sopenharmony_ci case 768: 37662306a36Sopenharmony_ci if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 37762306a36Sopenharmony_ci break; 37862306a36Sopenharmony_ci case 800: 37962306a36Sopenharmony_ci if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 38062306a36Sopenharmony_ci else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; 38162306a36Sopenharmony_ci break; 38262306a36Sopenharmony_ci case 848: 38362306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 38462306a36Sopenharmony_ci break; 38562306a36Sopenharmony_ci case 856: 38662306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 38762306a36Sopenharmony_ci break; 38862306a36Sopenharmony_ci case 960: 38962306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 39062306a36Sopenharmony_ci if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth]; 39162306a36Sopenharmony_ci else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth]; 39262306a36Sopenharmony_ci } 39362306a36Sopenharmony_ci break; 39462306a36Sopenharmony_ci case 1024: 39562306a36Sopenharmony_ci if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth]; 39662306a36Sopenharmony_ci else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 39762306a36Sopenharmony_ci else if(VGAEngine == SIS_300_VGA) { 39862306a36Sopenharmony_ci if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth]; 39962306a36Sopenharmony_ci } 40062306a36Sopenharmony_ci break; 40162306a36Sopenharmony_ci case 1152: 40262306a36Sopenharmony_ci if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth]; 40362306a36Sopenharmony_ci if(VGAEngine == SIS_300_VGA) { 40462306a36Sopenharmony_ci if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth]; 40562306a36Sopenharmony_ci } 40662306a36Sopenharmony_ci break; 40762306a36Sopenharmony_ci case 1280: 40862306a36Sopenharmony_ci switch(VDisplay) { 40962306a36Sopenharmony_ci case 720: 41062306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x720[Depth]; 41162306a36Sopenharmony_ci break; 41262306a36Sopenharmony_ci case 768: 41362306a36Sopenharmony_ci if(VGAEngine == SIS_300_VGA) { 41462306a36Sopenharmony_ci ModeIndex = ModeIndex_300_1280x768[Depth]; 41562306a36Sopenharmony_ci } else { 41662306a36Sopenharmony_ci ModeIndex = ModeIndex_310_1280x768[Depth]; 41762306a36Sopenharmony_ci } 41862306a36Sopenharmony_ci break; 41962306a36Sopenharmony_ci case 800: 42062306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 42162306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x800[Depth]; 42262306a36Sopenharmony_ci } 42362306a36Sopenharmony_ci break; 42462306a36Sopenharmony_ci case 854: 42562306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 42662306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x854[Depth]; 42762306a36Sopenharmony_ci } 42862306a36Sopenharmony_ci break; 42962306a36Sopenharmony_ci case 960: 43062306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x960[Depth]; 43162306a36Sopenharmony_ci break; 43262306a36Sopenharmony_ci case 1024: 43362306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x1024[Depth]; 43462306a36Sopenharmony_ci break; 43562306a36Sopenharmony_ci } 43662306a36Sopenharmony_ci break; 43762306a36Sopenharmony_ci case 1360: 43862306a36Sopenharmony_ci if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 43962306a36Sopenharmony_ci if(VGAEngine == SIS_300_VGA) { 44062306a36Sopenharmony_ci if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth]; 44162306a36Sopenharmony_ci } 44262306a36Sopenharmony_ci break; 44362306a36Sopenharmony_ci case 1400: 44462306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 44562306a36Sopenharmony_ci if(VDisplay == 1050) { 44662306a36Sopenharmony_ci ModeIndex = ModeIndex_1400x1050[Depth]; 44762306a36Sopenharmony_ci } 44862306a36Sopenharmony_ci } 44962306a36Sopenharmony_ci break; 45062306a36Sopenharmony_ci case 1600: 45162306a36Sopenharmony_ci if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 45262306a36Sopenharmony_ci break; 45362306a36Sopenharmony_ci case 1680: 45462306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 45562306a36Sopenharmony_ci if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; 45662306a36Sopenharmony_ci } 45762306a36Sopenharmony_ci break; 45862306a36Sopenharmony_ci case 1920: 45962306a36Sopenharmony_ci if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth]; 46062306a36Sopenharmony_ci else if(VGAEngine == SIS_315_VGA) { 46162306a36Sopenharmony_ci if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth]; 46262306a36Sopenharmony_ci } 46362306a36Sopenharmony_ci break; 46462306a36Sopenharmony_ci case 2048: 46562306a36Sopenharmony_ci if(VDisplay == 1536) { 46662306a36Sopenharmony_ci if(VGAEngine == SIS_300_VGA) { 46762306a36Sopenharmony_ci ModeIndex = ModeIndex_300_2048x1536[Depth]; 46862306a36Sopenharmony_ci } else { 46962306a36Sopenharmony_ci ModeIndex = ModeIndex_310_2048x1536[Depth]; 47062306a36Sopenharmony_ci } 47162306a36Sopenharmony_ci } 47262306a36Sopenharmony_ci break; 47362306a36Sopenharmony_ci } 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci return ModeIndex; 47662306a36Sopenharmony_ci} 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ciunsigned short 47962306a36Sopenharmony_ciSiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, 48062306a36Sopenharmony_ci int Depth, bool FSTN, unsigned short CustomT, int LCDwidth, int LCDheight, 48162306a36Sopenharmony_ci unsigned int VBFlags2) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci unsigned short ModeIndex = 0; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) { 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci switch(HDisplay) 48862306a36Sopenharmony_ci { 48962306a36Sopenharmony_ci case 320: 49062306a36Sopenharmony_ci if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) { 49162306a36Sopenharmony_ci if(VDisplay == 200) { 49262306a36Sopenharmony_ci if(!FSTN) ModeIndex = ModeIndex_320x200[Depth]; 49362306a36Sopenharmony_ci } else if(VDisplay == 240) { 49462306a36Sopenharmony_ci if(!FSTN) ModeIndex = ModeIndex_320x240[Depth]; 49562306a36Sopenharmony_ci else if(VGAEngine == SIS_315_VGA) { 49662306a36Sopenharmony_ci ModeIndex = ModeIndex_320x240_FSTN[Depth]; 49762306a36Sopenharmony_ci } 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci } 50062306a36Sopenharmony_ci break; 50162306a36Sopenharmony_ci case 400: 50262306a36Sopenharmony_ci if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) { 50362306a36Sopenharmony_ci if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) { 50462306a36Sopenharmony_ci if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 50562306a36Sopenharmony_ci } 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci break; 50862306a36Sopenharmony_ci case 512: 50962306a36Sopenharmony_ci if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) { 51062306a36Sopenharmony_ci if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) { 51162306a36Sopenharmony_ci if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) { 51262306a36Sopenharmony_ci if(VDisplay == 384) { 51362306a36Sopenharmony_ci ModeIndex = ModeIndex_512x384[Depth]; 51462306a36Sopenharmony_ci } 51562306a36Sopenharmony_ci } 51662306a36Sopenharmony_ci } 51762306a36Sopenharmony_ci } 51862306a36Sopenharmony_ci break; 51962306a36Sopenharmony_ci case 640: 52062306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 52162306a36Sopenharmony_ci else if(VDisplay == 400) { 52262306a36Sopenharmony_ci if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) 52362306a36Sopenharmony_ci ModeIndex = ModeIndex_640x400[Depth]; 52462306a36Sopenharmony_ci } 52562306a36Sopenharmony_ci break; 52662306a36Sopenharmony_ci case 800: 52762306a36Sopenharmony_ci if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 52862306a36Sopenharmony_ci break; 52962306a36Sopenharmony_ci case 848: 53062306a36Sopenharmony_ci if(CustomT == CUT_PANEL848) { 53162306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci break; 53462306a36Sopenharmony_ci case 856: 53562306a36Sopenharmony_ci if(CustomT == CUT_PANEL856) { 53662306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci break; 53962306a36Sopenharmony_ci case 1024: 54062306a36Sopenharmony_ci if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 54162306a36Sopenharmony_ci else if(VGAEngine == SIS_300_VGA) { 54262306a36Sopenharmony_ci if((VDisplay == 600) && (LCDheight == 600)) { 54362306a36Sopenharmony_ci ModeIndex = ModeIndex_1024x600[Depth]; 54462306a36Sopenharmony_ci } 54562306a36Sopenharmony_ci } 54662306a36Sopenharmony_ci break; 54762306a36Sopenharmony_ci case 1152: 54862306a36Sopenharmony_ci if(VGAEngine == SIS_300_VGA) { 54962306a36Sopenharmony_ci if((VDisplay == 768) && (LCDheight == 768)) { 55062306a36Sopenharmony_ci ModeIndex = ModeIndex_1152x768[Depth]; 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci } 55362306a36Sopenharmony_ci break; 55462306a36Sopenharmony_ci case 1280: 55562306a36Sopenharmony_ci if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth]; 55662306a36Sopenharmony_ci else if(VGAEngine == SIS_315_VGA) { 55762306a36Sopenharmony_ci if((VDisplay == 768) && (LCDheight == 768)) { 55862306a36Sopenharmony_ci ModeIndex = ModeIndex_310_1280x768[Depth]; 55962306a36Sopenharmony_ci } 56062306a36Sopenharmony_ci } 56162306a36Sopenharmony_ci break; 56262306a36Sopenharmony_ci case 1360: 56362306a36Sopenharmony_ci if(VGAEngine == SIS_300_VGA) { 56462306a36Sopenharmony_ci if(CustomT == CUT_BARCO1366) { 56562306a36Sopenharmony_ci if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth]; 56662306a36Sopenharmony_ci } 56762306a36Sopenharmony_ci } 56862306a36Sopenharmony_ci if(CustomT == CUT_PANEL848) { 56962306a36Sopenharmony_ci if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 57062306a36Sopenharmony_ci } 57162306a36Sopenharmony_ci break; 57262306a36Sopenharmony_ci case 1400: 57362306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 57462306a36Sopenharmony_ci if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth]; 57562306a36Sopenharmony_ci } 57662306a36Sopenharmony_ci break; 57762306a36Sopenharmony_ci case 1600: 57862306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 57962306a36Sopenharmony_ci if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 58062306a36Sopenharmony_ci } 58162306a36Sopenharmony_ci break; 58262306a36Sopenharmony_ci } 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci } else if(VBFlags2 & VB2_SISBRIDGE) { 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci switch(HDisplay) 58762306a36Sopenharmony_ci { 58862306a36Sopenharmony_ci case 320: 58962306a36Sopenharmony_ci if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 59062306a36Sopenharmony_ci else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth]; 59162306a36Sopenharmony_ci break; 59262306a36Sopenharmony_ci case 400: 59362306a36Sopenharmony_ci if(LCDwidth >= 800 && LCDheight >= 600) { 59462306a36Sopenharmony_ci if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 59562306a36Sopenharmony_ci } 59662306a36Sopenharmony_ci break; 59762306a36Sopenharmony_ci case 512: 59862306a36Sopenharmony_ci if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) { 59962306a36Sopenharmony_ci if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 60062306a36Sopenharmony_ci } 60162306a36Sopenharmony_ci break; 60262306a36Sopenharmony_ci case 640: 60362306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 60462306a36Sopenharmony_ci else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 60562306a36Sopenharmony_ci break; 60662306a36Sopenharmony_ci case 720: 60762306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 60862306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth]; 60962306a36Sopenharmony_ci else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth]; 61062306a36Sopenharmony_ci } 61162306a36Sopenharmony_ci break; 61262306a36Sopenharmony_ci case 768: 61362306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 61462306a36Sopenharmony_ci if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 61562306a36Sopenharmony_ci } 61662306a36Sopenharmony_ci break; 61762306a36Sopenharmony_ci case 800: 61862306a36Sopenharmony_ci if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 61962306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 62062306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; 62162306a36Sopenharmony_ci } 62262306a36Sopenharmony_ci break; 62362306a36Sopenharmony_ci case 848: 62462306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 62562306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci break; 62862306a36Sopenharmony_ci case 856: 62962306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 63062306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; 63162306a36Sopenharmony_ci } 63262306a36Sopenharmony_ci break; 63362306a36Sopenharmony_ci case 960: 63462306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 63562306a36Sopenharmony_ci if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth]; 63662306a36Sopenharmony_ci else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth]; 63762306a36Sopenharmony_ci } 63862306a36Sopenharmony_ci break; 63962306a36Sopenharmony_ci case 1024: 64062306a36Sopenharmony_ci if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 64162306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 64262306a36Sopenharmony_ci if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth]; 64362306a36Sopenharmony_ci } 64462306a36Sopenharmony_ci break; 64562306a36Sopenharmony_ci case 1152: 64662306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 64762306a36Sopenharmony_ci if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth]; 64862306a36Sopenharmony_ci } 64962306a36Sopenharmony_ci break; 65062306a36Sopenharmony_ci case 1280: 65162306a36Sopenharmony_ci switch(VDisplay) { 65262306a36Sopenharmony_ci case 720: 65362306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x720[Depth]; 65462306a36Sopenharmony_ci break; 65562306a36Sopenharmony_ci case 768: 65662306a36Sopenharmony_ci if(VGAEngine == SIS_300_VGA) { 65762306a36Sopenharmony_ci ModeIndex = ModeIndex_300_1280x768[Depth]; 65862306a36Sopenharmony_ci } else { 65962306a36Sopenharmony_ci ModeIndex = ModeIndex_310_1280x768[Depth]; 66062306a36Sopenharmony_ci } 66162306a36Sopenharmony_ci break; 66262306a36Sopenharmony_ci case 800: 66362306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 66462306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x800[Depth]; 66562306a36Sopenharmony_ci } 66662306a36Sopenharmony_ci break; 66762306a36Sopenharmony_ci case 854: 66862306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 66962306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x854[Depth]; 67062306a36Sopenharmony_ci } 67162306a36Sopenharmony_ci break; 67262306a36Sopenharmony_ci case 960: 67362306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x960[Depth]; 67462306a36Sopenharmony_ci break; 67562306a36Sopenharmony_ci case 1024: 67662306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x1024[Depth]; 67762306a36Sopenharmony_ci break; 67862306a36Sopenharmony_ci } 67962306a36Sopenharmony_ci break; 68062306a36Sopenharmony_ci case 1360: 68162306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { /* OVER1280 only? */ 68262306a36Sopenharmony_ci if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth]; 68362306a36Sopenharmony_ci } 68462306a36Sopenharmony_ci break; 68562306a36Sopenharmony_ci case 1400: 68662306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 68762306a36Sopenharmony_ci if(VBFlags2 & VB2_LCDOVER1280BRIDGE) { 68862306a36Sopenharmony_ci if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth]; 68962306a36Sopenharmony_ci } 69062306a36Sopenharmony_ci } 69162306a36Sopenharmony_ci break; 69262306a36Sopenharmony_ci case 1600: 69362306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 69462306a36Sopenharmony_ci if(VBFlags2 & VB2_LCDOVER1280BRIDGE) { 69562306a36Sopenharmony_ci if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth]; 69662306a36Sopenharmony_ci } 69762306a36Sopenharmony_ci } 69862306a36Sopenharmony_ci break; 69962306a36Sopenharmony_ci#ifndef VB_FORBID_CRT2LCD_OVER_1600 70062306a36Sopenharmony_ci case 1680: 70162306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 70262306a36Sopenharmony_ci if(VBFlags2 & VB2_LCDOVER1280BRIDGE) { 70362306a36Sopenharmony_ci if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth]; 70462306a36Sopenharmony_ci } 70562306a36Sopenharmony_ci } 70662306a36Sopenharmony_ci break; 70762306a36Sopenharmony_ci case 1920: 70862306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 70962306a36Sopenharmony_ci if(VBFlags2 & VB2_LCDOVER1600BRIDGE) { 71062306a36Sopenharmony_ci if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth]; 71162306a36Sopenharmony_ci } 71262306a36Sopenharmony_ci } 71362306a36Sopenharmony_ci break; 71462306a36Sopenharmony_ci case 2048: 71562306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 71662306a36Sopenharmony_ci if(VBFlags2 & VB2_LCDOVER1600BRIDGE) { 71762306a36Sopenharmony_ci if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth]; 71862306a36Sopenharmony_ci } 71962306a36Sopenharmony_ci } 72062306a36Sopenharmony_ci break; 72162306a36Sopenharmony_ci#endif 72262306a36Sopenharmony_ci } 72362306a36Sopenharmony_ci } 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci return ModeIndex; 72662306a36Sopenharmony_ci} 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ciunsigned short 72962306a36Sopenharmony_ciSiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth, 73062306a36Sopenharmony_ci unsigned int VBFlags2) 73162306a36Sopenharmony_ci{ 73262306a36Sopenharmony_ci unsigned short ModeIndex = 0; 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci if(VBFlags2 & VB2_CHRONTEL) { 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci switch(HDisplay) 73762306a36Sopenharmony_ci { 73862306a36Sopenharmony_ci case 512: 73962306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 74062306a36Sopenharmony_ci if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 74162306a36Sopenharmony_ci } 74262306a36Sopenharmony_ci break; 74362306a36Sopenharmony_ci case 640: 74462306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 74562306a36Sopenharmony_ci else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 74662306a36Sopenharmony_ci break; 74762306a36Sopenharmony_ci case 800: 74862306a36Sopenharmony_ci if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 74962306a36Sopenharmony_ci break; 75062306a36Sopenharmony_ci case 1024: 75162306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 75262306a36Sopenharmony_ci if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; 75362306a36Sopenharmony_ci } 75462306a36Sopenharmony_ci break; 75562306a36Sopenharmony_ci } 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci } else if(VBFlags2 & VB2_SISTVBRIDGE) { 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci switch(HDisplay) 76062306a36Sopenharmony_ci { 76162306a36Sopenharmony_ci case 320: 76262306a36Sopenharmony_ci if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; 76362306a36Sopenharmony_ci else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth]; 76462306a36Sopenharmony_ci break; 76562306a36Sopenharmony_ci case 400: 76662306a36Sopenharmony_ci if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; 76762306a36Sopenharmony_ci break; 76862306a36Sopenharmony_ci case 512: 76962306a36Sopenharmony_ci if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) || 77062306a36Sopenharmony_ci (VBFlags & TV_HIVISION) || 77162306a36Sopenharmony_ci ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) { 77262306a36Sopenharmony_ci if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; 77362306a36Sopenharmony_ci } 77462306a36Sopenharmony_ci break; 77562306a36Sopenharmony_ci case 640: 77662306a36Sopenharmony_ci if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; 77762306a36Sopenharmony_ci else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; 77862306a36Sopenharmony_ci break; 77962306a36Sopenharmony_ci case 720: 78062306a36Sopenharmony_ci if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) { 78162306a36Sopenharmony_ci if(VDisplay == 480) { 78262306a36Sopenharmony_ci ModeIndex = ModeIndex_720x480[Depth]; 78362306a36Sopenharmony_ci } else if(VDisplay == 576) { 78462306a36Sopenharmony_ci if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) || 78562306a36Sopenharmony_ci ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) 78662306a36Sopenharmony_ci ModeIndex = ModeIndex_720x576[Depth]; 78762306a36Sopenharmony_ci } 78862306a36Sopenharmony_ci } 78962306a36Sopenharmony_ci break; 79062306a36Sopenharmony_ci case 768: 79162306a36Sopenharmony_ci if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) { 79262306a36Sopenharmony_ci if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) || 79362306a36Sopenharmony_ci ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) { 79462306a36Sopenharmony_ci if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; 79562306a36Sopenharmony_ci } 79662306a36Sopenharmony_ci } 79762306a36Sopenharmony_ci break; 79862306a36Sopenharmony_ci case 800: 79962306a36Sopenharmony_ci if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; 80062306a36Sopenharmony_ci else if(VDisplay == 480) { 80162306a36Sopenharmony_ci if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) { 80262306a36Sopenharmony_ci ModeIndex = ModeIndex_800x480[Depth]; 80362306a36Sopenharmony_ci } 80462306a36Sopenharmony_ci } 80562306a36Sopenharmony_ci break; 80662306a36Sopenharmony_ci case 960: 80762306a36Sopenharmony_ci if(VGAEngine == SIS_315_VGA) { 80862306a36Sopenharmony_ci if(VDisplay == 600) { 80962306a36Sopenharmony_ci if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 81062306a36Sopenharmony_ci ModeIndex = ModeIndex_960x600[Depth]; 81162306a36Sopenharmony_ci } 81262306a36Sopenharmony_ci } 81362306a36Sopenharmony_ci } 81462306a36Sopenharmony_ci break; 81562306a36Sopenharmony_ci case 1024: 81662306a36Sopenharmony_ci if(VDisplay == 768) { 81762306a36Sopenharmony_ci if(VBFlags2 & VB2_30xBLV) { 81862306a36Sopenharmony_ci ModeIndex = ModeIndex_1024x768[Depth]; 81962306a36Sopenharmony_ci } 82062306a36Sopenharmony_ci } else if(VDisplay == 576) { 82162306a36Sopenharmony_ci if( (VBFlags & TV_HIVISION) || 82262306a36Sopenharmony_ci ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) || 82362306a36Sopenharmony_ci ((VBFlags2 & VB2_30xBLV) && 82462306a36Sopenharmony_ci ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) { 82562306a36Sopenharmony_ci ModeIndex = ModeIndex_1024x576[Depth]; 82662306a36Sopenharmony_ci } 82762306a36Sopenharmony_ci } 82862306a36Sopenharmony_ci break; 82962306a36Sopenharmony_ci case 1280: 83062306a36Sopenharmony_ci if(VDisplay == 720) { 83162306a36Sopenharmony_ci if((VBFlags & TV_HIVISION) || 83262306a36Sopenharmony_ci ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) { 83362306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x720[Depth]; 83462306a36Sopenharmony_ci } 83562306a36Sopenharmony_ci } else if(VDisplay == 1024) { 83662306a36Sopenharmony_ci if((VBFlags & TV_HIVISION) || 83762306a36Sopenharmony_ci ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) { 83862306a36Sopenharmony_ci ModeIndex = ModeIndex_1280x1024[Depth]; 83962306a36Sopenharmony_ci } 84062306a36Sopenharmony_ci } 84162306a36Sopenharmony_ci break; 84262306a36Sopenharmony_ci } 84362306a36Sopenharmony_ci } 84462306a36Sopenharmony_ci return ModeIndex; 84562306a36Sopenharmony_ci} 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ciunsigned short 84862306a36Sopenharmony_ciSiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth, 84962306a36Sopenharmony_ci unsigned int VBFlags2) 85062306a36Sopenharmony_ci{ 85162306a36Sopenharmony_ci if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0; 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci if(HDisplay >= 1920) return 0; 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci switch(HDisplay) 85662306a36Sopenharmony_ci { 85762306a36Sopenharmony_ci case 1600: 85862306a36Sopenharmony_ci if(VDisplay == 1200) { 85962306a36Sopenharmony_ci if(VGAEngine != SIS_315_VGA) return 0; 86062306a36Sopenharmony_ci if(!(VBFlags2 & VB2_30xB)) return 0; 86162306a36Sopenharmony_ci } 86262306a36Sopenharmony_ci break; 86362306a36Sopenharmony_ci case 1680: 86462306a36Sopenharmony_ci if(VDisplay == 1050) { 86562306a36Sopenharmony_ci if(VGAEngine != SIS_315_VGA) return 0; 86662306a36Sopenharmony_ci if(!(VBFlags2 & VB2_30xB)) return 0; 86762306a36Sopenharmony_ci } 86862306a36Sopenharmony_ci break; 86962306a36Sopenharmony_ci } 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, false, 0, 0); 87262306a36Sopenharmony_ci} 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci/*********************************************/ 87662306a36Sopenharmony_ci/* HELPER: SetReg, GetReg */ 87762306a36Sopenharmony_ci/*********************************************/ 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_civoid 88062306a36Sopenharmony_ciSiS_SetReg(SISIOADDRESS port, u8 index, u8 data) 88162306a36Sopenharmony_ci{ 88262306a36Sopenharmony_ci outb(index, port); 88362306a36Sopenharmony_ci outb(data, port + 1); 88462306a36Sopenharmony_ci} 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_civoid 88762306a36Sopenharmony_ciSiS_SetRegByte(SISIOADDRESS port, u8 data) 88862306a36Sopenharmony_ci{ 88962306a36Sopenharmony_ci outb(data, port); 89062306a36Sopenharmony_ci} 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_civoid 89362306a36Sopenharmony_ciSiS_SetRegShort(SISIOADDRESS port, u16 data) 89462306a36Sopenharmony_ci{ 89562306a36Sopenharmony_ci outw(data, port); 89662306a36Sopenharmony_ci} 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_civoid 89962306a36Sopenharmony_ciSiS_SetRegLong(SISIOADDRESS port, u32 data) 90062306a36Sopenharmony_ci{ 90162306a36Sopenharmony_ci outl(data, port); 90262306a36Sopenharmony_ci} 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ciu8 90562306a36Sopenharmony_ciSiS_GetReg(SISIOADDRESS port, u8 index) 90662306a36Sopenharmony_ci{ 90762306a36Sopenharmony_ci outb(index, port); 90862306a36Sopenharmony_ci return inb(port + 1); 90962306a36Sopenharmony_ci} 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ciu8 91262306a36Sopenharmony_ciSiS_GetRegByte(SISIOADDRESS port) 91362306a36Sopenharmony_ci{ 91462306a36Sopenharmony_ci return inb(port); 91562306a36Sopenharmony_ci} 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ciu16 91862306a36Sopenharmony_ciSiS_GetRegShort(SISIOADDRESS port) 91962306a36Sopenharmony_ci{ 92062306a36Sopenharmony_ci return inw(port); 92162306a36Sopenharmony_ci} 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ciu32 92462306a36Sopenharmony_ciSiS_GetRegLong(SISIOADDRESS port) 92562306a36Sopenharmony_ci{ 92662306a36Sopenharmony_ci return inl(port); 92762306a36Sopenharmony_ci} 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_civoid 93062306a36Sopenharmony_ciSiS_SetRegANDOR(SISIOADDRESS Port, u8 Index, u8 DataAND, u8 DataOR) 93162306a36Sopenharmony_ci{ 93262306a36Sopenharmony_ci u8 temp; 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_ci temp = SiS_GetReg(Port, Index); 93562306a36Sopenharmony_ci temp = (temp & (DataAND)) | DataOR; 93662306a36Sopenharmony_ci SiS_SetReg(Port, Index, temp); 93762306a36Sopenharmony_ci} 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_civoid 94062306a36Sopenharmony_ciSiS_SetRegAND(SISIOADDRESS Port, u8 Index, u8 DataAND) 94162306a36Sopenharmony_ci{ 94262306a36Sopenharmony_ci u8 temp; 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci temp = SiS_GetReg(Port, Index); 94562306a36Sopenharmony_ci temp &= DataAND; 94662306a36Sopenharmony_ci SiS_SetReg(Port, Index, temp); 94762306a36Sopenharmony_ci} 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_civoid 95062306a36Sopenharmony_ciSiS_SetRegOR(SISIOADDRESS Port, u8 Index, u8 DataOR) 95162306a36Sopenharmony_ci{ 95262306a36Sopenharmony_ci u8 temp; 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci temp = SiS_GetReg(Port, Index); 95562306a36Sopenharmony_ci temp |= DataOR; 95662306a36Sopenharmony_ci SiS_SetReg(Port, Index, temp); 95762306a36Sopenharmony_ci} 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci/*********************************************/ 96062306a36Sopenharmony_ci/* HELPER: DisplayOn, DisplayOff */ 96162306a36Sopenharmony_ci/*********************************************/ 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_civoid 96462306a36Sopenharmony_ciSiS_DisplayOn(struct SiS_Private *SiS_Pr) 96562306a36Sopenharmony_ci{ 96662306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF); 96762306a36Sopenharmony_ci} 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_civoid 97062306a36Sopenharmony_ciSiS_DisplayOff(struct SiS_Private *SiS_Pr) 97162306a36Sopenharmony_ci{ 97262306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20); 97362306a36Sopenharmony_ci} 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci/*********************************************/ 97762306a36Sopenharmony_ci/* HELPER: Init Port Addresses */ 97862306a36Sopenharmony_ci/*********************************************/ 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_civoid 98162306a36Sopenharmony_ciSiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr) 98262306a36Sopenharmony_ci{ 98362306a36Sopenharmony_ci SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; 98462306a36Sopenharmony_ci SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; 98562306a36Sopenharmony_ci SiS_Pr->SiS_P3c0 = BaseAddr + 0x10; 98662306a36Sopenharmony_ci SiS_Pr->SiS_P3ce = BaseAddr + 0x1e; 98762306a36Sopenharmony_ci SiS_Pr->SiS_P3c2 = BaseAddr + 0x12; 98862306a36Sopenharmony_ci SiS_Pr->SiS_P3ca = BaseAddr + 0x1a; 98962306a36Sopenharmony_ci SiS_Pr->SiS_P3c6 = BaseAddr + 0x16; 99062306a36Sopenharmony_ci SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; 99162306a36Sopenharmony_ci SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; 99262306a36Sopenharmony_ci SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; 99362306a36Sopenharmony_ci SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; 99462306a36Sopenharmony_ci SiS_Pr->SiS_P3cc = BaseAddr + 0x1c; 99562306a36Sopenharmony_ci SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; 99662306a36Sopenharmony_ci SiS_Pr->SiS_P3da = BaseAddr + 0x2a; 99762306a36Sopenharmony_ci SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04; 99862306a36Sopenharmony_ci SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10; 99962306a36Sopenharmony_ci SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12; 100062306a36Sopenharmony_ci SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14; 100162306a36Sopenharmony_ci SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; 100262306a36Sopenharmony_ci SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14; 100362306a36Sopenharmony_ci SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE; 100462306a36Sopenharmony_ci SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK; 100562306a36Sopenharmony_ci} 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_ci/*********************************************/ 100862306a36Sopenharmony_ci/* HELPER: GetSysFlags */ 100962306a36Sopenharmony_ci/*********************************************/ 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_cistatic void 101262306a36Sopenharmony_ciSiS_GetSysFlags(struct SiS_Private *SiS_Pr) 101362306a36Sopenharmony_ci{ 101462306a36Sopenharmony_ci unsigned char cr5f, temp1, temp2; 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci /* 661 and newer: NEVER write non-zero to SR11[7:4] */ 101762306a36Sopenharmony_ci /* (SR11 is used for DDC and in enable/disablebridge) */ 101862306a36Sopenharmony_ci SiS_Pr->SiS_SensibleSR11 = false; 101962306a36Sopenharmony_ci SiS_Pr->SiS_MyCR63 = 0x63; 102062306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_330) { 102162306a36Sopenharmony_ci SiS_Pr->SiS_MyCR63 = 0x53; 102262306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_661) { 102362306a36Sopenharmony_ci SiS_Pr->SiS_SensibleSR11 = true; 102462306a36Sopenharmony_ci } 102562306a36Sopenharmony_ci } 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci /* You should use the macros, not these flags directly */ 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_ci SiS_Pr->SiS_SysFlags = 0; 103062306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_650) { 103162306a36Sopenharmony_ci cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0; 103262306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07); 103362306a36Sopenharmony_ci temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 103462306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8); 103562306a36Sopenharmony_ci temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 103662306a36Sopenharmony_ci if((!temp1) || (temp2)) { 103762306a36Sopenharmony_ci switch(cr5f) { 103862306a36Sopenharmony_ci case 0x80: 103962306a36Sopenharmony_ci case 0x90: 104062306a36Sopenharmony_ci case 0xc0: 104162306a36Sopenharmony_ci SiS_Pr->SiS_SysFlags |= SF_IsM650; 104262306a36Sopenharmony_ci break; 104362306a36Sopenharmony_ci case 0xa0: 104462306a36Sopenharmony_ci case 0xb0: 104562306a36Sopenharmony_ci case 0xe0: 104662306a36Sopenharmony_ci SiS_Pr->SiS_SysFlags |= SF_Is651; 104762306a36Sopenharmony_ci break; 104862306a36Sopenharmony_ci } 104962306a36Sopenharmony_ci } else { 105062306a36Sopenharmony_ci switch(cr5f) { 105162306a36Sopenharmony_ci case 0x90: 105262306a36Sopenharmony_ci temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8; 105362306a36Sopenharmony_ci switch(temp1) { 105462306a36Sopenharmony_ci case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break; 105562306a36Sopenharmony_ci case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break; 105662306a36Sopenharmony_ci default: SiS_Pr->SiS_SysFlags |= SF_IsM650; break; 105762306a36Sopenharmony_ci } 105862306a36Sopenharmony_ci break; 105962306a36Sopenharmony_ci case 0xb0: 106062306a36Sopenharmony_ci SiS_Pr->SiS_SysFlags |= SF_Is652; 106162306a36Sopenharmony_ci break; 106262306a36Sopenharmony_ci default: 106362306a36Sopenharmony_ci SiS_Pr->SiS_SysFlags |= SF_IsM650; 106462306a36Sopenharmony_ci break; 106562306a36Sopenharmony_ci } 106662306a36Sopenharmony_ci } 106762306a36Sopenharmony_ci } 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) { 107062306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) { 107162306a36Sopenharmony_ci SiS_Pr->SiS_SysFlags |= SF_760LFB; 107262306a36Sopenharmony_ci } 107362306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) { 107462306a36Sopenharmony_ci SiS_Pr->SiS_SysFlags |= SF_760UMA; 107562306a36Sopenharmony_ci } 107662306a36Sopenharmony_ci } 107762306a36Sopenharmony_ci} 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci/*********************************************/ 108062306a36Sopenharmony_ci/* HELPER: Init PCI & Engines */ 108162306a36Sopenharmony_ci/*********************************************/ 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_cistatic void 108462306a36Sopenharmony_ciSiSInitPCIetc(struct SiS_Private *SiS_Pr) 108562306a36Sopenharmony_ci{ 108662306a36Sopenharmony_ci switch(SiS_Pr->ChipType) { 108762306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 108862306a36Sopenharmony_ci case SIS_300: 108962306a36Sopenharmony_ci case SIS_540: 109062306a36Sopenharmony_ci case SIS_630: 109162306a36Sopenharmony_ci case SIS_730: 109262306a36Sopenharmony_ci /* Set - PCI LINEAR ADDRESSING ENABLE (0x80) 109362306a36Sopenharmony_ci * - RELOCATED VGA IO ENABLED (0x20) 109462306a36Sopenharmony_ci * - MMIO ENABLED (0x01) 109562306a36Sopenharmony_ci * Leave other bits untouched. 109662306a36Sopenharmony_ci */ 109762306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1); 109862306a36Sopenharmony_ci /* - Enable 2D (0x40) 109962306a36Sopenharmony_ci * - Enable 3D (0x02) 110062306a36Sopenharmony_ci * - Enable 3D Vertex command fetch (0x10) ? 110162306a36Sopenharmony_ci * - Enable 3D command parser (0x08) ? 110262306a36Sopenharmony_ci */ 110362306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A); 110462306a36Sopenharmony_ci break; 110562306a36Sopenharmony_ci#endif 110662306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 110762306a36Sopenharmony_ci case SIS_315H: 110862306a36Sopenharmony_ci case SIS_315: 110962306a36Sopenharmony_ci case SIS_315PRO: 111062306a36Sopenharmony_ci case SIS_650: 111162306a36Sopenharmony_ci case SIS_740: 111262306a36Sopenharmony_ci case SIS_330: 111362306a36Sopenharmony_ci case SIS_661: 111462306a36Sopenharmony_ci case SIS_741: 111562306a36Sopenharmony_ci case SIS_660: 111662306a36Sopenharmony_ci case SIS_760: 111762306a36Sopenharmony_ci case SIS_761: 111862306a36Sopenharmony_ci case SIS_340: 111962306a36Sopenharmony_ci case XGI_40: 112062306a36Sopenharmony_ci /* See above */ 112162306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1); 112262306a36Sopenharmony_ci /* - Enable 3D G/L transformation engine (0x80) 112362306a36Sopenharmony_ci * - Enable 2D (0x40) 112462306a36Sopenharmony_ci * - Enable 3D vertex command fetch (0x10) 112562306a36Sopenharmony_ci * - Enable 3D command parser (0x08) 112662306a36Sopenharmony_ci * - Enable 3D (0x02) 112762306a36Sopenharmony_ci */ 112862306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA); 112962306a36Sopenharmony_ci break; 113062306a36Sopenharmony_ci case XGI_20: 113162306a36Sopenharmony_ci case SIS_550: 113262306a36Sopenharmony_ci /* See above */ 113362306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1); 113462306a36Sopenharmony_ci /* No 3D engine ! */ 113562306a36Sopenharmony_ci /* - Enable 2D (0x40) 113662306a36Sopenharmony_ci * - disable 3D 113762306a36Sopenharmony_ci */ 113862306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40); 113962306a36Sopenharmony_ci break; 114062306a36Sopenharmony_ci#endif 114162306a36Sopenharmony_ci default: 114262306a36Sopenharmony_ci break; 114362306a36Sopenharmony_ci } 114462306a36Sopenharmony_ci} 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci/*********************************************/ 114762306a36Sopenharmony_ci/* HELPER: SetLVDSetc */ 114862306a36Sopenharmony_ci/*********************************************/ 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_cistatic 115162306a36Sopenharmony_civoid 115262306a36Sopenharmony_ciSiSSetLVDSetc(struct SiS_Private *SiS_Pr) 115362306a36Sopenharmony_ci{ 115462306a36Sopenharmony_ci unsigned short temp; 115562306a36Sopenharmony_ci 115662306a36Sopenharmony_ci SiS_Pr->SiS_IF_DEF_LVDS = 0; 115762306a36Sopenharmony_ci SiS_Pr->SiS_IF_DEF_TRUMPION = 0; 115862306a36Sopenharmony_ci SiS_Pr->SiS_IF_DEF_CH70xx = 0; 115962306a36Sopenharmony_ci SiS_Pr->SiS_IF_DEF_CONEX = 0; 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_ci SiS_Pr->SiS_ChrontelInit = 0; 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_20) return; 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci /* Check for SiS30x first */ 116662306a36Sopenharmony_ci temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 116762306a36Sopenharmony_ci if((temp == 1) || (temp == 2)) return; 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci switch(SiS_Pr->ChipType) { 117062306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 117162306a36Sopenharmony_ci case SIS_540: 117262306a36Sopenharmony_ci case SIS_630: 117362306a36Sopenharmony_ci case SIS_730: 117462306a36Sopenharmony_ci temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1; 117562306a36Sopenharmony_ci if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 117662306a36Sopenharmony_ci if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1; 117762306a36Sopenharmony_ci if((temp == 4) || (temp == 5)) { 117862306a36Sopenharmony_ci /* Save power status (and error check) - UNUSED */ 117962306a36Sopenharmony_ci SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e); 118062306a36Sopenharmony_ci SiS_Pr->SiS_IF_DEF_CH70xx = 1; 118162306a36Sopenharmony_ci } 118262306a36Sopenharmony_ci break; 118362306a36Sopenharmony_ci#endif 118462306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 118562306a36Sopenharmony_ci case SIS_550: 118662306a36Sopenharmony_ci case SIS_650: 118762306a36Sopenharmony_ci case SIS_740: 118862306a36Sopenharmony_ci case SIS_330: 118962306a36Sopenharmony_ci temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1; 119062306a36Sopenharmony_ci if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 119162306a36Sopenharmony_ci if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2; 119262306a36Sopenharmony_ci break; 119362306a36Sopenharmony_ci case SIS_661: 119462306a36Sopenharmony_ci case SIS_741: 119562306a36Sopenharmony_ci case SIS_660: 119662306a36Sopenharmony_ci case SIS_760: 119762306a36Sopenharmony_ci case SIS_761: 119862306a36Sopenharmony_ci case SIS_340: 119962306a36Sopenharmony_ci case XGI_20: 120062306a36Sopenharmony_ci case XGI_40: 120162306a36Sopenharmony_ci temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5; 120262306a36Sopenharmony_ci if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1; 120362306a36Sopenharmony_ci if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2; 120462306a36Sopenharmony_ci if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */ 120562306a36Sopenharmony_ci break; 120662306a36Sopenharmony_ci#endif 120762306a36Sopenharmony_ci default: 120862306a36Sopenharmony_ci break; 120962306a36Sopenharmony_ci } 121062306a36Sopenharmony_ci} 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci/*********************************************/ 121362306a36Sopenharmony_ci/* HELPER: Enable DSTN/FSTN */ 121462306a36Sopenharmony_ci/*********************************************/ 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_civoid 121762306a36Sopenharmony_ciSiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable) 121862306a36Sopenharmony_ci{ 121962306a36Sopenharmony_ci SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0; 122062306a36Sopenharmony_ci} 122162306a36Sopenharmony_ci 122262306a36Sopenharmony_civoid 122362306a36Sopenharmony_ciSiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable) 122462306a36Sopenharmony_ci{ 122562306a36Sopenharmony_ci SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0; 122662306a36Sopenharmony_ci} 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci/*********************************************/ 122962306a36Sopenharmony_ci/* HELPER: Get modeflag */ 123062306a36Sopenharmony_ci/*********************************************/ 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_ciunsigned short 123362306a36Sopenharmony_ciSiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 123462306a36Sopenharmony_ci unsigned short ModeIdIndex) 123562306a36Sopenharmony_ci{ 123662306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 123762306a36Sopenharmony_ci return SiS_Pr->CModeFlag; 123862306a36Sopenharmony_ci } else if(ModeNo <= 0x13) { 123962306a36Sopenharmony_ci return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 124062306a36Sopenharmony_ci } else { 124162306a36Sopenharmony_ci return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 124262306a36Sopenharmony_ci } 124362306a36Sopenharmony_ci} 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci/*********************************************/ 124662306a36Sopenharmony_ci/* HELPER: Determine ROM usage */ 124762306a36Sopenharmony_ci/*********************************************/ 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_cibool 125062306a36Sopenharmony_ciSiSDetermineROMLayout661(struct SiS_Private *SiS_Pr) 125162306a36Sopenharmony_ci{ 125262306a36Sopenharmony_ci unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 125362306a36Sopenharmony_ci unsigned short romversoffs, romvmaj = 1, romvmin = 0; 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_ci if(SiS_Pr->ChipType >= XGI_20) { 125662306a36Sopenharmony_ci /* XGI ROMs don't qualify */ 125762306a36Sopenharmony_ci return false; 125862306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_761) { 125962306a36Sopenharmony_ci /* I very much assume 761, 340 and newer will use new layout */ 126062306a36Sopenharmony_ci return true; 126162306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_661) { 126262306a36Sopenharmony_ci if((ROMAddr[0x1a] == 'N') && 126362306a36Sopenharmony_ci (ROMAddr[0x1b] == 'e') && 126462306a36Sopenharmony_ci (ROMAddr[0x1c] == 'w') && 126562306a36Sopenharmony_ci (ROMAddr[0x1d] == 'V')) { 126662306a36Sopenharmony_ci return true; 126762306a36Sopenharmony_ci } 126862306a36Sopenharmony_ci romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8); 126962306a36Sopenharmony_ci if(romversoffs) { 127062306a36Sopenharmony_ci if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) { 127162306a36Sopenharmony_ci romvmaj = ROMAddr[romversoffs] - '0'; 127262306a36Sopenharmony_ci romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0'); 127362306a36Sopenharmony_ci } 127462306a36Sopenharmony_ci } 127562306a36Sopenharmony_ci if((romvmaj != 0) || (romvmin >= 92)) { 127662306a36Sopenharmony_ci return true; 127762306a36Sopenharmony_ci } 127862306a36Sopenharmony_ci } else if(IS_SIS650740) { 127962306a36Sopenharmony_ci if((ROMAddr[0x1a] == 'N') && 128062306a36Sopenharmony_ci (ROMAddr[0x1b] == 'e') && 128162306a36Sopenharmony_ci (ROMAddr[0x1c] == 'w') && 128262306a36Sopenharmony_ci (ROMAddr[0x1d] == 'V')) { 128362306a36Sopenharmony_ci return true; 128462306a36Sopenharmony_ci } 128562306a36Sopenharmony_ci } 128662306a36Sopenharmony_ci return false; 128762306a36Sopenharmony_ci} 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_cistatic void 129062306a36Sopenharmony_ciSiSDetermineROMUsage(struct SiS_Private *SiS_Pr) 129162306a36Sopenharmony_ci{ 129262306a36Sopenharmony_ci unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 129362306a36Sopenharmony_ci unsigned short romptr = 0; 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci SiS_Pr->SiS_UseROM = false; 129662306a36Sopenharmony_ci SiS_Pr->SiS_ROMNew = false; 129762306a36Sopenharmony_ci SiS_Pr->SiS_PWDOffset = 0; 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ci if(SiS_Pr->ChipType >= XGI_20) return; 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_ci if((ROMAddr) && (SiS_Pr->UseROM)) { 130262306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_300) { 130362306a36Sopenharmony_ci /* 300: We check if the code starts below 0x220 by 130462306a36Sopenharmony_ci * checking the jmp instruction at the beginning 130562306a36Sopenharmony_ci * of the BIOS image. 130662306a36Sopenharmony_ci */ 130762306a36Sopenharmony_ci if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a) 130862306a36Sopenharmony_ci SiS_Pr->SiS_UseROM = true; 130962306a36Sopenharmony_ci } else if(SiS_Pr->ChipType < SIS_315H) { 131062306a36Sopenharmony_ci /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps 131162306a36Sopenharmony_ci * the others do as well 131262306a36Sopenharmony_ci */ 131362306a36Sopenharmony_ci SiS_Pr->SiS_UseROM = true; 131462306a36Sopenharmony_ci } else { 131562306a36Sopenharmony_ci /* 315/330 series stick to the standard(s) */ 131662306a36Sopenharmony_ci SiS_Pr->SiS_UseROM = true; 131762306a36Sopenharmony_ci if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) { 131862306a36Sopenharmony_ci SiS_Pr->SiS_EMIOffset = 14; 131962306a36Sopenharmony_ci SiS_Pr->SiS_PWDOffset = 17; 132062306a36Sopenharmony_ci SiS_Pr->SiS661LCD2TableSize = 36; 132162306a36Sopenharmony_ci /* Find out about LCD data table entry size */ 132262306a36Sopenharmony_ci if((romptr = SISGETROMW(0x0102))) { 132362306a36Sopenharmony_ci if(ROMAddr[romptr + (32 * 16)] == 0xff) 132462306a36Sopenharmony_ci SiS_Pr->SiS661LCD2TableSize = 32; 132562306a36Sopenharmony_ci else if(ROMAddr[romptr + (34 * 16)] == 0xff) 132662306a36Sopenharmony_ci SiS_Pr->SiS661LCD2TableSize = 34; 132762306a36Sopenharmony_ci else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94, 2.05.00+ */ 132862306a36Sopenharmony_ci SiS_Pr->SiS661LCD2TableSize = 36; 132962306a36Sopenharmony_ci else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */ 133062306a36Sopenharmony_ci (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00 - <2.05.00 */ 133162306a36Sopenharmony_ci SiS_Pr->SiS661LCD2TableSize = 38; /* UMC data layout abandoned at 2.05.00 */ 133262306a36Sopenharmony_ci SiS_Pr->SiS_EMIOffset = 16; 133362306a36Sopenharmony_ci SiS_Pr->SiS_PWDOffset = 19; 133462306a36Sopenharmony_ci } 133562306a36Sopenharmony_ci } 133662306a36Sopenharmony_ci } 133762306a36Sopenharmony_ci } 133862306a36Sopenharmony_ci } 133962306a36Sopenharmony_ci} 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci/*********************************************/ 134262306a36Sopenharmony_ci/* HELPER: SET SEGMENT REGISTERS */ 134362306a36Sopenharmony_ci/*********************************************/ 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_cistatic void 134662306a36Sopenharmony_ciSiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) 134762306a36Sopenharmony_ci{ 134862306a36Sopenharmony_ci unsigned short temp; 134962306a36Sopenharmony_ci 135062306a36Sopenharmony_ci value &= 0x00ff; 135162306a36Sopenharmony_ci temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0; 135262306a36Sopenharmony_ci temp |= (value >> 4); 135362306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp); 135462306a36Sopenharmony_ci temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0; 135562306a36Sopenharmony_ci temp |= (value & 0x0f); 135662306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp); 135762306a36Sopenharmony_ci} 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_cistatic void 136062306a36Sopenharmony_ciSiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) 136162306a36Sopenharmony_ci{ 136262306a36Sopenharmony_ci unsigned short temp; 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci value &= 0x00ff; 136562306a36Sopenharmony_ci temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f; 136662306a36Sopenharmony_ci temp |= (value & 0xf0); 136762306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp); 136862306a36Sopenharmony_ci temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f; 136962306a36Sopenharmony_ci temp |= (value << 4); 137062306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp); 137162306a36Sopenharmony_ci} 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_cistatic void 137462306a36Sopenharmony_ciSiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) 137562306a36Sopenharmony_ci{ 137662306a36Sopenharmony_ci SiS_SetSegRegLower(SiS_Pr, value); 137762306a36Sopenharmony_ci SiS_SetSegRegUpper(SiS_Pr, value); 137862306a36Sopenharmony_ci} 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_cistatic void 138162306a36Sopenharmony_ciSiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) 138262306a36Sopenharmony_ci{ 138362306a36Sopenharmony_ci SiS_SetSegmentReg(SiS_Pr, 0); 138462306a36Sopenharmony_ci} 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_cistatic void 138762306a36Sopenharmony_ciSiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value) 138862306a36Sopenharmony_ci{ 138962306a36Sopenharmony_ci unsigned short temp = value >> 8; 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ci temp &= 0x07; 139262306a36Sopenharmony_ci temp |= (temp << 4); 139362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp); 139462306a36Sopenharmony_ci SiS_SetSegmentReg(SiS_Pr, value); 139562306a36Sopenharmony_ci} 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_cistatic void 139862306a36Sopenharmony_ciSiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) 139962306a36Sopenharmony_ci{ 140062306a36Sopenharmony_ci SiS_SetSegmentRegOver(SiS_Pr, 0); 140162306a36Sopenharmony_ci} 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_cistatic void 140462306a36Sopenharmony_ciSiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) 140562306a36Sopenharmony_ci{ 140662306a36Sopenharmony_ci if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) { 140762306a36Sopenharmony_ci SiS_ResetSegmentReg(SiS_Pr); 140862306a36Sopenharmony_ci SiS_ResetSegmentRegOver(SiS_Pr); 140962306a36Sopenharmony_ci } 141062306a36Sopenharmony_ci} 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci/*********************************************/ 141362306a36Sopenharmony_ci/* HELPER: GetVBType */ 141462306a36Sopenharmony_ci/*********************************************/ 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_cistatic 141762306a36Sopenharmony_civoid 141862306a36Sopenharmony_ciSiS_GetVBType(struct SiS_Private *SiS_Pr) 141962306a36Sopenharmony_ci{ 142062306a36Sopenharmony_ci unsigned short flag = 0, rev = 0, nolcd = 0; 142162306a36Sopenharmony_ci unsigned short p4_0f, p4_25, p4_27; 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_ci SiS_Pr->SiS_VBType = 0; 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ci if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX)) 142662306a36Sopenharmony_ci return; 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_20) 142962306a36Sopenharmony_ci return; 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_ci flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci if(flag > 3) 143462306a36Sopenharmony_ci return; 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci if(flag >= 2) { 143962306a36Sopenharmony_ci SiS_Pr->SiS_VBType = VB_SIS302B; 144062306a36Sopenharmony_ci } else if(flag == 1) { 144162306a36Sopenharmony_ci if(rev >= 0xC0) { 144262306a36Sopenharmony_ci SiS_Pr->SiS_VBType = VB_SIS301C; 144362306a36Sopenharmony_ci } else if(rev >= 0xB0) { 144462306a36Sopenharmony_ci SiS_Pr->SiS_VBType = VB_SIS301B; 144562306a36Sopenharmony_ci /* Check if 30xB DH version (no LCD support, use Panel Link instead) */ 144662306a36Sopenharmony_ci nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23); 144762306a36Sopenharmony_ci if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD; 144862306a36Sopenharmony_ci } else { 144962306a36Sopenharmony_ci SiS_Pr->SiS_VBType = VB_SIS301; 145062306a36Sopenharmony_ci } 145162306a36Sopenharmony_ci } 145262306a36Sopenharmony_ci if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) { 145362306a36Sopenharmony_ci if(rev >= 0xE0) { 145462306a36Sopenharmony_ci flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39); 145562306a36Sopenharmony_ci if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV; 145662306a36Sopenharmony_ci else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */ 145762306a36Sopenharmony_ci } else if(rev >= 0xD0) { 145862306a36Sopenharmony_ci SiS_Pr->SiS_VBType = VB_SIS301LV; 145962306a36Sopenharmony_ci } 146062306a36Sopenharmony_ci } 146162306a36Sopenharmony_ci if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) { 146262306a36Sopenharmony_ci p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f); 146362306a36Sopenharmony_ci p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25); 146462306a36Sopenharmony_ci p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27); 146562306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f); 146662306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08); 146762306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd); 146862306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) { 146962306a36Sopenharmony_ci SiS_Pr->SiS_VBType |= VB_UMC; 147062306a36Sopenharmony_ci } 147162306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27); 147262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25); 147362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f); 147462306a36Sopenharmony_ci } 147562306a36Sopenharmony_ci} 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci/*********************************************/ 147862306a36Sopenharmony_ci/* HELPER: Check RAM size */ 147962306a36Sopenharmony_ci/*********************************************/ 148062306a36Sopenharmony_ci 148162306a36Sopenharmony_cistatic bool 148262306a36Sopenharmony_ciSiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 148362306a36Sopenharmony_ci unsigned short ModeIdIndex) 148462306a36Sopenharmony_ci{ 148562306a36Sopenharmony_ci unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024); 148662306a36Sopenharmony_ci unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 148762306a36Sopenharmony_ci unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1; 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci if(!AdapterMemSize) return true; 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci if(AdapterMemSize < memorysize) return false; 149262306a36Sopenharmony_ci return true; 149362306a36Sopenharmony_ci} 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci/*********************************************/ 149662306a36Sopenharmony_ci/* HELPER: Get DRAM type */ 149762306a36Sopenharmony_ci/*********************************************/ 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 150062306a36Sopenharmony_cistatic unsigned char 150162306a36Sopenharmony_ciSiS_Get310DRAMType(struct SiS_Private *SiS_Pr) 150262306a36Sopenharmony_ci{ 150362306a36Sopenharmony_ci unsigned char data; 150462306a36Sopenharmony_ci 150562306a36Sopenharmony_ci if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) { 150662306a36Sopenharmony_ci data = (*SiS_Pr->pSiS_SoftSetting) & 0x03; 150762306a36Sopenharmony_ci } else { 150862306a36Sopenharmony_ci if(SiS_Pr->ChipType >= XGI_20) { 150962306a36Sopenharmony_ci /* Do I need this? SR17 seems to be zero anyway... */ 151062306a36Sopenharmony_ci data = 0; 151162306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_340) { 151262306a36Sopenharmony_ci /* TODO */ 151362306a36Sopenharmony_ci data = 0; 151462306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_661) { 151562306a36Sopenharmony_ci if(SiS_Pr->SiS_ROMNew) { 151662306a36Sopenharmony_ci data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6); 151762306a36Sopenharmony_ci } else { 151862306a36Sopenharmony_ci data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07; 151962306a36Sopenharmony_ci } 152062306a36Sopenharmony_ci } else if(IS_SIS550650740) { 152162306a36Sopenharmony_ci data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07; 152262306a36Sopenharmony_ci } else { /* 315, 330 */ 152362306a36Sopenharmony_ci data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03; 152462306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_330) { 152562306a36Sopenharmony_ci if(data > 1) { 152662306a36Sopenharmony_ci switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) { 152762306a36Sopenharmony_ci case 0x00: data = 1; break; 152862306a36Sopenharmony_ci case 0x10: data = 3; break; 152962306a36Sopenharmony_ci case 0x20: data = 3; break; 153062306a36Sopenharmony_ci case 0x30: data = 2; break; 153162306a36Sopenharmony_ci } 153262306a36Sopenharmony_ci } else { 153362306a36Sopenharmony_ci data = 0; 153462306a36Sopenharmony_ci } 153562306a36Sopenharmony_ci } 153662306a36Sopenharmony_ci } 153762306a36Sopenharmony_ci } 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci return data; 154062306a36Sopenharmony_ci} 154162306a36Sopenharmony_ci 154262306a36Sopenharmony_cistatic unsigned short 154362306a36Sopenharmony_ciSiS_GetMCLK(struct SiS_Private *SiS_Pr) 154462306a36Sopenharmony_ci{ 154562306a36Sopenharmony_ci unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 154662306a36Sopenharmony_ci unsigned short index; 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci index = SiS_Get310DRAMType(SiS_Pr); 154962306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_661) { 155062306a36Sopenharmony_ci if(SiS_Pr->SiS_ROMNew) { 155162306a36Sopenharmony_ci return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3)))); 155262306a36Sopenharmony_ci } 155362306a36Sopenharmony_ci return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); 155462306a36Sopenharmony_ci } else if(index >= 4) { 155562306a36Sopenharmony_ci return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK); 155662306a36Sopenharmony_ci } else { 155762306a36Sopenharmony_ci return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); 155862306a36Sopenharmony_ci } 155962306a36Sopenharmony_ci} 156062306a36Sopenharmony_ci#endif 156162306a36Sopenharmony_ci 156262306a36Sopenharmony_ci/*********************************************/ 156362306a36Sopenharmony_ci/* HELPER: ClearBuffer */ 156462306a36Sopenharmony_ci/*********************************************/ 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_cistatic void 156762306a36Sopenharmony_ciSiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 156862306a36Sopenharmony_ci{ 156962306a36Sopenharmony_ci unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress; 157062306a36Sopenharmony_ci unsigned int memsize = SiS_Pr->VideoMemorySize; 157162306a36Sopenharmony_ci unsigned short SISIOMEMTYPE *pBuffer; 157262306a36Sopenharmony_ci int i; 157362306a36Sopenharmony_ci 157462306a36Sopenharmony_ci if(!memaddr || !memsize) return; 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType >= ModeEGA) { 157762306a36Sopenharmony_ci if(ModeNo > 0x13) { 157862306a36Sopenharmony_ci memset_io(memaddr, 0, memsize); 157962306a36Sopenharmony_ci } else { 158062306a36Sopenharmony_ci pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; 158162306a36Sopenharmony_ci for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]); 158262306a36Sopenharmony_ci } 158362306a36Sopenharmony_ci } else if(SiS_Pr->SiS_ModeType < ModeCGA) { 158462306a36Sopenharmony_ci pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; 158562306a36Sopenharmony_ci for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]); 158662306a36Sopenharmony_ci } else { 158762306a36Sopenharmony_ci memset_io(memaddr, 0, 0x8000); 158862306a36Sopenharmony_ci } 158962306a36Sopenharmony_ci} 159062306a36Sopenharmony_ci 159162306a36Sopenharmony_ci/*********************************************/ 159262306a36Sopenharmony_ci/* HELPER: SearchModeID */ 159362306a36Sopenharmony_ci/*********************************************/ 159462306a36Sopenharmony_ci 159562306a36Sopenharmony_cibool 159662306a36Sopenharmony_ciSiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, 159762306a36Sopenharmony_ci unsigned short *ModeIdIndex) 159862306a36Sopenharmony_ci{ 159962306a36Sopenharmony_ci unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO; 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_ci if((*ModeNo) <= 0x13) { 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_ci if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) { 160662306a36Sopenharmony_ci if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break; 160762306a36Sopenharmony_ci if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return false; 160862306a36Sopenharmony_ci } 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci if((*ModeNo) == 0x07) { 161162306a36Sopenharmony_ci if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ 161262306a36Sopenharmony_ci /* else 350 lines */ 161362306a36Sopenharmony_ci } 161462306a36Sopenharmony_ci if((*ModeNo) <= 0x03) { 161562306a36Sopenharmony_ci if(!(VGAINFO & 0x80)) (*ModeIdIndex)++; 161662306a36Sopenharmony_ci if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ 161762306a36Sopenharmony_ci /* else 350 lines */ 161862306a36Sopenharmony_ci } 161962306a36Sopenharmony_ci /* else 200 lines */ 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_ci } else { 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) { 162462306a36Sopenharmony_ci if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break; 162562306a36Sopenharmony_ci if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return false; 162662306a36Sopenharmony_ci } 162762306a36Sopenharmony_ci 162862306a36Sopenharmony_ci } 162962306a36Sopenharmony_ci return true; 163062306a36Sopenharmony_ci} 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ci/*********************************************/ 163362306a36Sopenharmony_ci/* HELPER: GetModePtr */ 163462306a36Sopenharmony_ci/*********************************************/ 163562306a36Sopenharmony_ci 163662306a36Sopenharmony_ciunsigned short 163762306a36Sopenharmony_ciSiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 163862306a36Sopenharmony_ci{ 163962306a36Sopenharmony_ci unsigned short index; 164062306a36Sopenharmony_ci 164162306a36Sopenharmony_ci if(ModeNo <= 0x13) { 164262306a36Sopenharmony_ci index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex; 164362306a36Sopenharmony_ci } else { 164462306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B; 164562306a36Sopenharmony_ci else index = 0x0F; 164662306a36Sopenharmony_ci } 164762306a36Sopenharmony_ci return index; 164862306a36Sopenharmony_ci} 164962306a36Sopenharmony_ci 165062306a36Sopenharmony_ci/*********************************************/ 165162306a36Sopenharmony_ci/* HELPERS: Get some indices */ 165262306a36Sopenharmony_ci/*********************************************/ 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ciunsigned short 165562306a36Sopenharmony_ciSiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide) 165662306a36Sopenharmony_ci{ 165762306a36Sopenharmony_ci if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) { 165862306a36Sopenharmony_ci if(UseWide == 1) { 165962306a36Sopenharmony_ci return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE; 166062306a36Sopenharmony_ci } else { 166162306a36Sopenharmony_ci return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM; 166262306a36Sopenharmony_ci } 166362306a36Sopenharmony_ci } else { 166462306a36Sopenharmony_ci return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK; 166562306a36Sopenharmony_ci } 166662306a36Sopenharmony_ci} 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_ciunsigned short 166962306a36Sopenharmony_ciSiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide) 167062306a36Sopenharmony_ci{ 167162306a36Sopenharmony_ci if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) { 167262306a36Sopenharmony_ci if(UseWide == 1) { 167362306a36Sopenharmony_ci return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE; 167462306a36Sopenharmony_ci } else { 167562306a36Sopenharmony_ci return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM; 167662306a36Sopenharmony_ci } 167762306a36Sopenharmony_ci } else { 167862306a36Sopenharmony_ci return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC; 167962306a36Sopenharmony_ci } 168062306a36Sopenharmony_ci} 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci/*********************************************/ 168362306a36Sopenharmony_ci/* HELPER: LowModeTests */ 168462306a36Sopenharmony_ci/*********************************************/ 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_cistatic bool 168762306a36Sopenharmony_ciSiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 168862306a36Sopenharmony_ci{ 168962306a36Sopenharmony_ci unsigned short temp, temp1, temp2; 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_ci if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12)) 169262306a36Sopenharmony_ci return true; 169362306a36Sopenharmony_ci temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11); 169462306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80); 169562306a36Sopenharmony_ci temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); 169662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55); 169762306a36Sopenharmony_ci temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); 169862306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1); 169962306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp); 170062306a36Sopenharmony_ci if((SiS_Pr->ChipType >= SIS_315H) || 170162306a36Sopenharmony_ci (SiS_Pr->ChipType == SIS_300)) { 170262306a36Sopenharmony_ci if(temp2 == 0x55) return false; 170362306a36Sopenharmony_ci else return true; 170462306a36Sopenharmony_ci } else { 170562306a36Sopenharmony_ci if(temp2 != 0x55) return true; 170662306a36Sopenharmony_ci else { 170762306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 170862306a36Sopenharmony_ci return false; 170962306a36Sopenharmony_ci } 171062306a36Sopenharmony_ci } 171162306a36Sopenharmony_ci} 171262306a36Sopenharmony_ci 171362306a36Sopenharmony_cistatic void 171462306a36Sopenharmony_ciSiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 171562306a36Sopenharmony_ci{ 171662306a36Sopenharmony_ci if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) { 171762306a36Sopenharmony_ci SiS_Pr->SiS_SetFlag |= LowModeTests; 171862306a36Sopenharmony_ci } 171962306a36Sopenharmony_ci} 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ci/*********************************************/ 172262306a36Sopenharmony_ci/* HELPER: OPEN/CLOSE CRT1 CRTC */ 172362306a36Sopenharmony_ci/*********************************************/ 172462306a36Sopenharmony_ci 172562306a36Sopenharmony_cistatic void 172662306a36Sopenharmony_ciSiS_OpenCRTC(struct SiS_Private *SiS_Pr) 172762306a36Sopenharmony_ci{ 172862306a36Sopenharmony_ci if(IS_SIS650) { 172962306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); 173062306a36Sopenharmony_ci if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20); 173162306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); 173262306a36Sopenharmony_ci } else if(IS_SIS661741660760) { 173362306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7); 173462306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); 173562306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); 173662306a36Sopenharmony_ci if(!SiS_Pr->SiS_ROMNew) { 173762306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef); 173862306a36Sopenharmony_ci } 173962306a36Sopenharmony_ci } 174062306a36Sopenharmony_ci} 174162306a36Sopenharmony_ci 174262306a36Sopenharmony_cistatic void 174362306a36Sopenharmony_ciSiS_CloseCRTC(struct SiS_Private *SiS_Pr) 174462306a36Sopenharmony_ci{ 174562306a36Sopenharmony_ci#if 0 /* This locks some CRTC registers. We don't want that. */ 174662306a36Sopenharmony_ci unsigned short temp1 = 0, temp2 = 0; 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci if(IS_SIS661741660760) { 174962306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 175062306a36Sopenharmony_ci temp1 = 0xa0; temp2 = 0x08; 175162306a36Sopenharmony_ci } 175262306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x51,0x1f,temp1); 175362306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x56,0xe7,temp2); 175462306a36Sopenharmony_ci } 175562306a36Sopenharmony_ci#endif 175662306a36Sopenharmony_ci} 175762306a36Sopenharmony_ci 175862306a36Sopenharmony_cistatic void 175962306a36Sopenharmony_ciSiS_HandleCRT1(struct SiS_Private *SiS_Pr) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci /* Enable CRT1 gating */ 176262306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf); 176362306a36Sopenharmony_ci#if 0 176462306a36Sopenharmony_ci if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) { 176562306a36Sopenharmony_ci if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) || 176662306a36Sopenharmony_ci (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) { 176762306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40); 176862306a36Sopenharmony_ci } 176962306a36Sopenharmony_ci } 177062306a36Sopenharmony_ci#endif 177162306a36Sopenharmony_ci} 177262306a36Sopenharmony_ci 177362306a36Sopenharmony_ci/*********************************************/ 177462306a36Sopenharmony_ci/* HELPER: GetColorDepth */ 177562306a36Sopenharmony_ci/*********************************************/ 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_ciunsigned short 177862306a36Sopenharmony_ciSiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 177962306a36Sopenharmony_ci unsigned short ModeIdIndex) 178062306a36Sopenharmony_ci{ 178162306a36Sopenharmony_ci static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; 178262306a36Sopenharmony_ci unsigned short modeflag; 178362306a36Sopenharmony_ci short index; 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci /* Do NOT check UseCustomMode, will skrew up FIFO */ 178662306a36Sopenharmony_ci if(ModeNo == 0xfe) { 178762306a36Sopenharmony_ci modeflag = SiS_Pr->CModeFlag; 178862306a36Sopenharmony_ci } else if(ModeNo <= 0x13) { 178962306a36Sopenharmony_ci modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 179062306a36Sopenharmony_ci } else { 179162306a36Sopenharmony_ci modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 179262306a36Sopenharmony_ci } 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci index = (modeflag & ModeTypeMask) - ModeEGA; 179562306a36Sopenharmony_ci if(index < 0) index = 0; 179662306a36Sopenharmony_ci return ColorDepth[index]; 179762306a36Sopenharmony_ci} 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci/*********************************************/ 180062306a36Sopenharmony_ci/* HELPER: GetOffset */ 180162306a36Sopenharmony_ci/*********************************************/ 180262306a36Sopenharmony_ci 180362306a36Sopenharmony_ciunsigned short 180462306a36Sopenharmony_ciSiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 180562306a36Sopenharmony_ci unsigned short ModeIdIndex, unsigned short RRTI) 180662306a36Sopenharmony_ci{ 180762306a36Sopenharmony_ci unsigned short xres, temp, colordepth, infoflag; 180862306a36Sopenharmony_ci 180962306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 181062306a36Sopenharmony_ci infoflag = SiS_Pr->CInfoFlag; 181162306a36Sopenharmony_ci xres = SiS_Pr->CHDisplay; 181262306a36Sopenharmony_ci } else { 181362306a36Sopenharmony_ci infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag; 181462306a36Sopenharmony_ci xres = SiS_Pr->SiS_RefIndex[RRTI].XRes; 181562306a36Sopenharmony_ci } 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex); 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci temp = xres / 16; 182062306a36Sopenharmony_ci if(infoflag & InterlaceMode) temp <<= 1; 182162306a36Sopenharmony_ci temp *= colordepth; 182262306a36Sopenharmony_ci if(xres % 16) temp += (colordepth >> 1); 182362306a36Sopenharmony_ci 182462306a36Sopenharmony_ci return temp; 182562306a36Sopenharmony_ci} 182662306a36Sopenharmony_ci 182762306a36Sopenharmony_ci/*********************************************/ 182862306a36Sopenharmony_ci/* SEQ */ 182962306a36Sopenharmony_ci/*********************************************/ 183062306a36Sopenharmony_ci 183162306a36Sopenharmony_cistatic void 183262306a36Sopenharmony_ciSiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 183362306a36Sopenharmony_ci{ 183462306a36Sopenharmony_ci unsigned char SRdata; 183562306a36Sopenharmony_ci int i; 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); 183862306a36Sopenharmony_ci 183962306a36Sopenharmony_ci /* or "display off" */ 184062306a36Sopenharmony_ci SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; 184162306a36Sopenharmony_ci 184262306a36Sopenharmony_ci /* determine whether to force x8 dotclock */ 184362306a36Sopenharmony_ci if((SiS_Pr->SiS_VBType & VB_SISVB) || (SiS_Pr->SiS_IF_DEF_LVDS)) { 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { 184662306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) SRdata |= 0x01; 184762306a36Sopenharmony_ci } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) SRdata |= 0x01; 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_ci } 185062306a36Sopenharmony_ci 185162306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata); 185262306a36Sopenharmony_ci 185362306a36Sopenharmony_ci for(i = 2; i <= 4; i++) { 185462306a36Sopenharmony_ci SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1]; 185562306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata); 185662306a36Sopenharmony_ci } 185762306a36Sopenharmony_ci} 185862306a36Sopenharmony_ci 185962306a36Sopenharmony_ci/*********************************************/ 186062306a36Sopenharmony_ci/* MISC */ 186162306a36Sopenharmony_ci/*********************************************/ 186262306a36Sopenharmony_ci 186362306a36Sopenharmony_cistatic void 186462306a36Sopenharmony_ciSiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 186562306a36Sopenharmony_ci{ 186662306a36Sopenharmony_ci unsigned char Miscdata; 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_ci Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; 186962306a36Sopenharmony_ci 187062306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_661) { 187162306a36Sopenharmony_ci if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 187262306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 187362306a36Sopenharmony_ci Miscdata |= 0x0C; 187462306a36Sopenharmony_ci } 187562306a36Sopenharmony_ci } 187662306a36Sopenharmony_ci } 187762306a36Sopenharmony_ci 187862306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata); 187962306a36Sopenharmony_ci} 188062306a36Sopenharmony_ci 188162306a36Sopenharmony_ci/*********************************************/ 188262306a36Sopenharmony_ci/* CRTC */ 188362306a36Sopenharmony_ci/*********************************************/ 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_cistatic void 188662306a36Sopenharmony_ciSiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 188762306a36Sopenharmony_ci{ 188862306a36Sopenharmony_ci unsigned char CRTCdata; 188962306a36Sopenharmony_ci unsigned short i; 189062306a36Sopenharmony_ci 189162306a36Sopenharmony_ci /* Unlock CRTC */ 189262306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 189362306a36Sopenharmony_ci 189462306a36Sopenharmony_ci for(i = 0; i <= 0x18; i++) { 189562306a36Sopenharmony_ci CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; 189662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); 189762306a36Sopenharmony_ci } 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_661) { 190062306a36Sopenharmony_ci SiS_OpenCRTC(SiS_Pr); 190162306a36Sopenharmony_ci for(i = 0x13; i <= 0x14; i++) { 190262306a36Sopenharmony_ci CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; 190362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); 190462306a36Sopenharmony_ci } 190562306a36Sopenharmony_ci } else if( ( (SiS_Pr->ChipType == SIS_630) || 190662306a36Sopenharmony_ci (SiS_Pr->ChipType == SIS_730) ) && 190762306a36Sopenharmony_ci (SiS_Pr->ChipRevision >= 0x30) ) { 190862306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 190962306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { 191062306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE); 191162306a36Sopenharmony_ci } 191262306a36Sopenharmony_ci } 191362306a36Sopenharmony_ci } 191462306a36Sopenharmony_ci} 191562306a36Sopenharmony_ci 191662306a36Sopenharmony_ci/*********************************************/ 191762306a36Sopenharmony_ci/* ATT */ 191862306a36Sopenharmony_ci/*********************************************/ 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_cistatic void 192162306a36Sopenharmony_ciSiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 192262306a36Sopenharmony_ci{ 192362306a36Sopenharmony_ci unsigned char ARdata; 192462306a36Sopenharmony_ci unsigned short i; 192562306a36Sopenharmony_ci 192662306a36Sopenharmony_ci for(i = 0; i <= 0x13; i++) { 192762306a36Sopenharmony_ci ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci if(i == 0x13) { 193062306a36Sopenharmony_ci /* Pixel shift. If screen on LCD or TV is shifted left or right, 193162306a36Sopenharmony_ci * this might be the cause. 193262306a36Sopenharmony_ci */ 193362306a36Sopenharmony_ci if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 193462306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ARdata = 0; 193562306a36Sopenharmony_ci } 193662306a36Sopenharmony_ci if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 193762306a36Sopenharmony_ci if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 193862306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 193962306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 194062306a36Sopenharmony_ci } 194162306a36Sopenharmony_ci } 194262306a36Sopenharmony_ci } 194362306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_661) { 194462306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { 194562306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 194662306a36Sopenharmony_ci } 194762306a36Sopenharmony_ci } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 194862306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 194962306a36Sopenharmony_ci if(IS_SIS550650740660) { 195062306a36Sopenharmony_ci /* 315, 330 don't do this */ 195162306a36Sopenharmony_ci if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 195262306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 195362306a36Sopenharmony_ci } else { 195462306a36Sopenharmony_ci ARdata = 0; 195562306a36Sopenharmony_ci } 195662306a36Sopenharmony_ci } 195762306a36Sopenharmony_ci } else { 195862306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata = 0; 195962306a36Sopenharmony_ci } 196062306a36Sopenharmony_ci } 196162306a36Sopenharmony_ci } 196262306a36Sopenharmony_ci SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */ 196362306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c0,i); /* set index */ 196462306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata); /* set data */ 196562306a36Sopenharmony_ci } 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_ci SiS_GetRegByte(SiS_Pr->SiS_P3da); /* reset 3da */ 196862306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14); /* set index */ 196962306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00); /* set data */ 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_ci SiS_GetRegByte(SiS_Pr->SiS_P3da); 197262306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20); /* Enable Attribute */ 197362306a36Sopenharmony_ci SiS_GetRegByte(SiS_Pr->SiS_P3da); 197462306a36Sopenharmony_ci} 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci/*********************************************/ 197762306a36Sopenharmony_ci/* GRC */ 197862306a36Sopenharmony_ci/*********************************************/ 197962306a36Sopenharmony_ci 198062306a36Sopenharmony_cistatic void 198162306a36Sopenharmony_ciSiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) 198262306a36Sopenharmony_ci{ 198362306a36Sopenharmony_ci unsigned char GRdata; 198462306a36Sopenharmony_ci unsigned short i; 198562306a36Sopenharmony_ci 198662306a36Sopenharmony_ci for(i = 0; i <= 0x08; i++) { 198762306a36Sopenharmony_ci GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; 198862306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata); 198962306a36Sopenharmony_ci } 199062306a36Sopenharmony_ci 199162306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType > ModeVGA) { 199262306a36Sopenharmony_ci /* 256 color disable */ 199362306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF); 199462306a36Sopenharmony_ci } 199562306a36Sopenharmony_ci} 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_ci/*********************************************/ 199862306a36Sopenharmony_ci/* CLEAR EXTENDED REGISTERS */ 199962306a36Sopenharmony_ci/*********************************************/ 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_cistatic void 200262306a36Sopenharmony_ciSiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 200362306a36Sopenharmony_ci{ 200462306a36Sopenharmony_ci unsigned short i; 200562306a36Sopenharmony_ci 200662306a36Sopenharmony_ci for(i = 0x0A; i <= 0x0E; i++) { 200762306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00); 200862306a36Sopenharmony_ci } 200962306a36Sopenharmony_ci 201062306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 201162306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE); 201262306a36Sopenharmony_ci if(ModeNo <= 0x13) { 201362306a36Sopenharmony_ci if(ModeNo == 0x06 || ModeNo >= 0x0e) { 201462306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20); 201562306a36Sopenharmony_ci } 201662306a36Sopenharmony_ci } 201762306a36Sopenharmony_ci } 201862306a36Sopenharmony_ci} 201962306a36Sopenharmony_ci 202062306a36Sopenharmony_ci/*********************************************/ 202162306a36Sopenharmony_ci/* RESET VCLK */ 202262306a36Sopenharmony_ci/*********************************************/ 202362306a36Sopenharmony_ci 202462306a36Sopenharmony_cistatic void 202562306a36Sopenharmony_ciSiS_ResetCRT1VCLK(struct SiS_Private *SiS_Pr) 202662306a36Sopenharmony_ci{ 202762306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 202862306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_661) { 202962306a36Sopenharmony_ci if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return; 203062306a36Sopenharmony_ci } 203162306a36Sopenharmony_ci } else { 203262306a36Sopenharmony_ci if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && 203362306a36Sopenharmony_ci (!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) { 203462306a36Sopenharmony_ci return; 203562306a36Sopenharmony_ci } 203662306a36Sopenharmony_ci } 203762306a36Sopenharmony_ci 203862306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x20); 203962306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B); 204062306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C); 204162306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 204262306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10); 204362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B); 204462306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C); 204562306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 204662306a36Sopenharmony_ci} 204762306a36Sopenharmony_ci 204862306a36Sopenharmony_ci/*********************************************/ 204962306a36Sopenharmony_ci/* SYNC */ 205062306a36Sopenharmony_ci/*********************************************/ 205162306a36Sopenharmony_ci 205262306a36Sopenharmony_cistatic void 205362306a36Sopenharmony_ciSiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short RRTI) 205462306a36Sopenharmony_ci{ 205562306a36Sopenharmony_ci unsigned short sync; 205662306a36Sopenharmony_ci 205762306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 205862306a36Sopenharmony_ci sync = SiS_Pr->CInfoFlag >> 8; 205962306a36Sopenharmony_ci } else { 206062306a36Sopenharmony_ci sync = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag >> 8; 206162306a36Sopenharmony_ci } 206262306a36Sopenharmony_ci 206362306a36Sopenharmony_ci sync &= 0xC0; 206462306a36Sopenharmony_ci sync |= 0x2f; 206562306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync); 206662306a36Sopenharmony_ci} 206762306a36Sopenharmony_ci 206862306a36Sopenharmony_ci/*********************************************/ 206962306a36Sopenharmony_ci/* CRTC/2 */ 207062306a36Sopenharmony_ci/*********************************************/ 207162306a36Sopenharmony_ci 207262306a36Sopenharmony_cistatic void 207362306a36Sopenharmony_ciSiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 207462306a36Sopenharmony_ci unsigned short ModeIdIndex, unsigned short RRTI) 207562306a36Sopenharmony_ci{ 207662306a36Sopenharmony_ci unsigned short temp, i, j, modeflag; 207762306a36Sopenharmony_ci unsigned char *crt1data = NULL; 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 208062306a36Sopenharmony_ci 208162306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci crt1data = &SiS_Pr->CCRT1CRTC[0]; 208462306a36Sopenharmony_ci 208562306a36Sopenharmony_ci } else { 208662306a36Sopenharmony_ci 208762306a36Sopenharmony_ci temp = SiS_GetRefCRT1CRTC(SiS_Pr, RRTI, SiS_Pr->SiS_UseWide); 208862306a36Sopenharmony_ci 208962306a36Sopenharmony_ci /* Alternate for 1600x1200 LCDA */ 209062306a36Sopenharmony_ci if((temp == 0x20) && (SiS_Pr->Alternate1600x1200)) temp = 0x57; 209162306a36Sopenharmony_ci 209262306a36Sopenharmony_ci crt1data = (unsigned char *)&SiS_Pr->SiS_CRT1Table[temp].CR[0]; 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci } 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_ci /* unlock cr0-7 */ 209762306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 209862306a36Sopenharmony_ci 209962306a36Sopenharmony_ci for(i = 0, j = 0; i <= 7; i++, j++) { 210062306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]); 210162306a36Sopenharmony_ci } 210262306a36Sopenharmony_ci for(j = 0x10; i <= 10; i++, j++) { 210362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]); 210462306a36Sopenharmony_ci } 210562306a36Sopenharmony_ci for(j = 0x15; i <= 12; i++, j++) { 210662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,j,crt1data[i]); 210762306a36Sopenharmony_ci } 210862306a36Sopenharmony_ci for(j = 0x0A; i <= 15; i++, j++) { 210962306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,j,crt1data[i]); 211062306a36Sopenharmony_ci } 211162306a36Sopenharmony_ci 211262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,crt1data[16] & 0xE0); 211362306a36Sopenharmony_ci 211462306a36Sopenharmony_ci temp = (crt1data[16] & 0x01) << 5; 211562306a36Sopenharmony_ci if(modeflag & DoubleScanMode) temp |= 0x80; 211662306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp); 211762306a36Sopenharmony_ci 211862306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType > ModeVGA) { 211962306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F); 212062306a36Sopenharmony_ci } 212162306a36Sopenharmony_ci 212262306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 212362306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_20) { 212462306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1); 212562306a36Sopenharmony_ci if(!(temp = crt1data[5] & 0x1f)) { 212662306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0c,0xfb); 212762306a36Sopenharmony_ci } 212862306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x05,0xe0,((temp - 1) & 0x1f)); 212962306a36Sopenharmony_ci temp = (crt1data[16] >> 5) + 3; 213062306a36Sopenharmony_ci if(temp > 7) temp -= 7; 213162306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0e,0x1f,(temp << 5)); 213262306a36Sopenharmony_ci } 213362306a36Sopenharmony_ci#endif 213462306a36Sopenharmony_ci} 213562306a36Sopenharmony_ci 213662306a36Sopenharmony_ci/*********************************************/ 213762306a36Sopenharmony_ci/* OFFSET & PITCH */ 213862306a36Sopenharmony_ci/*********************************************/ 213962306a36Sopenharmony_ci/* (partly overruled by SetPitch() in XF86) */ 214062306a36Sopenharmony_ci/*********************************************/ 214162306a36Sopenharmony_ci 214262306a36Sopenharmony_cistatic void 214362306a36Sopenharmony_ciSiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 214462306a36Sopenharmony_ci unsigned short ModeIdIndex, unsigned short RRTI) 214562306a36Sopenharmony_ci{ 214662306a36Sopenharmony_ci unsigned short temp, DisplayUnit, infoflag; 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 214962306a36Sopenharmony_ci infoflag = SiS_Pr->CInfoFlag; 215062306a36Sopenharmony_ci } else { 215162306a36Sopenharmony_ci infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag; 215262306a36Sopenharmony_ci } 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_ci DisplayUnit = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 215562306a36Sopenharmony_ci 215662306a36Sopenharmony_ci temp = (DisplayUnit >> 8) & 0x0f; 215762306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp); 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,DisplayUnit & 0xFF); 216062306a36Sopenharmony_ci 216162306a36Sopenharmony_ci if(infoflag & InterlaceMode) DisplayUnit >>= 1; 216262306a36Sopenharmony_ci 216362306a36Sopenharmony_ci DisplayUnit <<= 5; 216462306a36Sopenharmony_ci temp = (DisplayUnit >> 8) + 1; 216562306a36Sopenharmony_ci if(DisplayUnit & 0xff) temp++; 216662306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_20) { 216762306a36Sopenharmony_ci if(ModeNo == 0x4a || ModeNo == 0x49) temp--; 216862306a36Sopenharmony_ci } 216962306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp); 217062306a36Sopenharmony_ci} 217162306a36Sopenharmony_ci 217262306a36Sopenharmony_ci/*********************************************/ 217362306a36Sopenharmony_ci/* VCLK */ 217462306a36Sopenharmony_ci/*********************************************/ 217562306a36Sopenharmony_ci 217662306a36Sopenharmony_cistatic void 217762306a36Sopenharmony_ciSiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 217862306a36Sopenharmony_ci unsigned short ModeIdIndex, unsigned short RRTI) 217962306a36Sopenharmony_ci{ 218062306a36Sopenharmony_ci unsigned short index = 0, clka, clkb; 218162306a36Sopenharmony_ci 218262306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 218362306a36Sopenharmony_ci clka = SiS_Pr->CSR2B; 218462306a36Sopenharmony_ci clkb = SiS_Pr->CSR2C; 218562306a36Sopenharmony_ci } else { 218662306a36Sopenharmony_ci index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 218762306a36Sopenharmony_ci if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && 218862306a36Sopenharmony_ci (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 218962306a36Sopenharmony_ci /* Alternate for 1600x1200 LCDA */ 219062306a36Sopenharmony_ci if((index == 0x21) && (SiS_Pr->Alternate1600x1200)) index = 0x72; 219162306a36Sopenharmony_ci clka = SiS_Pr->SiS_VBVCLKData[index].Part4_A; 219262306a36Sopenharmony_ci clkb = SiS_Pr->SiS_VBVCLKData[index].Part4_B; 219362306a36Sopenharmony_ci } else { 219462306a36Sopenharmony_ci clka = SiS_Pr->SiS_VCLKData[index].SR2B; 219562306a36Sopenharmony_ci clkb = SiS_Pr->SiS_VCLKData[index].SR2C; 219662306a36Sopenharmony_ci } 219762306a36Sopenharmony_ci } 219862306a36Sopenharmony_ci 219962306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF); 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,clka); 220262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb); 220362306a36Sopenharmony_ci 220462306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 220562306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 220662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01); 220762306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_20) { 220862306a36Sopenharmony_ci unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 220962306a36Sopenharmony_ci if(mf & HalfDCLK) { 221062306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,SiS_GetReg(SiS_Pr->SiS_P3c4,0x2b)); 221162306a36Sopenharmony_ci clkb = SiS_GetReg(SiS_Pr->SiS_P3c4,0x2c); 221262306a36Sopenharmony_ci clkb = (((clkb & 0x1f) << 1) + 1) | (clkb & 0xe0); 221362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb); 221462306a36Sopenharmony_ci } 221562306a36Sopenharmony_ci } 221662306a36Sopenharmony_ci#endif 221762306a36Sopenharmony_ci } else { 221862306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80); 221962306a36Sopenharmony_ci } 222062306a36Sopenharmony_ci} 222162306a36Sopenharmony_ci 222262306a36Sopenharmony_ci/*********************************************/ 222362306a36Sopenharmony_ci/* FIFO */ 222462306a36Sopenharmony_ci/*********************************************/ 222562306a36Sopenharmony_ci 222662306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 222762306a36Sopenharmony_civoid 222862306a36Sopenharmony_ciSiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1, 222962306a36Sopenharmony_ci unsigned short *idx2) 223062306a36Sopenharmony_ci{ 223162306a36Sopenharmony_ci unsigned short temp1, temp2; 223262306a36Sopenharmony_ci static const unsigned char ThTiming[8] = { 223362306a36Sopenharmony_ci 1, 2, 2, 3, 0, 1, 1, 2 223462306a36Sopenharmony_ci }; 223562306a36Sopenharmony_ci 223662306a36Sopenharmony_ci temp1 = temp2 = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x62) >> 1; 223762306a36Sopenharmony_ci (*idx2) = (unsigned short)(ThTiming[((temp2 >> 3) | temp1) & 0x07]); 223862306a36Sopenharmony_ci (*idx1) = (unsigned short)(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6) & 0x03; 223962306a36Sopenharmony_ci (*idx1) |= (unsigned short)(((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 4) & 0x0c)); 224062306a36Sopenharmony_ci (*idx1) <<= 1; 224162306a36Sopenharmony_ci} 224262306a36Sopenharmony_ci 224362306a36Sopenharmony_cistatic unsigned short 224462306a36Sopenharmony_ciSiS_GetFIFOThresholdA300(unsigned short idx1, unsigned short idx2) 224562306a36Sopenharmony_ci{ 224662306a36Sopenharmony_ci static const unsigned char ThLowA[8 * 3] = { 224762306a36Sopenharmony_ci 61, 3,52, 5,68, 7,100,11, 224862306a36Sopenharmony_ci 43, 3,42, 5,54, 7, 78,11, 224962306a36Sopenharmony_ci 34, 3,37, 5,47, 7, 67,11 225062306a36Sopenharmony_ci }; 225162306a36Sopenharmony_ci 225262306a36Sopenharmony_ci return (unsigned short)((ThLowA[idx1 + 1] * idx2) + ThLowA[idx1]); 225362306a36Sopenharmony_ci} 225462306a36Sopenharmony_ci 225562306a36Sopenharmony_ciunsigned short 225662306a36Sopenharmony_ciSiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2) 225762306a36Sopenharmony_ci{ 225862306a36Sopenharmony_ci static const unsigned char ThLowB[8 * 3] = { 225962306a36Sopenharmony_ci 81, 4,72, 6,88, 8,120,12, 226062306a36Sopenharmony_ci 55, 4,54, 6,66, 8, 90,12, 226162306a36Sopenharmony_ci 42, 4,45, 6,55, 8, 75,12 226262306a36Sopenharmony_ci }; 226362306a36Sopenharmony_ci 226462306a36Sopenharmony_ci return (unsigned short)((ThLowB[idx1 + 1] * idx2) + ThLowB[idx1]); 226562306a36Sopenharmony_ci} 226662306a36Sopenharmony_ci 226762306a36Sopenharmony_cistatic unsigned short 226862306a36Sopenharmony_ciSiS_DoCalcDelay(struct SiS_Private *SiS_Pr, unsigned short MCLK, unsigned short VCLK, 226962306a36Sopenharmony_ci unsigned short colordepth, unsigned short key) 227062306a36Sopenharmony_ci{ 227162306a36Sopenharmony_ci unsigned short idx1, idx2; 227262306a36Sopenharmony_ci unsigned int longtemp = VCLK * colordepth; 227362306a36Sopenharmony_ci 227462306a36Sopenharmony_ci SiS_GetFIFOThresholdIndex300(SiS_Pr, &idx1, &idx2); 227562306a36Sopenharmony_ci 227662306a36Sopenharmony_ci if(key == 0) { 227762306a36Sopenharmony_ci longtemp *= SiS_GetFIFOThresholdA300(idx1, idx2); 227862306a36Sopenharmony_ci } else { 227962306a36Sopenharmony_ci longtemp *= SiS_GetFIFOThresholdB300(idx1, idx2); 228062306a36Sopenharmony_ci } 228162306a36Sopenharmony_ci idx1 = longtemp % (MCLK * 16); 228262306a36Sopenharmony_ci longtemp /= (MCLK * 16); 228362306a36Sopenharmony_ci if(idx1) longtemp++; 228462306a36Sopenharmony_ci return (unsigned short)longtemp; 228562306a36Sopenharmony_ci} 228662306a36Sopenharmony_ci 228762306a36Sopenharmony_cistatic unsigned short 228862306a36Sopenharmony_ciSiS_CalcDelay(struct SiS_Private *SiS_Pr, unsigned short VCLK, 228962306a36Sopenharmony_ci unsigned short colordepth, unsigned short MCLK) 229062306a36Sopenharmony_ci{ 229162306a36Sopenharmony_ci unsigned short temp1, temp2; 229262306a36Sopenharmony_ci 229362306a36Sopenharmony_ci temp2 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0); 229462306a36Sopenharmony_ci temp1 = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1); 229562306a36Sopenharmony_ci if(temp1 < 4) temp1 = 4; 229662306a36Sopenharmony_ci temp1 -= 4; 229762306a36Sopenharmony_ci if(temp2 < temp1) temp2 = temp1; 229862306a36Sopenharmony_ci return temp2; 229962306a36Sopenharmony_ci} 230062306a36Sopenharmony_ci 230162306a36Sopenharmony_cistatic void 230262306a36Sopenharmony_ciSiS_SetCRT1FIFO_300(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 230362306a36Sopenharmony_ci unsigned short RefreshRateTableIndex) 230462306a36Sopenharmony_ci{ 230562306a36Sopenharmony_ci unsigned short ThresholdLow = 0; 230662306a36Sopenharmony_ci unsigned short temp, index, VCLK, MCLK, colorth; 230762306a36Sopenharmony_ci static const unsigned short colortharray[6] = { 1, 1, 2, 2, 3, 4 }; 230862306a36Sopenharmony_ci 230962306a36Sopenharmony_ci if(ModeNo > 0x13) { 231062306a36Sopenharmony_ci 231162306a36Sopenharmony_ci /* Get VCLK */ 231262306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 231362306a36Sopenharmony_ci VCLK = SiS_Pr->CSRClock; 231462306a36Sopenharmony_ci } else { 231562306a36Sopenharmony_ci index = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide); 231662306a36Sopenharmony_ci VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 231762306a36Sopenharmony_ci } 231862306a36Sopenharmony_ci 231962306a36Sopenharmony_ci /* Get half colordepth */ 232062306a36Sopenharmony_ci colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)]; 232162306a36Sopenharmony_ci 232262306a36Sopenharmony_ci /* Get MCLK */ 232362306a36Sopenharmony_ci index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A) & 0x07; 232462306a36Sopenharmony_ci MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; 232562306a36Sopenharmony_ci 232662306a36Sopenharmony_ci temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xc3; 232762306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,temp); 232862306a36Sopenharmony_ci 232962306a36Sopenharmony_ci do { 233062306a36Sopenharmony_ci ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK) + 1; 233162306a36Sopenharmony_ci if(ThresholdLow < 0x13) break; 233262306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc); 233362306a36Sopenharmony_ci ThresholdLow = 0x13; 233462306a36Sopenharmony_ci temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) >> 6; 233562306a36Sopenharmony_ci if(!temp) break; 233662306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,((temp - 1) << 6)); 233762306a36Sopenharmony_ci } while(0); 233862306a36Sopenharmony_ci 233962306a36Sopenharmony_ci } else ThresholdLow = 2; 234062306a36Sopenharmony_ci 234162306a36Sopenharmony_ci /* Write CRT/CPU threshold low, CRT/Engine threshold high */ 234262306a36Sopenharmony_ci temp = (ThresholdLow << 4) | 0x0f; 234362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp); 234462306a36Sopenharmony_ci 234562306a36Sopenharmony_ci temp = (ThresholdLow & 0x10) << 1; 234662306a36Sopenharmony_ci if(ModeNo > 0x13) temp |= 0x40; 234762306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp); 234862306a36Sopenharmony_ci 234962306a36Sopenharmony_ci /* What is this? */ 235062306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09); 235162306a36Sopenharmony_ci 235262306a36Sopenharmony_ci /* Write CRT/CPU threshold high */ 235362306a36Sopenharmony_ci temp = ThresholdLow + 3; 235462306a36Sopenharmony_ci if(temp > 0x0f) temp = 0x0f; 235562306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp); 235662306a36Sopenharmony_ci} 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ciunsigned short 235962306a36Sopenharmony_ciSiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index) 236062306a36Sopenharmony_ci{ 236162306a36Sopenharmony_ci static const unsigned char LatencyFactor[] = { 236262306a36Sopenharmony_ci 97, 88, 86, 79, 77, 0, /* 64 bit BQ=2 */ 236362306a36Sopenharmony_ci 0, 87, 85, 78, 76, 54, /* 64 bit BQ=1 */ 236462306a36Sopenharmony_ci 97, 88, 86, 79, 77, 0, /* 128 bit BQ=2 */ 236562306a36Sopenharmony_ci 0, 79, 77, 70, 68, 48, /* 128 bit BQ=1 */ 236662306a36Sopenharmony_ci 80, 72, 69, 63, 61, 0, /* 64 bit BQ=2 */ 236762306a36Sopenharmony_ci 0, 70, 68, 61, 59, 37, /* 64 bit BQ=1 */ 236862306a36Sopenharmony_ci 86, 77, 75, 68, 66, 0, /* 128 bit BQ=2 */ 236962306a36Sopenharmony_ci 0, 68, 66, 59, 57, 37 /* 128 bit BQ=1 */ 237062306a36Sopenharmony_ci }; 237162306a36Sopenharmony_ci static const unsigned char LatencyFactor730[] = { 237262306a36Sopenharmony_ci 69, 63, 61, 237362306a36Sopenharmony_ci 86, 79, 77, 237462306a36Sopenharmony_ci 103, 96, 94, 237562306a36Sopenharmony_ci 120,113,111, 237662306a36Sopenharmony_ci 137,130,128 237762306a36Sopenharmony_ci }; 237862306a36Sopenharmony_ci 237962306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_730) { 238062306a36Sopenharmony_ci return (unsigned short)LatencyFactor730[index]; 238162306a36Sopenharmony_ci } else { 238262306a36Sopenharmony_ci return (unsigned short)LatencyFactor[index]; 238362306a36Sopenharmony_ci } 238462306a36Sopenharmony_ci} 238562306a36Sopenharmony_ci 238662306a36Sopenharmony_cistatic unsigned short 238762306a36Sopenharmony_ciSiS_CalcDelay2(struct SiS_Private *SiS_Pr, unsigned char key) 238862306a36Sopenharmony_ci{ 238962306a36Sopenharmony_ci unsigned short index; 239062306a36Sopenharmony_ci 239162306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_730) { 239262306a36Sopenharmony_ci index = ((key & 0x0f) * 3) + ((key & 0xc0) >> 6); 239362306a36Sopenharmony_ci } else { 239462306a36Sopenharmony_ci index = (key & 0xe0) >> 5; 239562306a36Sopenharmony_ci if(key & 0x10) index += 6; 239662306a36Sopenharmony_ci if(!(key & 0x01)) index += 24; 239762306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12; 239862306a36Sopenharmony_ci } 239962306a36Sopenharmony_ci return SiS_GetLatencyFactor630(SiS_Pr, index); 240062306a36Sopenharmony_ci} 240162306a36Sopenharmony_ci 240262306a36Sopenharmony_cistatic void 240362306a36Sopenharmony_ciSiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 240462306a36Sopenharmony_ci unsigned short RefreshRateTableIndex) 240562306a36Sopenharmony_ci{ 240662306a36Sopenharmony_ci unsigned short ThresholdLow = 0; 240762306a36Sopenharmony_ci unsigned short i, data, VCLK, MCLK16, colorth = 0; 240862306a36Sopenharmony_ci unsigned int templ, datal; 240962306a36Sopenharmony_ci const unsigned char *queuedata = NULL; 241062306a36Sopenharmony_ci static const unsigned char FQBQData[21] = { 241162306a36Sopenharmony_ci 0x01,0x21,0x41,0x61,0x81, 241262306a36Sopenharmony_ci 0x31,0x51,0x71,0x91,0xb1, 241362306a36Sopenharmony_ci 0x00,0x20,0x40,0x60,0x80, 241462306a36Sopenharmony_ci 0x30,0x50,0x70,0x90,0xb0, 241562306a36Sopenharmony_ci 0xff 241662306a36Sopenharmony_ci }; 241762306a36Sopenharmony_ci static const unsigned char FQBQData730[16] = { 241862306a36Sopenharmony_ci 0x34,0x74,0xb4, 241962306a36Sopenharmony_ci 0x23,0x63,0xa3, 242062306a36Sopenharmony_ci 0x12,0x52,0x92, 242162306a36Sopenharmony_ci 0x01,0x41,0x81, 242262306a36Sopenharmony_ci 0x00,0x40,0x80, 242362306a36Sopenharmony_ci 0xff 242462306a36Sopenharmony_ci }; 242562306a36Sopenharmony_ci static const unsigned short colortharray[6] = { 242662306a36Sopenharmony_ci 1, 1, 2, 2, 3, 4 242762306a36Sopenharmony_ci }; 242862306a36Sopenharmony_ci 242962306a36Sopenharmony_ci i = 0; 243062306a36Sopenharmony_ci 243162306a36Sopenharmony_ci if (SiS_Pr->ChipType == SIS_730) 243262306a36Sopenharmony_ci queuedata = &FQBQData730[0]; 243362306a36Sopenharmony_ci else 243462306a36Sopenharmony_ci queuedata = &FQBQData[0]; 243562306a36Sopenharmony_ci 243662306a36Sopenharmony_ci if(ModeNo > 0x13) { 243762306a36Sopenharmony_ci 243862306a36Sopenharmony_ci /* Get VCLK */ 243962306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 244062306a36Sopenharmony_ci VCLK = SiS_Pr->CSRClock; 244162306a36Sopenharmony_ci } else { 244262306a36Sopenharmony_ci data = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWide); 244362306a36Sopenharmony_ci VCLK = SiS_Pr->SiS_VCLKData[data].CLOCK; 244462306a36Sopenharmony_ci } 244562306a36Sopenharmony_ci 244662306a36Sopenharmony_ci /* Get MCLK * 16 */ 244762306a36Sopenharmony_ci data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A) & 0x07; 244862306a36Sopenharmony_ci MCLK16 = SiS_Pr->SiS_MCLKData_0[data].CLOCK * 16; 244962306a36Sopenharmony_ci 245062306a36Sopenharmony_ci /* Get half colordepth */ 245162306a36Sopenharmony_ci colorth = colortharray[(SiS_Pr->SiS_ModeType - ModeEGA)]; 245262306a36Sopenharmony_ci 245362306a36Sopenharmony_ci do { 245462306a36Sopenharmony_ci templ = SiS_CalcDelay2(SiS_Pr, queuedata[i]) * VCLK * colorth; 245562306a36Sopenharmony_ci 245662306a36Sopenharmony_ci datal = templ % MCLK16; 245762306a36Sopenharmony_ci templ = (templ / MCLK16) + 1; 245862306a36Sopenharmony_ci if(datal) templ++; 245962306a36Sopenharmony_ci 246062306a36Sopenharmony_ci if(templ > 0x13) { 246162306a36Sopenharmony_ci if(queuedata[i + 1] == 0xFF) { 246262306a36Sopenharmony_ci ThresholdLow = 0x13; 246362306a36Sopenharmony_ci break; 246462306a36Sopenharmony_ci } 246562306a36Sopenharmony_ci i++; 246662306a36Sopenharmony_ci } else { 246762306a36Sopenharmony_ci ThresholdLow = templ; 246862306a36Sopenharmony_ci break; 246962306a36Sopenharmony_ci } 247062306a36Sopenharmony_ci } while(queuedata[i] != 0xFF); 247162306a36Sopenharmony_ci 247262306a36Sopenharmony_ci } else { 247362306a36Sopenharmony_ci 247462306a36Sopenharmony_ci if(SiS_Pr->ChipType != SIS_730) i = 9; 247562306a36Sopenharmony_ci ThresholdLow = 0x02; 247662306a36Sopenharmony_ci 247762306a36Sopenharmony_ci } 247862306a36Sopenharmony_ci 247962306a36Sopenharmony_ci /* Write CRT/CPU threshold low, CRT/Engine threshold high */ 248062306a36Sopenharmony_ci data = ((ThresholdLow & 0x0f) << 4) | 0x0f; 248162306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data); 248262306a36Sopenharmony_ci 248362306a36Sopenharmony_ci data = (ThresholdLow & 0x10) << 1; 248462306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data); 248562306a36Sopenharmony_ci 248662306a36Sopenharmony_ci /* What is this? */ 248762306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09); 248862306a36Sopenharmony_ci 248962306a36Sopenharmony_ci /* Write CRT/CPU threshold high (gap = 3) */ 249062306a36Sopenharmony_ci data = ThresholdLow + 3; 249162306a36Sopenharmony_ci if(data > 0x0f) data = 0x0f; 249262306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data); 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_ci /* Write foreground and background queue */ 249562306a36Sopenharmony_ci templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); 249662306a36Sopenharmony_ci 249762306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_730) { 249862306a36Sopenharmony_ci 249962306a36Sopenharmony_ci templ &= 0xfffff9ff; 250062306a36Sopenharmony_ci templ |= ((queuedata[i] & 0xc0) << 3); 250162306a36Sopenharmony_ci 250262306a36Sopenharmony_ci } else { 250362306a36Sopenharmony_ci 250462306a36Sopenharmony_ci templ &= 0xf0ffffff; 250562306a36Sopenharmony_ci if( (ModeNo <= 0x13) && 250662306a36Sopenharmony_ci (SiS_Pr->ChipType == SIS_630) && 250762306a36Sopenharmony_ci (SiS_Pr->ChipRevision >= 0x30) ) { 250862306a36Sopenharmony_ci templ |= 0x0b000000; 250962306a36Sopenharmony_ci } else { 251062306a36Sopenharmony_ci templ |= ((queuedata[i] & 0xf0) << 20); 251162306a36Sopenharmony_ci } 251262306a36Sopenharmony_ci 251362306a36Sopenharmony_ci } 251462306a36Sopenharmony_ci 251562306a36Sopenharmony_ci sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ); 251662306a36Sopenharmony_ci templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0); 251762306a36Sopenharmony_ci 251862306a36Sopenharmony_ci /* GUI grant timer (PCI config 0xA3) */ 251962306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_730) { 252062306a36Sopenharmony_ci 252162306a36Sopenharmony_ci templ &= 0x00ffffff; 252262306a36Sopenharmony_ci datal = queuedata[i] << 8; 252362306a36Sopenharmony_ci templ |= (((datal & 0x0f00) | ((datal & 0x3000) >> 8)) << 20); 252462306a36Sopenharmony_ci 252562306a36Sopenharmony_ci } else { 252662306a36Sopenharmony_ci 252762306a36Sopenharmony_ci templ &= 0xf0ffffff; 252862306a36Sopenharmony_ci templ |= ((queuedata[i] & 0x0f) << 24); 252962306a36Sopenharmony_ci 253062306a36Sopenharmony_ci } 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_ci sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ); 253362306a36Sopenharmony_ci} 253462306a36Sopenharmony_ci#endif /* CONFIG_FB_SIS_300 */ 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 253762306a36Sopenharmony_cistatic void 253862306a36Sopenharmony_ciSiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 253962306a36Sopenharmony_ci{ 254062306a36Sopenharmony_ci unsigned short modeflag; 254162306a36Sopenharmony_ci 254262306a36Sopenharmony_ci /* disable auto-threshold */ 254362306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE); 254462306a36Sopenharmony_ci 254562306a36Sopenharmony_ci modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 254662306a36Sopenharmony_ci 254762306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE); 254862306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0); 254962306a36Sopenharmony_ci if(ModeNo > 0x13) { 255062306a36Sopenharmony_ci if(SiS_Pr->ChipType >= XGI_20) { 255162306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 255262306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 255362306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_661) { 255462306a36Sopenharmony_ci if(!(modeflag & HalfDCLK)) { 255562306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 255662306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 255762306a36Sopenharmony_ci } 255862306a36Sopenharmony_ci } else { 255962306a36Sopenharmony_ci if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) { 256062306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34); 256162306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01); 256262306a36Sopenharmony_ci } 256362306a36Sopenharmony_ci } 256462306a36Sopenharmony_ci } 256562306a36Sopenharmony_ci} 256662306a36Sopenharmony_ci#endif 256762306a36Sopenharmony_ci 256862306a36Sopenharmony_ci/*********************************************/ 256962306a36Sopenharmony_ci/* MODE REGISTERS */ 257062306a36Sopenharmony_ci/*********************************************/ 257162306a36Sopenharmony_ci 257262306a36Sopenharmony_cistatic void 257362306a36Sopenharmony_ciSiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 257462306a36Sopenharmony_ci unsigned short RefreshRateTableIndex, unsigned short ModeIdIndex) 257562306a36Sopenharmony_ci{ 257662306a36Sopenharmony_ci unsigned short data = 0, VCLK = 0, index = 0; 257762306a36Sopenharmony_ci 257862306a36Sopenharmony_ci if(ModeNo > 0x13) { 257962306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 258062306a36Sopenharmony_ci VCLK = SiS_Pr->CSRClock; 258162306a36Sopenharmony_ci } else { 258262306a36Sopenharmony_ci index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 258362306a36Sopenharmony_ci VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 258462306a36Sopenharmony_ci } 258562306a36Sopenharmony_ci } 258662306a36Sopenharmony_ci 258762306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_315H) { 258862306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 258962306a36Sopenharmony_ci if(VCLK > 150) data |= 0x80; 259062306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data); 259162306a36Sopenharmony_ci 259262306a36Sopenharmony_ci data = 0x00; 259362306a36Sopenharmony_ci if(VCLK >= 150) data |= 0x08; 259462306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data); 259562306a36Sopenharmony_ci#endif 259662306a36Sopenharmony_ci } else if(SiS_Pr->ChipType < XGI_20) { 259762306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 259862306a36Sopenharmony_ci if(VCLK >= 166) data |= 0x0c; 259962306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); 260062306a36Sopenharmony_ci 260162306a36Sopenharmony_ci if(VCLK >= 166) { 260262306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7); 260362306a36Sopenharmony_ci } 260462306a36Sopenharmony_ci#endif 260562306a36Sopenharmony_ci } else { 260662306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 260762306a36Sopenharmony_ci if(VCLK >= 200) data |= 0x0c; 260862306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_20) data &= ~0x04; 260962306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data); 261062306a36Sopenharmony_ci if(SiS_Pr->ChipType != XGI_20) { 261162306a36Sopenharmony_ci data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xe7; 261262306a36Sopenharmony_ci if(VCLK < 200) data |= 0x10; 261362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,data); 261462306a36Sopenharmony_ci } 261562306a36Sopenharmony_ci#endif 261662306a36Sopenharmony_ci } 261762306a36Sopenharmony_ci 261862306a36Sopenharmony_ci /* DAC speed */ 261962306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_661) { 262062306a36Sopenharmony_ci 262162306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10); 262262306a36Sopenharmony_ci 262362306a36Sopenharmony_ci } else { 262462306a36Sopenharmony_ci 262562306a36Sopenharmony_ci data = 0x03; 262662306a36Sopenharmony_ci if(VCLK >= 260) data = 0x00; 262762306a36Sopenharmony_ci else if(VCLK >= 160) data = 0x01; 262862306a36Sopenharmony_ci else if(VCLK >= 135) data = 0x02; 262962306a36Sopenharmony_ci 263062306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_540) { 263162306a36Sopenharmony_ci /* Was == 203 or < 234 which made no sense */ 263262306a36Sopenharmony_ci if (VCLK < 234) data = 0x02; 263362306a36Sopenharmony_ci } 263462306a36Sopenharmony_ci 263562306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_315H) { 263662306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data); 263762306a36Sopenharmony_ci } else { 263862306a36Sopenharmony_ci if(SiS_Pr->ChipType > SIS_315PRO) { 263962306a36Sopenharmony_ci if(ModeNo > 0x13) data &= 0xfc; 264062306a36Sopenharmony_ci } 264162306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data); 264262306a36Sopenharmony_ci } 264362306a36Sopenharmony_ci 264462306a36Sopenharmony_ci } 264562306a36Sopenharmony_ci} 264662306a36Sopenharmony_ci 264762306a36Sopenharmony_cistatic void 264862306a36Sopenharmony_ciSiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 264962306a36Sopenharmony_ci unsigned short ModeIdIndex, unsigned short RRTI) 265062306a36Sopenharmony_ci{ 265162306a36Sopenharmony_ci unsigned short data, infoflag = 0, modeflag; 265262306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 265362306a36Sopenharmony_ci unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 265462306a36Sopenharmony_ci unsigned short data2, data3; 265562306a36Sopenharmony_ci#endif 265662306a36Sopenharmony_ci 265762306a36Sopenharmony_ci modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 265862306a36Sopenharmony_ci 265962306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 266062306a36Sopenharmony_ci infoflag = SiS_Pr->CInfoFlag; 266162306a36Sopenharmony_ci } else { 266262306a36Sopenharmony_ci if(ModeNo > 0x13) { 266362306a36Sopenharmony_ci infoflag = SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag; 266462306a36Sopenharmony_ci } 266562306a36Sopenharmony_ci } 266662306a36Sopenharmony_ci 266762306a36Sopenharmony_ci /* Disable DPMS */ 266862306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F); 266962306a36Sopenharmony_ci 267062306a36Sopenharmony_ci data = 0; 267162306a36Sopenharmony_ci if(ModeNo > 0x13) { 267262306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType > ModeEGA) { 267362306a36Sopenharmony_ci data |= 0x02; 267462306a36Sopenharmony_ci data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); 267562306a36Sopenharmony_ci } 267662306a36Sopenharmony_ci if(infoflag & InterlaceMode) data |= 0x20; 267762306a36Sopenharmony_ci } 267862306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data); 267962306a36Sopenharmony_ci 268062306a36Sopenharmony_ci if(SiS_Pr->ChipType != SIS_300) { 268162306a36Sopenharmony_ci data = 0; 268262306a36Sopenharmony_ci if(infoflag & InterlaceMode) { 268362306a36Sopenharmony_ci /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ 268462306a36Sopenharmony_ci int hrs = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x04) | 268562306a36Sopenharmony_ci ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2)) - 3; 268662306a36Sopenharmony_ci int hto = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x00) | 268762306a36Sopenharmony_ci ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0x03) << 8)) + 5; 268862306a36Sopenharmony_ci data = hrs - (hto >> 1) + 3; 268962306a36Sopenharmony_ci } 269062306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data); 269162306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,((data >> 8) & 0x03)); 269262306a36Sopenharmony_ci } 269362306a36Sopenharmony_ci 269462306a36Sopenharmony_ci if(modeflag & HalfDCLK) { 269562306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08); 269662306a36Sopenharmony_ci } 269762306a36Sopenharmony_ci 269862306a36Sopenharmony_ci data = 0; 269962306a36Sopenharmony_ci if(modeflag & LineCompareOff) data = 0x08; 270062306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_300) { 270162306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data); 270262306a36Sopenharmony_ci } else { 270362306a36Sopenharmony_ci if(SiS_Pr->ChipType >= XGI_20) data |= 0x20; 270462306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType == ModeEGA) { 270562306a36Sopenharmony_ci if(ModeNo > 0x13) { 270662306a36Sopenharmony_ci data |= 0x40; 270762306a36Sopenharmony_ci } 270862306a36Sopenharmony_ci } 270962306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data); 271062306a36Sopenharmony_ci } 271162306a36Sopenharmony_ci 271262306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 271362306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 271462306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb); 271562306a36Sopenharmony_ci } 271662306a36Sopenharmony_ci 271762306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_315PRO) { 271862306a36Sopenharmony_ci 271962306a36Sopenharmony_ci data = SiS_Pr->SiS_SR15[(2 * 4) + SiS_Get310DRAMType(SiS_Pr)]; 272062306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType == ModeText) { 272162306a36Sopenharmony_ci data &= 0xc7; 272262306a36Sopenharmony_ci } else { 272362306a36Sopenharmony_ci data2 = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RRTI) >> 1; 272462306a36Sopenharmony_ci if(infoflag & InterlaceMode) data2 >>= 1; 272562306a36Sopenharmony_ci data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1; 272662306a36Sopenharmony_ci if(data3) data2 /= data3; 272762306a36Sopenharmony_ci if(data2 >= 0x50) { 272862306a36Sopenharmony_ci data &= 0x0f; 272962306a36Sopenharmony_ci data |= 0x50; 273062306a36Sopenharmony_ci } 273162306a36Sopenharmony_ci } 273262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data); 273362306a36Sopenharmony_ci 273462306a36Sopenharmony_ci } else if((SiS_Pr->ChipType == SIS_330) || (SiS_Pr->SiS_SysFlags & SF_760LFB)) { 273562306a36Sopenharmony_ci 273662306a36Sopenharmony_ci data = SiS_Get310DRAMType(SiS_Pr); 273762306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_330) { 273862306a36Sopenharmony_ci data = SiS_Pr->SiS_SR15[(2 * 4) + data]; 273962306a36Sopenharmony_ci } else { 274062306a36Sopenharmony_ci if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6]; 274162306a36Sopenharmony_ci else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data]; 274262306a36Sopenharmony_ci else data = 0xba; 274362306a36Sopenharmony_ci } 274462306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType <= ModeEGA) { 274562306a36Sopenharmony_ci data &= 0xc7; 274662306a36Sopenharmony_ci } else { 274762306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 274862306a36Sopenharmony_ci data2 = SiS_Pr->CSRClock; 274962306a36Sopenharmony_ci } else { 275062306a36Sopenharmony_ci data2 = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 275162306a36Sopenharmony_ci data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK; 275262306a36Sopenharmony_ci } 275362306a36Sopenharmony_ci 275462306a36Sopenharmony_ci data3 = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex) >> 1; 275562306a36Sopenharmony_ci if(data3) data2 *= data3; 275662306a36Sopenharmony_ci 275762306a36Sopenharmony_ci data2 = ((unsigned int)(SiS_GetMCLK(SiS_Pr) * 1024)) / data2; 275862306a36Sopenharmony_ci 275962306a36Sopenharmony_ci if(SiS_Pr->ChipType == SIS_330) { 276062306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType != Mode16Bpp) { 276162306a36Sopenharmony_ci if (data2 >= 0x19c) data = 0xba; 276262306a36Sopenharmony_ci else if(data2 >= 0x140) data = 0x7a; 276362306a36Sopenharmony_ci else if(data2 >= 0x101) data = 0x3a; 276462306a36Sopenharmony_ci else if(data2 >= 0xf5) data = 0x32; 276562306a36Sopenharmony_ci else if(data2 >= 0xe2) data = 0x2a; 276662306a36Sopenharmony_ci else if(data2 >= 0xc4) data = 0x22; 276762306a36Sopenharmony_ci else if(data2 >= 0xac) data = 0x1a; 276862306a36Sopenharmony_ci else if(data2 >= 0x9e) data = 0x12; 276962306a36Sopenharmony_ci else if(data2 >= 0x8e) data = 0x0a; 277062306a36Sopenharmony_ci else data = 0x02; 277162306a36Sopenharmony_ci } else { 277262306a36Sopenharmony_ci if(data2 >= 0x127) data = 0xba; 277362306a36Sopenharmony_ci else data = 0x7a; 277462306a36Sopenharmony_ci } 277562306a36Sopenharmony_ci } else { /* 76x+LFB */ 277662306a36Sopenharmony_ci if (data2 >= 0x190) data = 0xba; 277762306a36Sopenharmony_ci else if(data2 >= 0xff) data = 0x7a; 277862306a36Sopenharmony_ci else if(data2 >= 0xd3) data = 0x3a; 277962306a36Sopenharmony_ci else if(data2 >= 0xa9) data = 0x1a; 278062306a36Sopenharmony_ci else if(data2 >= 0x93) data = 0x0a; 278162306a36Sopenharmony_ci else data = 0x02; 278262306a36Sopenharmony_ci } 278362306a36Sopenharmony_ci } 278462306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data); 278562306a36Sopenharmony_ci 278662306a36Sopenharmony_ci } 278762306a36Sopenharmony_ci /* XGI: Nothing. */ 278862306a36Sopenharmony_ci /* TODO: Check SiS340 */ 278962306a36Sopenharmony_ci#endif 279062306a36Sopenharmony_ci 279162306a36Sopenharmony_ci data = 0x60; 279262306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType != ModeText) { 279362306a36Sopenharmony_ci data ^= 0x60; 279462306a36Sopenharmony_ci if(SiS_Pr->SiS_ModeType != ModeEGA) { 279562306a36Sopenharmony_ci data ^= 0xA0; 279662306a36Sopenharmony_ci } 279762306a36Sopenharmony_ci } 279862306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data); 279962306a36Sopenharmony_ci 280062306a36Sopenharmony_ci SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex); 280162306a36Sopenharmony_ci 280262306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 280362306a36Sopenharmony_ci if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) || 280462306a36Sopenharmony_ci (SiS_Pr->ChipType == XGI_40)) { 280562306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { 280662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c); 280762306a36Sopenharmony_ci } else { 280862306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c); 280962306a36Sopenharmony_ci } 281062306a36Sopenharmony_ci } else if(SiS_Pr->ChipType == XGI_20) { 281162306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { 281262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x33); 281362306a36Sopenharmony_ci } else { 281462306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x73); 281562306a36Sopenharmony_ci } 281662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x51,0x02); 281762306a36Sopenharmony_ci } 281862306a36Sopenharmony_ci#endif 281962306a36Sopenharmony_ci} 282062306a36Sopenharmony_ci 282162306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 282262306a36Sopenharmony_cistatic void 282362306a36Sopenharmony_ciSiS_SetupDualChip(struct SiS_Private *SiS_Pr) 282462306a36Sopenharmony_ci{ 282562306a36Sopenharmony_ci#if 0 282662306a36Sopenharmony_ci /* TODO: Find out about IOAddress2 */ 282762306a36Sopenharmony_ci SISIOADDRESS P2_3c2 = SiS_Pr->IOAddress2 + 0x12; 282862306a36Sopenharmony_ci SISIOADDRESS P2_3c4 = SiS_Pr->IOAddress2 + 0x14; 282962306a36Sopenharmony_ci SISIOADDRESS P2_3ce = SiS_Pr->IOAddress2 + 0x1e; 283062306a36Sopenharmony_ci int i; 283162306a36Sopenharmony_ci 283262306a36Sopenharmony_ci if((SiS_Pr->ChipRevision != 0) || 283362306a36Sopenharmony_ci (!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x04))) 283462306a36Sopenharmony_ci return; 283562306a36Sopenharmony_ci 283662306a36Sopenharmony_ci for(i = 0; i <= 4; i++) { /* SR00 - SR04 */ 283762306a36Sopenharmony_ci SiS_SetReg(P2_3c4,i,SiS_GetReg(SiS_Pr->SiS_P3c4,i)); 283862306a36Sopenharmony_ci } 283962306a36Sopenharmony_ci for(i = 0; i <= 8; i++) { /* GR00 - GR08 */ 284062306a36Sopenharmony_ci SiS_SetReg(P2_3ce,i,SiS_GetReg(SiS_Pr->SiS_P3ce,i)); 284162306a36Sopenharmony_ci } 284262306a36Sopenharmony_ci SiS_SetReg(P2_3c4,0x05,0x86); 284362306a36Sopenharmony_ci SiS_SetReg(P2_3c4,0x06,SiS_GetReg(SiS_Pr->SiS_P3c4,0x06)); /* SR06 */ 284462306a36Sopenharmony_ci SiS_SetReg(P2_3c4,0x21,SiS_GetReg(SiS_Pr->SiS_P3c4,0x21)); /* SR21 */ 284562306a36Sopenharmony_ci SiS_SetRegByte(P2_3c2,SiS_GetRegByte(SiS_Pr->SiS_P3cc)); /* MISC */ 284662306a36Sopenharmony_ci SiS_SetReg(P2_3c4,0x05,0x00); 284762306a36Sopenharmony_ci#endif 284862306a36Sopenharmony_ci} 284962306a36Sopenharmony_ci#endif 285062306a36Sopenharmony_ci 285162306a36Sopenharmony_ci/*********************************************/ 285262306a36Sopenharmony_ci/* LOAD DAC */ 285362306a36Sopenharmony_ci/*********************************************/ 285462306a36Sopenharmony_ci 285562306a36Sopenharmony_cistatic void 285662306a36Sopenharmony_ciSiS_WriteDAC(struct SiS_Private *SiS_Pr, SISIOADDRESS DACData, unsigned short shiftflag, 285762306a36Sopenharmony_ci unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh) 285862306a36Sopenharmony_ci{ 285962306a36Sopenharmony_ci unsigned short d1, d2, d3; 286062306a36Sopenharmony_ci 286162306a36Sopenharmony_ci switch(dl) { 286262306a36Sopenharmony_ci case 0: d1 = dh; d2 = ah; d3 = al; break; 286362306a36Sopenharmony_ci case 1: d1 = ah; d2 = al; d3 = dh; break; 286462306a36Sopenharmony_ci default: d1 = al; d2 = dh; d3 = ah; 286562306a36Sopenharmony_ci } 286662306a36Sopenharmony_ci SiS_SetRegByte(DACData, (d1 << shiftflag)); 286762306a36Sopenharmony_ci SiS_SetRegByte(DACData, (d2 << shiftflag)); 286862306a36Sopenharmony_ci SiS_SetRegByte(DACData, (d3 << shiftflag)); 286962306a36Sopenharmony_ci} 287062306a36Sopenharmony_ci 287162306a36Sopenharmony_civoid 287262306a36Sopenharmony_ciSiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 287362306a36Sopenharmony_ci{ 287462306a36Sopenharmony_ci unsigned short data, data2, time, i, j, k, m, n, o; 287562306a36Sopenharmony_ci unsigned short si, di, bx, sf; 287662306a36Sopenharmony_ci SISIOADDRESS DACAddr, DACData; 287762306a36Sopenharmony_ci const unsigned char *table = NULL; 287862306a36Sopenharmony_ci 287962306a36Sopenharmony_ci data = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex) & DACInfoFlag; 288062306a36Sopenharmony_ci 288162306a36Sopenharmony_ci j = time = 64; 288262306a36Sopenharmony_ci if(data == 0x00) table = SiS_MDA_DAC; 288362306a36Sopenharmony_ci else if(data == 0x08) table = SiS_CGA_DAC; 288462306a36Sopenharmony_ci else if(data == 0x10) table = SiS_EGA_DAC; 288562306a36Sopenharmony_ci else if(data == 0x18) { 288662306a36Sopenharmony_ci j = 16; 288762306a36Sopenharmony_ci time = 256; 288862306a36Sopenharmony_ci table = SiS_VGA_DAC; 288962306a36Sopenharmony_ci } 289062306a36Sopenharmony_ci 289162306a36Sopenharmony_ci if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */ 289262306a36Sopenharmony_ci (SiS_Pr->SiS_VBType & VB_NoLCD) ) || 289362306a36Sopenharmony_ci (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) || /* LCDA */ 289462306a36Sopenharmony_ci (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */ 289562306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 289662306a36Sopenharmony_ci DACAddr = SiS_Pr->SiS_P3c8; 289762306a36Sopenharmony_ci DACData = SiS_Pr->SiS_P3c9; 289862306a36Sopenharmony_ci sf = 0; 289962306a36Sopenharmony_ci } else { 290062306a36Sopenharmony_ci DACAddr = SiS_Pr->SiS_Part5Port; 290162306a36Sopenharmony_ci DACData = SiS_Pr->SiS_Part5Port + 1; 290262306a36Sopenharmony_ci sf = 2; 290362306a36Sopenharmony_ci } 290462306a36Sopenharmony_ci 290562306a36Sopenharmony_ci SiS_SetRegByte(DACAddr,0x00); 290662306a36Sopenharmony_ci 290762306a36Sopenharmony_ci for(i = 0; i < j; i++) { 290862306a36Sopenharmony_ci data = table[i]; 290962306a36Sopenharmony_ci for(k = 0; k < 3; k++) { 291062306a36Sopenharmony_ci data2 = 0; 291162306a36Sopenharmony_ci if(data & 0x01) data2 += 0x2A; 291262306a36Sopenharmony_ci if(data & 0x02) data2 += 0x15; 291362306a36Sopenharmony_ci SiS_SetRegByte(DACData, (data2 << sf)); 291462306a36Sopenharmony_ci data >>= 2; 291562306a36Sopenharmony_ci } 291662306a36Sopenharmony_ci } 291762306a36Sopenharmony_ci 291862306a36Sopenharmony_ci if(time == 256) { 291962306a36Sopenharmony_ci for(i = 16; i < 32; i++) { 292062306a36Sopenharmony_ci data = table[i] << sf; 292162306a36Sopenharmony_ci for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data); 292262306a36Sopenharmony_ci } 292362306a36Sopenharmony_ci si = 32; 292462306a36Sopenharmony_ci for(m = 0; m < 9; m++) { 292562306a36Sopenharmony_ci di = si; 292662306a36Sopenharmony_ci bx = si + 4; 292762306a36Sopenharmony_ci for(n = 0; n < 3; n++) { 292862306a36Sopenharmony_ci for(o = 0; o < 5; o++) { 292962306a36Sopenharmony_ci SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[bx], table[si]); 293062306a36Sopenharmony_ci si++; 293162306a36Sopenharmony_ci } 293262306a36Sopenharmony_ci si -= 2; 293362306a36Sopenharmony_ci for(o = 0; o < 3; o++) { 293462306a36Sopenharmony_ci SiS_WriteDAC(SiS_Pr, DACData, sf, n, table[di], table[si], table[bx]); 293562306a36Sopenharmony_ci si--; 293662306a36Sopenharmony_ci } 293762306a36Sopenharmony_ci } /* for n < 3 */ 293862306a36Sopenharmony_ci si += 5; 293962306a36Sopenharmony_ci } /* for m < 9 */ 294062306a36Sopenharmony_ci } 294162306a36Sopenharmony_ci} 294262306a36Sopenharmony_ci 294362306a36Sopenharmony_ci/*********************************************/ 294462306a36Sopenharmony_ci/* SET CRT1 REGISTER GROUP */ 294562306a36Sopenharmony_ci/*********************************************/ 294662306a36Sopenharmony_ci 294762306a36Sopenharmony_cistatic void 294862306a36Sopenharmony_ciSiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 294962306a36Sopenharmony_ci{ 295062306a36Sopenharmony_ci unsigned short StandTableIndex, RefreshRateTableIndex; 295162306a36Sopenharmony_ci 295262306a36Sopenharmony_ci SiS_Pr->SiS_CRT1Mode = ModeNo; 295362306a36Sopenharmony_ci 295462306a36Sopenharmony_ci StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex); 295562306a36Sopenharmony_ci 295662306a36Sopenharmony_ci if(SiS_Pr->SiS_SetFlag & LowModeTests) { 295762306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) { 295862306a36Sopenharmony_ci SiS_DisableBridge(SiS_Pr); 295962306a36Sopenharmony_ci } 296062306a36Sopenharmony_ci } 296162306a36Sopenharmony_ci 296262306a36Sopenharmony_ci SiS_ResetSegmentRegisters(SiS_Pr); 296362306a36Sopenharmony_ci 296462306a36Sopenharmony_ci SiS_SetSeqRegs(SiS_Pr, StandTableIndex); 296562306a36Sopenharmony_ci SiS_SetMiscRegs(SiS_Pr, StandTableIndex); 296662306a36Sopenharmony_ci SiS_SetCRTCRegs(SiS_Pr, StandTableIndex); 296762306a36Sopenharmony_ci SiS_SetATTRegs(SiS_Pr, StandTableIndex); 296862306a36Sopenharmony_ci SiS_SetGRCRegs(SiS_Pr, StandTableIndex); 296962306a36Sopenharmony_ci SiS_ClearExt1Regs(SiS_Pr, ModeNo); 297062306a36Sopenharmony_ci SiS_ResetCRT1VCLK(SiS_Pr); 297162306a36Sopenharmony_ci 297262306a36Sopenharmony_ci SiS_Pr->SiS_SelectCRT2Rate = 0; 297362306a36Sopenharmony_ci SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 297462306a36Sopenharmony_ci 297562306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { 297662306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 297762306a36Sopenharmony_ci SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 297862306a36Sopenharmony_ci } 297962306a36Sopenharmony_ci } 298062306a36Sopenharmony_ci 298162306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 298262306a36Sopenharmony_ci SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 298362306a36Sopenharmony_ci } 298462306a36Sopenharmony_ci 298562306a36Sopenharmony_ci RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex); 298662306a36Sopenharmony_ci 298762306a36Sopenharmony_ci if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 298862306a36Sopenharmony_ci SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2; 298962306a36Sopenharmony_ci } 299062306a36Sopenharmony_ci 299162306a36Sopenharmony_ci if(RefreshRateTableIndex != 0xFFFF) { 299262306a36Sopenharmony_ci SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex); 299362306a36Sopenharmony_ci SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 299462306a36Sopenharmony_ci SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 299562306a36Sopenharmony_ci SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 299662306a36Sopenharmony_ci } 299762306a36Sopenharmony_ci 299862306a36Sopenharmony_ci switch(SiS_Pr->ChipType) { 299962306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 300062306a36Sopenharmony_ci case SIS_300: 300162306a36Sopenharmony_ci SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex); 300262306a36Sopenharmony_ci break; 300362306a36Sopenharmony_ci case SIS_540: 300462306a36Sopenharmony_ci case SIS_630: 300562306a36Sopenharmony_ci case SIS_730: 300662306a36Sopenharmony_ci SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, RefreshRateTableIndex); 300762306a36Sopenharmony_ci break; 300862306a36Sopenharmony_ci#endif 300962306a36Sopenharmony_ci default: 301062306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 301162306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_20) { 301262306a36Sopenharmony_ci unsigned char sr2b = 0, sr2c = 0; 301362306a36Sopenharmony_ci switch(ModeNo) { 301462306a36Sopenharmony_ci case 0x00: 301562306a36Sopenharmony_ci case 0x01: sr2b = 0x4e; sr2c = 0xe9; break; 301662306a36Sopenharmony_ci case 0x04: 301762306a36Sopenharmony_ci case 0x05: 301862306a36Sopenharmony_ci case 0x0d: sr2b = 0x1b; sr2c = 0xe3; break; 301962306a36Sopenharmony_ci } 302062306a36Sopenharmony_ci if(sr2b) { 302162306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2b,sr2b); 302262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,sr2c); 302362306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c2,(SiS_GetRegByte(SiS_Pr->SiS_P3cc) | 0x0c)); 302462306a36Sopenharmony_ci } 302562306a36Sopenharmony_ci } 302662306a36Sopenharmony_ci SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex); 302762306a36Sopenharmony_ci#endif 302862306a36Sopenharmony_ci break; 302962306a36Sopenharmony_ci } 303062306a36Sopenharmony_ci 303162306a36Sopenharmony_ci SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 303262306a36Sopenharmony_ci 303362306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 303462306a36Sopenharmony_ci if(SiS_Pr->ChipType == XGI_40) { 303562306a36Sopenharmony_ci SiS_SetupDualChip(SiS_Pr); 303662306a36Sopenharmony_ci } 303762306a36Sopenharmony_ci#endif 303862306a36Sopenharmony_ci 303962306a36Sopenharmony_ci SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); 304062306a36Sopenharmony_ci 304162306a36Sopenharmony_ci if(SiS_Pr->SiS_flag_clearbuffer) { 304262306a36Sopenharmony_ci SiS_ClearBuffer(SiS_Pr, ModeNo); 304362306a36Sopenharmony_ci } 304462306a36Sopenharmony_ci 304562306a36Sopenharmony_ci if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) { 304662306a36Sopenharmony_ci SiS_WaitRetrace1(SiS_Pr); 304762306a36Sopenharmony_ci SiS_DisplayOn(SiS_Pr); 304862306a36Sopenharmony_ci } 304962306a36Sopenharmony_ci} 305062306a36Sopenharmony_ci 305162306a36Sopenharmony_ci/*********************************************/ 305262306a36Sopenharmony_ci/* HELPER: VIDEO BRIDGE PROG CLK */ 305362306a36Sopenharmony_ci/*********************************************/ 305462306a36Sopenharmony_ci 305562306a36Sopenharmony_cistatic void 305662306a36Sopenharmony_ciSiS_InitVB(struct SiS_Private *SiS_Pr) 305762306a36Sopenharmony_ci{ 305862306a36Sopenharmony_ci unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 305962306a36Sopenharmony_ci 306062306a36Sopenharmony_ci SiS_Pr->Init_P4_0E = 0; 306162306a36Sopenharmony_ci if(SiS_Pr->SiS_ROMNew) { 306262306a36Sopenharmony_ci SiS_Pr->Init_P4_0E = ROMAddr[0x82]; 306362306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= XGI_40) { 306462306a36Sopenharmony_ci if(SiS_Pr->SiS_XGIROM) { 306562306a36Sopenharmony_ci SiS_Pr->Init_P4_0E = ROMAddr[0x80]; 306662306a36Sopenharmony_ci } 306762306a36Sopenharmony_ci } 306862306a36Sopenharmony_ci} 306962306a36Sopenharmony_ci 307062306a36Sopenharmony_cistatic void 307162306a36Sopenharmony_ciSiS_ResetVB(struct SiS_Private *SiS_Pr) 307262306a36Sopenharmony_ci{ 307362306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 307462306a36Sopenharmony_ci unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 307562306a36Sopenharmony_ci unsigned short temp; 307662306a36Sopenharmony_ci 307762306a36Sopenharmony_ci /* VB programming clock */ 307862306a36Sopenharmony_ci if(SiS_Pr->SiS_UseROM) { 307962306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_330) { 308062306a36Sopenharmony_ci temp = ROMAddr[VB310Data_1_2_Offset] | 0x40; 308162306a36Sopenharmony_ci if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40; 308262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 308362306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= SIS_661 && SiS_Pr->ChipType < XGI_20) { 308462306a36Sopenharmony_ci temp = ROMAddr[0x7e] | 0x40; 308562306a36Sopenharmony_ci if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40; 308662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 308762306a36Sopenharmony_ci } 308862306a36Sopenharmony_ci } else if(SiS_Pr->ChipType >= XGI_40) { 308962306a36Sopenharmony_ci temp = 0x40; 309062306a36Sopenharmony_ci if(SiS_Pr->SiS_XGIROM) temp |= ROMAddr[0x7e]; 309162306a36Sopenharmony_ci /* Can we do this on any chipset? */ 309262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp); 309362306a36Sopenharmony_ci } 309462306a36Sopenharmony_ci#endif 309562306a36Sopenharmony_ci} 309662306a36Sopenharmony_ci 309762306a36Sopenharmony_ci/*********************************************/ 309862306a36Sopenharmony_ci/* HELPER: SET VIDEO/CAPTURE REGISTERS */ 309962306a36Sopenharmony_ci/*********************************************/ 310062306a36Sopenharmony_ci 310162306a36Sopenharmony_cistatic void 310262306a36Sopenharmony_ciSiS_StrangeStuff(struct SiS_Private *SiS_Pr) 310362306a36Sopenharmony_ci{ 310462306a36Sopenharmony_ci /* SiS65x and XGI set up some sort of "lock mode" for text 310562306a36Sopenharmony_ci * which locks CRT2 in some way to CRT1 timing. Disable 310662306a36Sopenharmony_ci * this here. 310762306a36Sopenharmony_ci */ 310862306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 310962306a36Sopenharmony_ci if((IS_SIS651) || (IS_SISM650) || 311062306a36Sopenharmony_ci SiS_Pr->ChipType == SIS_340 || 311162306a36Sopenharmony_ci SiS_Pr->ChipType == XGI_40) { 311262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00); /* Fiddle with capture regs */ 311362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00); 311462306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86); /* (BIOS does NOT unlock) */ 311562306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */ 311662306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef); 311762306a36Sopenharmony_ci } 311862306a36Sopenharmony_ci /* !!! This does not support modes < 0x13 !!! */ 311962306a36Sopenharmony_ci#endif 312062306a36Sopenharmony_ci} 312162306a36Sopenharmony_ci 312262306a36Sopenharmony_ci/*********************************************/ 312362306a36Sopenharmony_ci/* HELPER: SET AGP TIMING FOR SiS760 */ 312462306a36Sopenharmony_ci/*********************************************/ 312562306a36Sopenharmony_ci 312662306a36Sopenharmony_cistatic void 312762306a36Sopenharmony_ciSiS_Handle760(struct SiS_Private *SiS_Pr) 312862306a36Sopenharmony_ci{ 312962306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 313062306a36Sopenharmony_ci unsigned int somebase; 313162306a36Sopenharmony_ci unsigned char temp1, temp2, temp3; 313262306a36Sopenharmony_ci 313362306a36Sopenharmony_ci if( (SiS_Pr->ChipType != SIS_760) || 313462306a36Sopenharmony_ci ((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5c) & 0xf8) != 0x80) || 313562306a36Sopenharmony_ci (!(SiS_Pr->SiS_SysFlags & SF_760LFB)) || 313662306a36Sopenharmony_ci (!(SiS_Pr->SiS_SysFlags & SF_760UMA)) ) 313762306a36Sopenharmony_ci return; 313862306a36Sopenharmony_ci 313962306a36Sopenharmony_ci somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74); 314062306a36Sopenharmony_ci somebase &= 0xffff; 314162306a36Sopenharmony_ci 314262306a36Sopenharmony_ci if(somebase == 0) return; 314362306a36Sopenharmony_ci 314462306a36Sopenharmony_ci temp3 = SiS_GetRegByte((somebase + 0x85)) & 0xb7; 314562306a36Sopenharmony_ci 314662306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) { 314762306a36Sopenharmony_ci temp1 = 0x21; 314862306a36Sopenharmony_ci temp2 = 0x03; 314962306a36Sopenharmony_ci temp3 |= 0x08; 315062306a36Sopenharmony_ci } else { 315162306a36Sopenharmony_ci temp1 = 0x25; 315262306a36Sopenharmony_ci temp2 = 0x0b; 315362306a36Sopenharmony_ci } 315462306a36Sopenharmony_ci 315562306a36Sopenharmony_ci sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1); 315662306a36Sopenharmony_ci sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2); 315762306a36Sopenharmony_ci 315862306a36Sopenharmony_ci SiS_SetRegByte((somebase + 0x85), temp3); 315962306a36Sopenharmony_ci#endif 316062306a36Sopenharmony_ci} 316162306a36Sopenharmony_ci 316262306a36Sopenharmony_ci/*********************************************/ 316362306a36Sopenharmony_ci/* SiSSetMode() */ 316462306a36Sopenharmony_ci/*********************************************/ 316562306a36Sopenharmony_ci 316662306a36Sopenharmony_cibool 316762306a36Sopenharmony_ciSiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 316862306a36Sopenharmony_ci{ 316962306a36Sopenharmony_ci SISIOADDRESS BaseAddr = SiS_Pr->IOAddress; 317062306a36Sopenharmony_ci unsigned short RealModeNo, ModeIdIndex; 317162306a36Sopenharmony_ci unsigned char backupreg = 0; 317262306a36Sopenharmony_ci unsigned short KeepLockReg; 317362306a36Sopenharmony_ci 317462306a36Sopenharmony_ci SiS_Pr->UseCustomMode = false; 317562306a36Sopenharmony_ci SiS_Pr->CRT1UsesCustomMode = false; 317662306a36Sopenharmony_ci 317762306a36Sopenharmony_ci SiS_Pr->SiS_flag_clearbuffer = 0; 317862306a36Sopenharmony_ci 317962306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 318062306a36Sopenharmony_ci ModeNo = 0xfe; 318162306a36Sopenharmony_ci } else { 318262306a36Sopenharmony_ci if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1; 318362306a36Sopenharmony_ci ModeNo &= 0x7f; 318462306a36Sopenharmony_ci } 318562306a36Sopenharmony_ci 318662306a36Sopenharmony_ci /* Don't use FSTN mode for CRT1 */ 318762306a36Sopenharmony_ci RealModeNo = ModeNo; 318862306a36Sopenharmony_ci if(ModeNo == 0x5b) ModeNo = 0x56; 318962306a36Sopenharmony_ci 319062306a36Sopenharmony_ci SiSInitPtr(SiS_Pr); 319162306a36Sopenharmony_ci SiSRegInit(SiS_Pr, BaseAddr); 319262306a36Sopenharmony_ci SiS_GetSysFlags(SiS_Pr); 319362306a36Sopenharmony_ci 319462306a36Sopenharmony_ci SiS_Pr->SiS_VGAINFO = 0x11; 319562306a36Sopenharmony_ci 319662306a36Sopenharmony_ci KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05); 319762306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86); 319862306a36Sopenharmony_ci 319962306a36Sopenharmony_ci SiSInitPCIetc(SiS_Pr); 320062306a36Sopenharmony_ci SiSSetLVDSetc(SiS_Pr); 320162306a36Sopenharmony_ci SiSDetermineROMUsage(SiS_Pr); 320262306a36Sopenharmony_ci 320362306a36Sopenharmony_ci SiS_UnLockCRT2(SiS_Pr); 320462306a36Sopenharmony_ci 320562306a36Sopenharmony_ci if(!SiS_Pr->UseCustomMode) { 320662306a36Sopenharmony_ci if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false; 320762306a36Sopenharmony_ci } else { 320862306a36Sopenharmony_ci ModeIdIndex = 0; 320962306a36Sopenharmony_ci } 321062306a36Sopenharmony_ci 321162306a36Sopenharmony_ci SiS_GetVBType(SiS_Pr); 321262306a36Sopenharmony_ci 321362306a36Sopenharmony_ci /* Init/restore some VB registers */ 321462306a36Sopenharmony_ci SiS_InitVB(SiS_Pr); 321562306a36Sopenharmony_ci if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 321662306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 321762306a36Sopenharmony_ci SiS_ResetVB(SiS_Pr); 321862306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10); 321962306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c); 322062306a36Sopenharmony_ci backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 322162306a36Sopenharmony_ci } else { 322262306a36Sopenharmony_ci backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 322362306a36Sopenharmony_ci } 322462306a36Sopenharmony_ci } 322562306a36Sopenharmony_ci 322662306a36Sopenharmony_ci /* Get VB information (connectors, connected devices) */ 322762306a36Sopenharmony_ci SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, (SiS_Pr->UseCustomMode) ? 0 : 1); 322862306a36Sopenharmony_ci SiS_SetYPbPr(SiS_Pr); 322962306a36Sopenharmony_ci SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex); 323062306a36Sopenharmony_ci SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex); 323162306a36Sopenharmony_ci SiS_SetLowModeTest(SiS_Pr, ModeNo); 323262306a36Sopenharmony_ci 323362306a36Sopenharmony_ci /* Check memory size (kernel framebuffer driver only) */ 323462306a36Sopenharmony_ci if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) { 323562306a36Sopenharmony_ci return false; 323662306a36Sopenharmony_ci } 323762306a36Sopenharmony_ci 323862306a36Sopenharmony_ci SiS_OpenCRTC(SiS_Pr); 323962306a36Sopenharmony_ci 324062306a36Sopenharmony_ci if(SiS_Pr->UseCustomMode) { 324162306a36Sopenharmony_ci SiS_Pr->CRT1UsesCustomMode = true; 324262306a36Sopenharmony_ci SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock; 324362306a36Sopenharmony_ci SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag; 324462306a36Sopenharmony_ci } else { 324562306a36Sopenharmony_ci SiS_Pr->CRT1UsesCustomMode = false; 324662306a36Sopenharmony_ci } 324762306a36Sopenharmony_ci 324862306a36Sopenharmony_ci /* Set mode on CRT1 */ 324962306a36Sopenharmony_ci if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) || 325062306a36Sopenharmony_ci (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) { 325162306a36Sopenharmony_ci SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex); 325262306a36Sopenharmony_ci } 325362306a36Sopenharmony_ci 325462306a36Sopenharmony_ci /* Set mode on CRT2 */ 325562306a36Sopenharmony_ci if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) { 325662306a36Sopenharmony_ci if( (SiS_Pr->SiS_VBType & VB_SISVB) || 325762306a36Sopenharmony_ci (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 325862306a36Sopenharmony_ci (SiS_Pr->SiS_IF_DEF_CH70xx != 0) || 325962306a36Sopenharmony_ci (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) { 326062306a36Sopenharmony_ci SiS_SetCRT2Group(SiS_Pr, RealModeNo); 326162306a36Sopenharmony_ci } 326262306a36Sopenharmony_ci } 326362306a36Sopenharmony_ci 326462306a36Sopenharmony_ci SiS_HandleCRT1(SiS_Pr); 326562306a36Sopenharmony_ci 326662306a36Sopenharmony_ci SiS_StrangeStuff(SiS_Pr); 326762306a36Sopenharmony_ci 326862306a36Sopenharmony_ci SiS_DisplayOn(SiS_Pr); 326962306a36Sopenharmony_ci SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF); 327062306a36Sopenharmony_ci 327162306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 327262306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 327362306a36Sopenharmony_ci if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 327462306a36Sopenharmony_ci if(!(SiS_IsDualEdge(SiS_Pr))) { 327562306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 327662306a36Sopenharmony_ci } 327762306a36Sopenharmony_ci } 327862306a36Sopenharmony_ci } 327962306a36Sopenharmony_ci#endif 328062306a36Sopenharmony_ci 328162306a36Sopenharmony_ci if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 328262306a36Sopenharmony_ci if(SiS_Pr->ChipType >= SIS_315H) { 328362306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 328462306a36Sopenharmony_ci if(!SiS_Pr->SiS_ROMNew) { 328562306a36Sopenharmony_ci if(SiS_IsVAMode(SiS_Pr)) { 328662306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); 328762306a36Sopenharmony_ci } else { 328862306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE); 328962306a36Sopenharmony_ci } 329062306a36Sopenharmony_ci } 329162306a36Sopenharmony_ci 329262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg); 329362306a36Sopenharmony_ci 329462306a36Sopenharmony_ci if((IS_SIS650) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) { 329562306a36Sopenharmony_ci if((ModeNo == 0x03) || (ModeNo == 0x10)) { 329662306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80); 329762306a36Sopenharmony_ci SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08); 329862306a36Sopenharmony_ci } 329962306a36Sopenharmony_ci } 330062306a36Sopenharmony_ci 330162306a36Sopenharmony_ci if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) { 330262306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 330362306a36Sopenharmony_ci } 330462306a36Sopenharmony_ci#endif 330562306a36Sopenharmony_ci } else if((SiS_Pr->ChipType == SIS_630) || 330662306a36Sopenharmony_ci (SiS_Pr->ChipType == SIS_730)) { 330762306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg); 330862306a36Sopenharmony_ci } 330962306a36Sopenharmony_ci } 331062306a36Sopenharmony_ci 331162306a36Sopenharmony_ci SiS_CloseCRTC(SiS_Pr); 331262306a36Sopenharmony_ci 331362306a36Sopenharmony_ci SiS_Handle760(SiS_Pr); 331462306a36Sopenharmony_ci 331562306a36Sopenharmony_ci /* We never lock registers in XF86 */ 331662306a36Sopenharmony_ci if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00); 331762306a36Sopenharmony_ci 331862306a36Sopenharmony_ci return true; 331962306a36Sopenharmony_ci} 332062306a36Sopenharmony_ci 332162306a36Sopenharmony_ci#ifndef GETBITSTR 332262306a36Sopenharmony_ci#define GENBITSMASK(mask) GENMASK(1?mask,0?mask) 332362306a36Sopenharmony_ci#define GETBITS(var,mask) (((var) & GENBITSMASK(mask)) >> (0?mask)) 332462306a36Sopenharmony_ci#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to)) 332562306a36Sopenharmony_ci#endif 332662306a36Sopenharmony_ci 332762306a36Sopenharmony_civoid 332862306a36Sopenharmony_ciSiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth) 332962306a36Sopenharmony_ci{ 333062306a36Sopenharmony_ci int x = 1; /* Fix sync */ 333162306a36Sopenharmony_ci 333262306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */ 333362306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */ 333462306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */ 333562306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */ 333662306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */ 333762306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */ 333862306a36Sopenharmony_ci (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F); 333962306a36Sopenharmony_ci 334062306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */ 334162306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */ 334262306a36Sopenharmony_ci | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7) 334362306a36Sopenharmony_ci | (((SiS_Pr->CVSyncStart - x) & 0x100) >> 6) 334462306a36Sopenharmony_ci | (((SiS_Pr->CVBlankStart- 1) & 0x100) >> 5) 334562306a36Sopenharmony_ci | 0x10 334662306a36Sopenharmony_ci | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4) 334762306a36Sopenharmony_ci | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3) 334862306a36Sopenharmony_ci | (((SiS_Pr->CVSyncStart - x) & 0x200) >> 2); 334962306a36Sopenharmony_ci 335062306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */ 335162306a36Sopenharmony_ci 335262306a36Sopenharmony_ci if(depth != 8) { 335362306a36Sopenharmony_ci if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60; /* SRE */ 335462306a36Sopenharmony_ci else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40; 335562306a36Sopenharmony_ci } 335662306a36Sopenharmony_ci 335762306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart - x) & 0xFF; /* CR10 */ 335862306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd - x) & 0x0F) | 0x80; /* CR11 */ 335962306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */ 336062306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */ 336162306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */ 336262306a36Sopenharmony_ci 336362306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[13] = /* SRA */ 336462306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) | 336562306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) | 336662306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) | 336762306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CVSyncStart -x), 10:10, 3:3) | 336862306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) | 336962306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ; 337062306a36Sopenharmony_ci 337162306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[14] = /* SRB */ 337262306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) | 337362306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) | 337462306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) | 337562306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ; 337662306a36Sopenharmony_ci 337762306a36Sopenharmony_ci 337862306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[15] = /* SRC */ 337962306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) | 338062306a36Sopenharmony_ci GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ; 338162306a36Sopenharmony_ci} 338262306a36Sopenharmony_ci 338362306a36Sopenharmony_civoid 338462306a36Sopenharmony_ciSiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 338562306a36Sopenharmony_ci unsigned short ModeIdIndex) 338662306a36Sopenharmony_ci{ 338762306a36Sopenharmony_ci unsigned short modeflag, tempax, tempbx = 0, remaining = 0; 338862306a36Sopenharmony_ci unsigned short VGAHDE = SiS_Pr->SiS_VGAHDE; 338962306a36Sopenharmony_ci int i, j; 339062306a36Sopenharmony_ci 339162306a36Sopenharmony_ci /* 1:1 data: use data set by setcrt1crtc() */ 339262306a36Sopenharmony_ci if(SiS_Pr->SiS_LCDInfo & LCDPass11) return; 339362306a36Sopenharmony_ci 339462306a36Sopenharmony_ci modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 339562306a36Sopenharmony_ci 339662306a36Sopenharmony_ci if(modeflag & HalfDCLK) VGAHDE >>= 1; 339762306a36Sopenharmony_ci 339862306a36Sopenharmony_ci SiS_Pr->CHDisplay = VGAHDE; 339962306a36Sopenharmony_ci SiS_Pr->CHBlankStart = VGAHDE; 340062306a36Sopenharmony_ci 340162306a36Sopenharmony_ci SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE; 340262306a36Sopenharmony_ci SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE; 340362306a36Sopenharmony_ci 340462306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_315H) { 340562306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 340662306a36Sopenharmony_ci tempbx = SiS_Pr->SiS_VGAHT; 340762306a36Sopenharmony_ci if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 340862306a36Sopenharmony_ci tempbx = SiS_Pr->PanelHT; 340962306a36Sopenharmony_ci } 341062306a36Sopenharmony_ci if(modeflag & HalfDCLK) tempbx >>= 1; 341162306a36Sopenharmony_ci remaining = tempbx % 8; 341262306a36Sopenharmony_ci#endif 341362306a36Sopenharmony_ci } else { 341462306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 341562306a36Sopenharmony_ci /* OK for LCDA, LVDS */ 341662306a36Sopenharmony_ci tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes; 341762306a36Sopenharmony_ci tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */ 341862306a36Sopenharmony_ci if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 341962306a36Sopenharmony_ci tempax = SiS_Pr->PanelXRes; 342062306a36Sopenharmony_ci } 342162306a36Sopenharmony_ci tempbx += tempax; 342262306a36Sopenharmony_ci if(modeflag & HalfDCLK) tempbx -= VGAHDE; 342362306a36Sopenharmony_ci#endif 342462306a36Sopenharmony_ci } 342562306a36Sopenharmony_ci SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx; 342662306a36Sopenharmony_ci 342762306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_315H) { 342862306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 342962306a36Sopenharmony_ci if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) { 343062306a36Sopenharmony_ci SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1); 343162306a36Sopenharmony_ci SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE; 343262306a36Sopenharmony_ci if(modeflag & HalfDCLK) { 343362306a36Sopenharmony_ci SiS_Pr->CHSyncStart >>= 1; 343462306a36Sopenharmony_ci SiS_Pr->CHSyncEnd >>= 1; 343562306a36Sopenharmony_ci } 343662306a36Sopenharmony_ci } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 343762306a36Sopenharmony_ci tempax = (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) >> 1; 343862306a36Sopenharmony_ci tempbx = (SiS_Pr->PanelHRS + 1) & ~1; 343962306a36Sopenharmony_ci if(modeflag & HalfDCLK) { 344062306a36Sopenharmony_ci tempax >>= 1; 344162306a36Sopenharmony_ci tempbx >>= 1; 344262306a36Sopenharmony_ci } 344362306a36Sopenharmony_ci SiS_Pr->CHSyncStart = (VGAHDE + tempax + tempbx + 7) & ~7; 344462306a36Sopenharmony_ci tempax = SiS_Pr->PanelHRE + 7; 344562306a36Sopenharmony_ci if(modeflag & HalfDCLK) tempax >>= 1; 344662306a36Sopenharmony_ci SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + tempax) & ~7; 344762306a36Sopenharmony_ci } else { 344862306a36Sopenharmony_ci SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE; 344962306a36Sopenharmony_ci if(modeflag & HalfDCLK) { 345062306a36Sopenharmony_ci SiS_Pr->CHSyncStart >>= 1; 345162306a36Sopenharmony_ci tempax = ((SiS_Pr->CHTotal - SiS_Pr->CHSyncStart) / 3) << 1; 345262306a36Sopenharmony_ci SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + tempax; 345362306a36Sopenharmony_ci } else { 345462306a36Sopenharmony_ci SiS_Pr->CHSyncEnd = (SiS_Pr->CHSyncStart + (SiS_Pr->CHTotal / 10) + 7) & ~7; 345562306a36Sopenharmony_ci SiS_Pr->CHSyncStart += 8; 345662306a36Sopenharmony_ci } 345762306a36Sopenharmony_ci } 345862306a36Sopenharmony_ci#endif 345962306a36Sopenharmony_ci } else { 346062306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_315 346162306a36Sopenharmony_ci tempax = VGAHDE; 346262306a36Sopenharmony_ci if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 346362306a36Sopenharmony_ci tempbx = SiS_Pr->PanelXRes; 346462306a36Sopenharmony_ci if(modeflag & HalfDCLK) tempbx >>= 1; 346562306a36Sopenharmony_ci tempax += ((tempbx - tempax) >> 1); 346662306a36Sopenharmony_ci } 346762306a36Sopenharmony_ci tempax += SiS_Pr->PanelHRS; 346862306a36Sopenharmony_ci SiS_Pr->CHSyncStart = tempax; 346962306a36Sopenharmony_ci tempax += SiS_Pr->PanelHRE; 347062306a36Sopenharmony_ci SiS_Pr->CHSyncEnd = tempax; 347162306a36Sopenharmony_ci#endif 347262306a36Sopenharmony_ci } 347362306a36Sopenharmony_ci 347462306a36Sopenharmony_ci tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes; 347562306a36Sopenharmony_ci tempax = SiS_Pr->SiS_VGAVDE; 347662306a36Sopenharmony_ci if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 347762306a36Sopenharmony_ci tempax = SiS_Pr->PanelYRes; 347862306a36Sopenharmony_ci } else if(SiS_Pr->ChipType < SIS_315H) { 347962306a36Sopenharmony_ci#ifdef CONFIG_FB_SIS_300 348062306a36Sopenharmony_ci /* Stupid hack for 640x400/320x200 */ 348162306a36Sopenharmony_ci if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 348262306a36Sopenharmony_ci if((tempax + tempbx) == 438) tempbx += 16; 348362306a36Sopenharmony_ci } else if((SiS_Pr->SiS_LCDResInfo == Panel_800x600) || 348462306a36Sopenharmony_ci (SiS_Pr->SiS_LCDResInfo == Panel_1024x600)) { 348562306a36Sopenharmony_ci tempax = 0; 348662306a36Sopenharmony_ci tempbx = SiS_Pr->SiS_VGAVT; 348762306a36Sopenharmony_ci } 348862306a36Sopenharmony_ci#endif 348962306a36Sopenharmony_ci } 349062306a36Sopenharmony_ci SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax; 349162306a36Sopenharmony_ci 349262306a36Sopenharmony_ci tempax = SiS_Pr->SiS_VGAVDE; 349362306a36Sopenharmony_ci if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 349462306a36Sopenharmony_ci tempax += (SiS_Pr->PanelYRes - tempax) >> 1; 349562306a36Sopenharmony_ci } 349662306a36Sopenharmony_ci tempax += SiS_Pr->PanelVRS; 349762306a36Sopenharmony_ci SiS_Pr->CVSyncStart = tempax; 349862306a36Sopenharmony_ci tempax += SiS_Pr->PanelVRE; 349962306a36Sopenharmony_ci SiS_Pr->CVSyncEnd = tempax; 350062306a36Sopenharmony_ci if(SiS_Pr->ChipType < SIS_315H) { 350162306a36Sopenharmony_ci SiS_Pr->CVSyncStart--; 350262306a36Sopenharmony_ci SiS_Pr->CVSyncEnd--; 350362306a36Sopenharmony_ci } 350462306a36Sopenharmony_ci 350562306a36Sopenharmony_ci SiS_CalcCRRegisters(SiS_Pr, 8); 350662306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[15] &= ~0xF8; 350762306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[15] |= (remaining << 4); 350862306a36Sopenharmony_ci SiS_Pr->CCRT1CRTC[16] &= ~0xE0; 350962306a36Sopenharmony_ci 351062306a36Sopenharmony_ci SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 351162306a36Sopenharmony_ci 351262306a36Sopenharmony_ci for(i = 0, j = 0; i <= 7; i++, j++) { 351362306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 351462306a36Sopenharmony_ci } 351562306a36Sopenharmony_ci for(j = 0x10; i <= 10; i++, j++) { 351662306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 351762306a36Sopenharmony_ci } 351862306a36Sopenharmony_ci for(j = 0x15; i <= 12; i++, j++) { 351962306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]); 352062306a36Sopenharmony_ci } 352162306a36Sopenharmony_ci for(j = 0x0A; i <= 15; i++, j++) { 352262306a36Sopenharmony_ci SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]); 352362306a36Sopenharmony_ci } 352462306a36Sopenharmony_ci 352562306a36Sopenharmony_ci tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0; 352662306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax); 352762306a36Sopenharmony_ci 352862306a36Sopenharmony_ci tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5; 352962306a36Sopenharmony_ci if(modeflag & DoubleScanMode) tempax |= 0x80; 353062306a36Sopenharmony_ci SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax); 353162306a36Sopenharmony_ci 353262306a36Sopenharmony_ci} 353362306a36Sopenharmony_ci 353462306a36Sopenharmony_civoid 353562306a36Sopenharmony_ciSiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, 353662306a36Sopenharmony_ci int xres, int yres, 353762306a36Sopenharmony_ci struct fb_var_screeninfo *var, bool writeres 353862306a36Sopenharmony_ci) 353962306a36Sopenharmony_ci{ 354062306a36Sopenharmony_ci unsigned short HRE, HBE, HRS, HDE; 354162306a36Sopenharmony_ci unsigned short VRE, VBE, VRS, VDE; 354262306a36Sopenharmony_ci unsigned char sr_data, cr_data; 354362306a36Sopenharmony_ci int B, C, D, E, F, temp; 354462306a36Sopenharmony_ci 354562306a36Sopenharmony_ci sr_data = crdata[14]; 354662306a36Sopenharmony_ci 354762306a36Sopenharmony_ci /* Horizontal display enable end */ 354862306a36Sopenharmony_ci HDE = crdata[1] | ((unsigned short)(sr_data & 0x0C) << 6); 354962306a36Sopenharmony_ci E = HDE + 1; 355062306a36Sopenharmony_ci 355162306a36Sopenharmony_ci /* Horizontal retrace (=sync) start */ 355262306a36Sopenharmony_ci HRS = crdata[4] | ((unsigned short)(sr_data & 0xC0) << 2); 355362306a36Sopenharmony_ci F = HRS - E - 3; 355462306a36Sopenharmony_ci 355562306a36Sopenharmony_ci sr_data = crdata[15]; 355662306a36Sopenharmony_ci cr_data = crdata[5]; 355762306a36Sopenharmony_ci 355862306a36Sopenharmony_ci /* Horizontal blank end */ 355962306a36Sopenharmony_ci HBE = (crdata[3] & 0x1f) | 356062306a36Sopenharmony_ci ((unsigned short)(cr_data & 0x80) >> 2) | 356162306a36Sopenharmony_ci ((unsigned short)(sr_data & 0x03) << 6); 356262306a36Sopenharmony_ci 356362306a36Sopenharmony_ci /* Horizontal retrace (=sync) end */ 356462306a36Sopenharmony_ci HRE = (cr_data & 0x1f) | ((sr_data & 0x04) << 3); 356562306a36Sopenharmony_ci 356662306a36Sopenharmony_ci temp = HBE - ((E - 1) & 255); 356762306a36Sopenharmony_ci B = (temp > 0) ? temp : (temp + 256); 356862306a36Sopenharmony_ci 356962306a36Sopenharmony_ci temp = HRE - ((E + F + 3) & 63); 357062306a36Sopenharmony_ci C = (temp > 0) ? temp : (temp + 64); 357162306a36Sopenharmony_ci 357262306a36Sopenharmony_ci D = B - F - C; 357362306a36Sopenharmony_ci 357462306a36Sopenharmony_ci if(writeres) var->xres = xres = E * 8; 357562306a36Sopenharmony_ci var->left_margin = D * 8; 357662306a36Sopenharmony_ci var->right_margin = F * 8; 357762306a36Sopenharmony_ci var->hsync_len = C * 8; 357862306a36Sopenharmony_ci 357962306a36Sopenharmony_ci /* Vertical */ 358062306a36Sopenharmony_ci sr_data = crdata[13]; 358162306a36Sopenharmony_ci cr_data = crdata[7]; 358262306a36Sopenharmony_ci 358362306a36Sopenharmony_ci /* Vertical display enable end */ 358462306a36Sopenharmony_ci VDE = crdata[10] | 358562306a36Sopenharmony_ci ((unsigned short)(cr_data & 0x02) << 7) | 358662306a36Sopenharmony_ci ((unsigned short)(cr_data & 0x40) << 3) | 358762306a36Sopenharmony_ci ((unsigned short)(sr_data & 0x02) << 9); 358862306a36Sopenharmony_ci E = VDE + 1; 358962306a36Sopenharmony_ci 359062306a36Sopenharmony_ci /* Vertical retrace (=sync) start */ 359162306a36Sopenharmony_ci VRS = crdata[8] | 359262306a36Sopenharmony_ci ((unsigned short)(cr_data & 0x04) << 6) | 359362306a36Sopenharmony_ci ((unsigned short)(cr_data & 0x80) << 2) | 359462306a36Sopenharmony_ci ((unsigned short)(sr_data & 0x08) << 7); 359562306a36Sopenharmony_ci F = VRS + 1 - E; 359662306a36Sopenharmony_ci 359762306a36Sopenharmony_ci /* Vertical blank end */ 359862306a36Sopenharmony_ci VBE = crdata[12] | ((unsigned short)(sr_data & 0x10) << 4); 359962306a36Sopenharmony_ci temp = VBE - ((E - 1) & 511); 360062306a36Sopenharmony_ci B = (temp > 0) ? temp : (temp + 512); 360162306a36Sopenharmony_ci 360262306a36Sopenharmony_ci /* Vertical retrace (=sync) end */ 360362306a36Sopenharmony_ci VRE = (crdata[9] & 0x0f) | ((sr_data & 0x20) >> 1); 360462306a36Sopenharmony_ci temp = VRE - ((E + F - 1) & 31); 360562306a36Sopenharmony_ci C = (temp > 0) ? temp : (temp + 32); 360662306a36Sopenharmony_ci 360762306a36Sopenharmony_ci D = B - F - C; 360862306a36Sopenharmony_ci 360962306a36Sopenharmony_ci if(writeres) var->yres = yres = E; 361062306a36Sopenharmony_ci var->upper_margin = D; 361162306a36Sopenharmony_ci var->lower_margin = F; 361262306a36Sopenharmony_ci var->vsync_len = C; 361362306a36Sopenharmony_ci 361462306a36Sopenharmony_ci if((xres == 320) && ((yres == 200) || (yres == 240))) { 361562306a36Sopenharmony_ci /* Terrible hack, but correct CRTC data for 361662306a36Sopenharmony_ci * these modes only produces a black screen... 361762306a36Sopenharmony_ci * (HRE is 0, leading into a too large C and 361862306a36Sopenharmony_ci * a negative D. The CRT controller does not 361962306a36Sopenharmony_ci * seem to like correcting HRE to 50) 362062306a36Sopenharmony_ci */ 362162306a36Sopenharmony_ci var->left_margin = (400 - 376); 362262306a36Sopenharmony_ci var->right_margin = (328 - 320); 362362306a36Sopenharmony_ci var->hsync_len = (376 - 328); 362462306a36Sopenharmony_ci 362562306a36Sopenharmony_ci } 362662306a36Sopenharmony_ci 362762306a36Sopenharmony_ci} 362862306a36Sopenharmony_ci 362962306a36Sopenharmony_ci 363062306a36Sopenharmony_ci 363162306a36Sopenharmony_ci 3632