PageRenderTime 302ms CodeModel.GetById 33ms app.highlight 227ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/video/sis/init.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t
C | 3654 lines | 2881 code | 474 blank | 299 comment | 1070 complexity | 0446235e90d6fea09f8a38cd3ec6a989 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

   1/* $XFree86$ */
   2/* $XdotOrg$ */
   3/*
   4 * Mode initializing code (CRT1 section) for
   5 * for SiS 300/305/540/630/730,
   6 *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
   7 *     XGI Volari V3XT/V5/V8, Z7
   8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
   9 *
  10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
  11 *
  12 * If distributed as part of the Linux kernel, the following license terms
  13 * apply:
  14 *
  15 * * This program is free software; you can redistribute it and/or modify
  16 * * it under the terms of the GNU General Public License as published by
  17 * * the Free Software Foundation; either version 2 of the named License,
  18 * * or any later version.
  19 * *
  20 * * This program is distributed in the hope that it will be useful,
  21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23 * * GNU General Public License for more details.
  24 * *
  25 * * You should have received a copy of the GNU General Public License
  26 * * along with this program; if not, write to the Free Software
  27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  28 *
  29 * Otherwise, the following license terms apply:
  30 *
  31 * * Redistribution and use in source and binary forms, with or without
  32 * * modification, are permitted provided that the following conditions
  33 * * are met:
  34 * * 1) Redistributions of source code must retain the above copyright
  35 * *    notice, this list of conditions and the following disclaimer.
  36 * * 2) Redistributions in binary form must reproduce the above copyright
  37 * *    notice, this list of conditions and the following disclaimer in the
  38 * *    documentation and/or other materials provided with the distribution.
  39 * * 3) The name of the author may not be used to endorse or promote products
  40 * *    derived from this software without specific prior written permission.
  41 * *
  42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52 *
  53 * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
  54 *
  55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
  56 * Used by permission.
  57 */
  58
  59#include "init.h"
  60
  61#ifdef CONFIG_FB_SIS_300
  62#include "300vtbl.h"
  63#endif
  64
  65#ifdef CONFIG_FB_SIS_315
  66#include "310vtbl.h"
  67#endif
  68
  69#if defined(ALLOC_PRAGMA)
  70#pragma alloc_text(PAGE,SiSSetMode)
  71#endif
  72
  73/*********************************************/
  74/*         POINTER INITIALIZATION            */
  75/*********************************************/
  76
  77#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
  78static void
  79InitCommonPointer(struct SiS_Private *SiS_Pr)
  80{
  81   SiS_Pr->SiS_SModeIDTable  = SiS_SModeIDTable;
  82   SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
  83   SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
  84   SiS_Pr->SiS_StandTable    = SiS_StandTable;
  85
  86   SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
  87   SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
  88   SiS_Pr->SiS_HiTVSt1Timing  = SiS_HiTVSt1Timing;
  89   SiS_Pr->SiS_HiTVSt2Timing  = SiS_HiTVSt2Timing;
  90
  91   SiS_Pr->SiS_HiTVExtTiming  = SiS_HiTVExtTiming;
  92   SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
  93   SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
  94#if 0
  95   SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
  96   SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
  97#endif
  98
  99   SiS_Pr->SiS_StPALData   = SiS_StPALData;
 100   SiS_Pr->SiS_ExtPALData  = SiS_ExtPALData;
 101   SiS_Pr->SiS_StNTSCData  = SiS_StNTSCData;
 102   SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
 103   SiS_Pr->SiS_St1HiTVData = SiS_StHiTVData;
 104   SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
 105   SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
 106   SiS_Pr->SiS_St525iData  = SiS_StNTSCData;
 107   SiS_Pr->SiS_St525pData  = SiS_St525pData;
 108   SiS_Pr->SiS_St750pData  = SiS_St750pData;
 109   SiS_Pr->SiS_Ext525iData = SiS_ExtNTSCData;
 110   SiS_Pr->SiS_Ext525pData = SiS_ExtNTSCData;
 111   SiS_Pr->SiS_Ext750pData = SiS_Ext750pData;
 112
 113   SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
 114   SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
 115
 116   SiS_Pr->SiS_LCD1280x720Data      = SiS_LCD1280x720Data;
 117   SiS_Pr->SiS_StLCD1280x768_2Data  = SiS_StLCD1280x768_2Data;
 118   SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
 119   SiS_Pr->SiS_LCD1280x800Data      = SiS_LCD1280x800Data;
 120   SiS_Pr->SiS_LCD1280x800_2Data    = SiS_LCD1280x800_2Data;
 121   SiS_Pr->SiS_LCD1280x854Data      = SiS_LCD1280x854Data;
 122   SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
 123   SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
 124   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
 125   SiS_Pr->SiS_LCD1680x1050Data     = SiS_LCD1680x1050Data;
 126   SiS_Pr->SiS_StLCD1600x1200Data   = SiS_StLCD1600x1200Data;
 127   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
 128   SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
 129
 130   SiS_Pr->SiS_LVDS320x240Data_1   = SiS_LVDS320x240Data_1;
 131   SiS_Pr->SiS_LVDS320x240Data_2   = SiS_LVDS320x240Data_2;
 132   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
 133   SiS_Pr->SiS_LVDS800x600Data_1   = SiS_LVDS800x600Data_1;
 134   SiS_Pr->SiS_LVDS1024x600Data_1  = SiS_LVDS1024x600Data_1;
 135   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
 136
 137   SiS_Pr->SiS_LVDSCRT1320x240_1     = SiS_LVDSCRT1320x240_1;
 138   SiS_Pr->SiS_LVDSCRT1320x240_2     = SiS_LVDSCRT1320x240_2;
 139   SiS_Pr->SiS_LVDSCRT1320x240_2_H   = SiS_LVDSCRT1320x240_2_H;
 140   SiS_Pr->SiS_LVDSCRT1320x240_3     = SiS_LVDSCRT1320x240_3;
 141   SiS_Pr->SiS_LVDSCRT1320x240_3_H   = SiS_LVDSCRT1320x240_3_H;
 142   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
 143   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
 144#if 0
 145   SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
 146   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = SiS_LVDSCRT11024x600_1_H;
 147   SiS_Pr->SiS_LVDSCRT11024x600_2    = SiS_LVDSCRT11024x600_2;
 148   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
 149#endif
 150
 151   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
 152   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
 153
 154   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* lowest value LVDS/LCDA */
 155   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* lowest value 301 */
 156}
 157#endif
 158
 159#ifdef CONFIG_FB_SIS_300
 160static void
 161InitTo300Pointer(struct SiS_Private *SiS_Pr)
 162{
 163   InitCommonPointer(SiS_Pr);
 164
 165   SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
 166   SiS_Pr->SiS_EModeIDTable  = SiS300_EModeIDTable;
 167   SiS_Pr->SiS_RefIndex      = SiS300_RefIndex;
 168   SiS_Pr->SiS_CRT1Table     = SiS300_CRT1Table;
 169   if(SiS_Pr->ChipType == SIS_300) {
 170      SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
 171   } else {
 172      SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
 173   }
 174   SiS_Pr->SiS_VCLKData      = SiS300_VCLKData;
 175   SiS_Pr->SiS_VBVCLKData    = (struct SiS_VBVCLKData *)SiS300_VCLKData;
 176
 177   SiS_Pr->SiS_SR15  = SiS300_SR15;
 178
 179   SiS_Pr->SiS_PanelDelayTbl     = SiS300_PanelDelayTbl;
 180   SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
 181
 182   SiS_Pr->SiS_ExtLCD1024x768Data   = SiS300_ExtLCD1024x768Data;
 183   SiS_Pr->SiS_St2LCD1024x768Data   = SiS300_St2LCD1024x768Data;
 184   SiS_Pr->SiS_ExtLCD1280x1024Data  = SiS300_ExtLCD1280x1024Data;
 185   SiS_Pr->SiS_St2LCD1280x1024Data  = SiS300_St2LCD1280x1024Data;
 186
 187   SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS300_CRT2Part2_1024x768_1;
 188   SiS_Pr->SiS_CRT2Part2_1024x768_2  = SiS300_CRT2Part2_1024x768_2;
 189   SiS_Pr->SiS_CRT2Part2_1024x768_3  = SiS300_CRT2Part2_1024x768_3;
 190
 191   SiS_Pr->SiS_CHTVUPALData  = SiS300_CHTVUPALData;
 192   SiS_Pr->SiS_CHTVOPALData  = SiS300_CHTVOPALData;
 193   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData;    /* not supported on 300 series */
 194   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData;    /* not supported on 300 series */
 195   SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData;  /* not supported on 300 series */
 196   SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData;  /* not supported on 300 series */
 197   SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
 198
 199   SiS_Pr->SiS_LVDS848x480Data_1   = SiS300_LVDS848x480Data_1;
 200   SiS_Pr->SiS_LVDS848x480Data_2   = SiS300_LVDS848x480Data_2;
 201   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS300_LVDSBARCO1024Data_1;
 202   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS300_LVDSBARCO1366Data_1;
 203   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS300_LVDSBARCO1366Data_2;
 204
 205   SiS_Pr->SiS_PanelType04_1a = SiS300_PanelType04_1a;
 206   SiS_Pr->SiS_PanelType04_2a = SiS300_PanelType04_2a;
 207   SiS_Pr->SiS_PanelType04_1b = SiS300_PanelType04_1b;
 208   SiS_Pr->SiS_PanelType04_2b = SiS300_PanelType04_2b;
 209
 210   SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
 211   SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
 212   SiS_Pr->SiS_CHTVCRT1UPAL  = SiS300_CHTVCRT1UPAL;
 213   SiS_Pr->SiS_CHTVCRT1OPAL  = SiS300_CHTVCRT1OPAL;
 214   SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL;
 215   SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC;
 216   SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC;
 217   SiS_Pr->SiS_CHTVReg_UPAL  = SiS300_CHTVReg_UPAL;
 218   SiS_Pr->SiS_CHTVReg_OPAL  = SiS300_CHTVReg_OPAL;
 219   SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC;  /* not supported on 300 series */
 220   SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC;  /* not supported on 300 series */
 221   SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL;   /* not supported on 300 series */
 222   SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL;   /* not supported on 300 series */
 223   SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL;
 224   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
 225   SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
 226   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS300_CHTVVCLKUPAL;
 227   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS300_CHTVVCLKOPAL;
 228   SiS_Pr->SiS_CHTVVCLKUPALM = SiS300_CHTVVCLKUNTSC;  /* not supported on 300 series */
 229   SiS_Pr->SiS_CHTVVCLKOPALM = SiS300_CHTVVCLKONTSC;  /* not supported on 300 series */
 230   SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL;   /* not supported on 300 series */
 231   SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
 232   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
 233}
 234#endif
 235
 236#ifdef CONFIG_FB_SIS_315
 237static void
 238InitTo310Pointer(struct SiS_Private *SiS_Pr)
 239{
 240   InitCommonPointer(SiS_Pr);
 241
 242   SiS_Pr->SiS_EModeIDTable  = SiS310_EModeIDTable;
 243   SiS_Pr->SiS_RefIndex      = SiS310_RefIndex;
 244   SiS_Pr->SiS_CRT1Table     = SiS310_CRT1Table;
 245   if(SiS_Pr->ChipType >= SIS_340) {
 246      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_340;  /* 340 + XGI */
 247   } else if(SiS_Pr->ChipType >= SIS_761) {
 248      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_761;  /* 761 - preliminary */
 249   } else if(SiS_Pr->ChipType >= SIS_760) {
 250      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760;  /* 760 */
 251   } else if(SiS_Pr->ChipType >= SIS_661) {
 252      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660;  /* 661/741 */
 253   } else if(SiS_Pr->ChipType == SIS_330) {
 254      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330;  /* 330 */
 255   } else if(SiS_Pr->ChipType > SIS_315PRO) {
 256      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650;  /* 550, 650, 740 */
 257   } else {
 258      SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315;  /* 315 */
 259   }
 260   if(SiS_Pr->ChipType >= SIS_340) {
 261      SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1_340;
 262   } else {
 263      SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
 264   }
 265   SiS_Pr->SiS_VCLKData      = SiS310_VCLKData;
 266   SiS_Pr->SiS_VBVCLKData    = SiS310_VBVCLKData;
 267
 268   SiS_Pr->SiS_SR15  = SiS310_SR15;
 269
 270   SiS_Pr->SiS_PanelDelayTbl     = SiS310_PanelDelayTbl;
 271   SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
 272
 273   SiS_Pr->SiS_St2LCD1024x768Data   = SiS310_St2LCD1024x768Data;
 274   SiS_Pr->SiS_ExtLCD1024x768Data   = SiS310_ExtLCD1024x768Data;
 275   SiS_Pr->SiS_St2LCD1280x1024Data  = SiS310_St2LCD1280x1024Data;
 276   SiS_Pr->SiS_ExtLCD1280x1024Data  = SiS310_ExtLCD1280x1024Data;
 277
 278   SiS_Pr->SiS_CRT2Part2_1024x768_1  = SiS310_CRT2Part2_1024x768_1;
 279
 280   SiS_Pr->SiS_CHTVUPALData  = SiS310_CHTVUPALData;
 281   SiS_Pr->SiS_CHTVOPALData  = SiS310_CHTVOPALData;
 282   SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
 283   SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData;
 284   SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData;
 285   SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
 286   SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
 287
 288   SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
 289   SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
 290   SiS_Pr->SiS_CHTVCRT1UPAL  = SiS310_CHTVCRT1UPAL;
 291   SiS_Pr->SiS_CHTVCRT1OPAL  = SiS310_CHTVCRT1OPAL;
 292   SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
 293
 294   SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
 295   SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
 296   SiS_Pr->SiS_CHTVReg_UPAL  = SiS310_CHTVReg_UPAL;
 297   SiS_Pr->SiS_CHTVReg_OPAL  = SiS310_CHTVReg_OPAL;
 298   SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM;
 299   SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM;
 300   SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN;
 301   SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN;
 302   SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL;
 303
 304   SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
 305   SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
 306   SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
 307   SiS_Pr->SiS_CHTVVCLKOPAL  = SiS310_CHTVVCLKOPAL;
 308   SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
 309   SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
 310   SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
 311   SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
 312   SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
 313}
 314#endif
 315
 316bool
 317SiSInitPtr(struct SiS_Private *SiS_Pr)
 318{
 319   if(SiS_Pr->ChipType < SIS_315H) {
 320#ifdef CONFIG_FB_SIS_300
 321      InitTo300Pointer(SiS_Pr);
 322#else
 323      return false;
 324#endif
 325   } else {
 326#ifdef CONFIG_FB_SIS_315
 327      InitTo310Pointer(SiS_Pr);
 328#else
 329      return false;
 330#endif
 331   }
 332   return true;
 333}
 334
 335/*********************************************/
 336/*            HELPER: Get ModeID             */
 337/*********************************************/
 338
 339static
 340unsigned short
 341SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
 342		int Depth, bool FSTN, int LCDwidth, int LCDheight)
 343{
 344   unsigned short ModeIndex = 0;
 345
 346   switch(HDisplay)
 347   {
 348	case 320:
 349		if(VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth];
 350		else if(VDisplay == 240) {
 351			if((VBFlags & CRT2_LCD) && (FSTN))
 352				ModeIndex = ModeIndex_320x240_FSTN[Depth];
 353			else
 354				ModeIndex = ModeIndex_320x240[Depth];
 355		}
 356		break;
 357	case 400:
 358		if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
 359			if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
 360		}
 361		break;
 362	case 512:
 363		if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
 364			if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
 365		}
 366		break;
 367	case 640:
 368		if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
 369		else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
 370		break;
 371	case 720:
 372		if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
 373		else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
 374		break;
 375	case 768:
 376		if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
 377		break;
 378	case 800:
 379		if(VDisplay == 600)      ModeIndex = ModeIndex_800x600[Depth];
 380		else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
 381		break;
 382	case 848:
 383		if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
 384		break;
 385	case 856:
 386		if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
 387		break;
 388	case 960:
 389		if(VGAEngine == SIS_315_VGA) {
 390			if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
 391			else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 392		}
 393		break;
 394	case 1024:
 395		if(VDisplay == 576)      ModeIndex = ModeIndex_1024x576[Depth];
 396		else if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
 397		else if(VGAEngine == SIS_300_VGA) {
 398			if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
 399		}
 400		break;
 401	case 1152:
 402		if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
 403		if(VGAEngine == SIS_300_VGA) {
 404			if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
 405		}
 406		break;
 407	case 1280:
 408		switch(VDisplay) {
 409			case 720:
 410				ModeIndex = ModeIndex_1280x720[Depth];
 411				break;
 412			case 768:
 413				if(VGAEngine == SIS_300_VGA) {
 414					ModeIndex = ModeIndex_300_1280x768[Depth];
 415				} else {
 416					ModeIndex = ModeIndex_310_1280x768[Depth];
 417				}
 418				break;
 419			case 800:
 420				if(VGAEngine == SIS_315_VGA) {
 421					ModeIndex = ModeIndex_1280x800[Depth];
 422				}
 423				break;
 424			case 854:
 425				if(VGAEngine == SIS_315_VGA) {
 426					ModeIndex = ModeIndex_1280x854[Depth];
 427				}
 428				break;
 429			case 960:
 430				ModeIndex = ModeIndex_1280x960[Depth];
 431				break;
 432			case 1024:
 433				ModeIndex = ModeIndex_1280x1024[Depth];
 434				break;
 435		}
 436		break;
 437	case 1360:
 438		if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
 439		if(VGAEngine == SIS_300_VGA) {
 440			if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
 441		}
 442		break;
 443	case 1400:
 444		if(VGAEngine == SIS_315_VGA) {
 445			if(VDisplay == 1050) {
 446				ModeIndex = ModeIndex_1400x1050[Depth];
 447			}
 448		}
 449		break;
 450	case 1600:
 451		if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
 452		break;
 453	case 1680:
 454		if(VGAEngine == SIS_315_VGA) {
 455			if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
 456		}
 457		break;
 458	case 1920:
 459		if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
 460		else if(VGAEngine == SIS_315_VGA) {
 461			if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
 462		}
 463		break;
 464	case 2048:
 465		if(VDisplay == 1536) {
 466			if(VGAEngine == SIS_300_VGA) {
 467				ModeIndex = ModeIndex_300_2048x1536[Depth];
 468			} else {
 469				ModeIndex = ModeIndex_310_2048x1536[Depth];
 470			}
 471		}
 472		break;
 473   }
 474
 475   return ModeIndex;
 476}
 477
 478unsigned short
 479SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
 480		int Depth, bool FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
 481		unsigned int VBFlags2)
 482{
 483   unsigned short ModeIndex = 0;
 484
 485   if(VBFlags2 & (VB2_LVDS | VB2_30xBDH)) {
 486
 487      switch(HDisplay)
 488      {
 489	case 320:
 490	     if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
 491		if(VDisplay == 200) {
 492		   if(!FSTN) ModeIndex = ModeIndex_320x200[Depth];
 493		} else if(VDisplay == 240) {
 494		   if(!FSTN) ModeIndex = ModeIndex_320x240[Depth];
 495		   else if(VGAEngine == SIS_315_VGA) {
 496		      ModeIndex = ModeIndex_320x240_FSTN[Depth];
 497		   }
 498		}
 499	     }
 500	     break;
 501	case 400:
 502	     if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
 503		if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
 504		   if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
 505		}
 506	     }
 507	     break;
 508	case 512:
 509	     if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856)) {
 510		if(!((VGAEngine == SIS_300_VGA) && (VBFlags2 & VB2_TRUMPION))) {
 511		   if(LCDwidth >= 1024 && LCDwidth != 1152 && LCDheight >= 768) {
 512		      if(VDisplay == 384) {
 513		         ModeIndex = ModeIndex_512x384[Depth];
 514		      }
 515		   }
 516		}
 517	     }
 518	     break;
 519	case 640:
 520	     if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
 521	     else if(VDisplay == 400) {
 522		if((CustomT != CUT_PANEL848) && (CustomT != CUT_PANEL856))
 523		   ModeIndex = ModeIndex_640x400[Depth];
 524	     }
 525	     break;
 526	case 800:
 527	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
 528	     break;
 529	case 848:
 530	     if(CustomT == CUT_PANEL848) {
 531	        if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
 532	     }
 533	     break;
 534	case 856:
 535	     if(CustomT == CUT_PANEL856) {
 536	        if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
 537	     }
 538	     break;
 539	case 1024:
 540	     if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
 541	     else if(VGAEngine == SIS_300_VGA) {
 542		if((VDisplay == 600) && (LCDheight == 600)) {
 543		   ModeIndex = ModeIndex_1024x600[Depth];
 544		}
 545	     }
 546	     break;
 547	case 1152:
 548	     if(VGAEngine == SIS_300_VGA) {
 549		if((VDisplay == 768) && (LCDheight == 768)) {
 550		   ModeIndex = ModeIndex_1152x768[Depth];
 551		}
 552	     }
 553	     break;
 554        case 1280:
 555	     if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
 556	     else if(VGAEngine == SIS_315_VGA) {
 557		if((VDisplay == 768) && (LCDheight == 768)) {
 558		   ModeIndex = ModeIndex_310_1280x768[Depth];
 559		}
 560	     }
 561	     break;
 562	case 1360:
 563	     if(VGAEngine == SIS_300_VGA) {
 564		if(CustomT == CUT_BARCO1366) {
 565		   if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
 566		}
 567	     }
 568	     if(CustomT == CUT_PANEL848) {
 569		if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
 570	     }
 571	     break;
 572	case 1400:
 573	     if(VGAEngine == SIS_315_VGA) {
 574		if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
 575	     }
 576	     break;
 577	case 1600:
 578	     if(VGAEngine == SIS_315_VGA) {
 579		if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
 580	     }
 581	     break;
 582      }
 583
 584   } else if(VBFlags2 & VB2_SISBRIDGE) {
 585
 586      switch(HDisplay)
 587      {
 588	case 320:
 589	     if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
 590	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
 591	     break;
 592	case 400:
 593	     if(LCDwidth >= 800 && LCDheight >= 600) {
 594		if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
 595	     }
 596	     break;
 597	case 512:
 598	     if(LCDwidth >= 1024 && LCDheight >= 768 && LCDwidth != 1152) {
 599		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
 600	     }
 601	     break;
 602	case 640:
 603	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
 604	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
 605	     break;
 606	case 720:
 607	     if(VGAEngine == SIS_315_VGA) {
 608		if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
 609		else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
 610	     }
 611	     break;
 612	case 768:
 613	     if(VGAEngine == SIS_315_VGA) {
 614		if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
 615	     }
 616	     break;
 617	case 800:
 618	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
 619	     if(VGAEngine == SIS_315_VGA) {
 620		if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
 621	     }
 622	     break;
 623	case 848:
 624	     if(VGAEngine == SIS_315_VGA) {
 625		if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
 626	     }
 627	     break;
 628	case 856:
 629	     if(VGAEngine == SIS_315_VGA) {
 630		if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
 631	     }
 632	     break;
 633	case 960:
 634	     if(VGAEngine == SIS_315_VGA) {
 635		if(VDisplay == 540)      ModeIndex = ModeIndex_960x540[Depth];
 636		else if(VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth];
 637	     }
 638	     break;
 639	case 1024:
 640	     if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
 641	     if(VGAEngine == SIS_315_VGA) {
 642		if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
 643	     }
 644	     break;
 645	case 1152:
 646	     if(VGAEngine == SIS_315_VGA) {
 647		if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
 648	     }
 649	     break;
 650	case 1280:
 651	     switch(VDisplay) {
 652	     case 720:
 653		ModeIndex = ModeIndex_1280x720[Depth];
 654	     case 768:
 655		if(VGAEngine == SIS_300_VGA) {
 656		   ModeIndex = ModeIndex_300_1280x768[Depth];
 657		} else {
 658		   ModeIndex = ModeIndex_310_1280x768[Depth];
 659		}
 660		break;
 661	     case 800:
 662		if(VGAEngine == SIS_315_VGA) {
 663		   ModeIndex = ModeIndex_1280x800[Depth];
 664		}
 665		break;
 666	     case 854:
 667		if(VGAEngine == SIS_315_VGA) {
 668		   ModeIndex = ModeIndex_1280x854[Depth];
 669		}
 670		break;
 671	     case 960:
 672		ModeIndex = ModeIndex_1280x960[Depth];
 673		break;
 674	     case 1024:
 675		ModeIndex = ModeIndex_1280x1024[Depth];
 676		break;
 677	     }
 678	     break;
 679	case 1360:
 680	     if(VGAEngine == SIS_315_VGA) {  /* OVER1280 only? */
 681		if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
 682	     }
 683	     break;
 684	case 1400:
 685	     if(VGAEngine == SIS_315_VGA) {
 686		if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
 687		   if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
 688		}
 689	     }
 690	     break;
 691	case 1600:
 692	     if(VGAEngine == SIS_315_VGA) {
 693		if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
 694		   if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
 695		}
 696	     }
 697	     break;
 698#ifndef VB_FORBID_CRT2LCD_OVER_1600
 699	case 1680:
 700	     if(VGAEngine == SIS_315_VGA) {
 701		if(VBFlags2 & VB2_LCDOVER1280BRIDGE) {
 702		   if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
 703		}
 704	     }
 705	     break;
 706	case 1920:
 707	     if(VGAEngine == SIS_315_VGA) {
 708		if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
 709		   if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
 710		}
 711	     }
 712	     break;
 713	case 2048:
 714	     if(VGAEngine == SIS_315_VGA) {
 715		if(VBFlags2 & VB2_LCDOVER1600BRIDGE) {
 716		   if(VDisplay == 1536) ModeIndex = ModeIndex_310_2048x1536[Depth];
 717		}
 718	     }
 719	     break;
 720#endif
 721      }
 722   }
 723
 724   return ModeIndex;
 725}
 726
 727unsigned short
 728SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
 729			unsigned int VBFlags2)
 730{
 731   unsigned short ModeIndex = 0;
 732
 733   if(VBFlags2 & VB2_CHRONTEL) {
 734
 735      switch(HDisplay)
 736      {
 737	case 512:
 738	     if(VGAEngine == SIS_315_VGA) {
 739		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
 740	     }
 741	     break;
 742	case 640:
 743	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
 744	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
 745	     break;
 746	case 800:
 747	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
 748	     break;
 749	case 1024:
 750	     if(VGAEngine == SIS_315_VGA) {
 751		if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
 752	     }
 753	     break;
 754      }
 755
 756   } else if(VBFlags2 & VB2_SISTVBRIDGE) {
 757
 758      switch(HDisplay)
 759      {
 760	case 320:
 761	     if(VDisplay == 200)      ModeIndex = ModeIndex_320x200[Depth];
 762	     else if(VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth];
 763	     break;
 764	case 400:
 765	     if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
 766	     break;
 767	case 512:
 768	     if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
 769		 (VBFlags & TV_HIVISION) 					      ||
 770		 ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
 771		if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
 772	     }
 773	     break;
 774	case 640:
 775	     if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
 776	     else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
 777	     break;
 778	case 720:
 779	     if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
 780		if(VDisplay == 480) {
 781		   ModeIndex = ModeIndex_720x480[Depth];
 782		} else if(VDisplay == 576) {
 783		   if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
 784		       ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
 785		      ModeIndex = ModeIndex_720x576[Depth];
 786		}
 787	     }
 788             break;
 789	case 768:
 790	     if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
 791		if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
 792		    ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
 793		   if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
 794		}
 795             }
 796	     break;
 797	case 800:
 798	     if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
 799	     else if(VDisplay == 480) {
 800		if(!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P))) {
 801		   ModeIndex = ModeIndex_800x480[Depth];
 802		}
 803	     }
 804	     break;
 805	case 960:
 806	     if(VGAEngine == SIS_315_VGA) {
 807		if(VDisplay == 600) {
 808		   if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
 809		      ModeIndex = ModeIndex_960x600[Depth];
 810		   }
 811		}
 812	     }
 813	     break;
 814	case 1024:
 815	     if(VDisplay == 768) {
 816		if(VBFlags2 & VB2_30xBLV) {
 817		   ModeIndex = ModeIndex_1024x768[Depth];
 818		}
 819	     } else if(VDisplay == 576) {
 820		if( (VBFlags & TV_HIVISION) ||
 821		    ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)) ||
 822		    ((VBFlags2 & VB2_30xBLV) &&
 823		     ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))) ) {
 824		   ModeIndex = ModeIndex_1024x576[Depth];
 825		}
 826	     }
 827	     break;
 828	case 1280:
 829	     if(VDisplay == 720) {
 830		if((VBFlags & TV_HIVISION) ||
 831		   ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
 832		   ModeIndex = ModeIndex_1280x720[Depth];
 833		}
 834	     } else if(VDisplay == 1024) {
 835		if((VBFlags & TV_HIVISION) ||
 836		   ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
 837		   ModeIndex = ModeIndex_1280x1024[Depth];
 838		}
 839	     }
 840	     break;
 841      }
 842   }
 843   return ModeIndex;
 844}
 845
 846unsigned short
 847SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay, int Depth,
 848			unsigned int VBFlags2)
 849{
 850   if(!(VBFlags2 & VB2_SISVGA2BRIDGE)) return 0;
 851
 852   if(HDisplay >= 1920) return 0;
 853
 854   switch(HDisplay)
 855   {
 856	case 1600:
 857		if(VDisplay == 1200) {
 858			if(VGAEngine != SIS_315_VGA) return 0;
 859			if(!(VBFlags2 & VB2_30xB)) return 0;
 860		}
 861		break;
 862	case 1680:
 863		if(VDisplay == 1050) {
 864			if(VGAEngine != SIS_315_VGA) return 0;
 865			if(!(VBFlags2 & VB2_30xB)) return 0;
 866		}
 867		break;
 868   }
 869
 870   return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, false, 0, 0);
 871}
 872
 873
 874/*********************************************/
 875/*          HELPER: SetReg, GetReg           */
 876/*********************************************/
 877
 878void
 879SiS_SetReg(SISIOADDRESS port, u8 index, u8 data)
 880{
 881	outb(index, port);
 882	outb(data, port + 1);
 883}
 884
 885void
 886SiS_SetRegByte(SISIOADDRESS port, u8 data)
 887{
 888	outb(data, port);
 889}
 890
 891void
 892SiS_SetRegShort(SISIOADDRESS port, u16 data)
 893{
 894	outw(data, port);
 895}
 896
 897void
 898SiS_SetRegLong(SISIOADDRESS port, u32 data)
 899{
 900	outl(data, port);
 901}
 902
 903u8
 904SiS_GetReg(SISIOADDRESS port, u8 index)
 905{
 906	outb(index, port);
 907	return inb(port + 1);
 908}
 909
 910u8
 911SiS_GetRegByte(SISIOADDRESS port)
 912{
 913	return inb(port);
 914}
 915
 916u16
 917SiS_GetRegShort(SISIOADDRESS port)
 918{
 919	return inw(port);
 920}
 921
 922u32
 923SiS_GetRegLong(SISIOADDRESS port)
 924{
 925	return inl(port);
 926}
 927
 928void
 929SiS_SetRegANDOR(SISIOADDRESS Port, u8 Index, u8 DataAND, u8 DataOR)
 930{
 931   u8 temp;
 932
 933   temp = SiS_GetReg(Port, Index);
 934   temp = (temp & (DataAND)) | DataOR;
 935   SiS_SetReg(Port, Index, temp);
 936}
 937
 938void
 939SiS_SetRegAND(SISIOADDRESS Port, u8 Index, u8 DataAND)
 940{
 941   u8 temp;
 942
 943   temp = SiS_GetReg(Port, Index);
 944   temp &= DataAND;
 945   SiS_SetReg(Port, Index, temp);
 946}
 947
 948void
 949SiS_SetRegOR(SISIOADDRESS Port, u8 Index, u8 DataOR)
 950{
 951   u8 temp;
 952
 953   temp = SiS_GetReg(Port, Index);
 954   temp |= DataOR;
 955   SiS_SetReg(Port, Index, temp);
 956}
 957
 958/*********************************************/
 959/*      HELPER: DisplayOn, DisplayOff        */
 960/*********************************************/
 961
 962void
 963SiS_DisplayOn(struct SiS_Private *SiS_Pr)
 964{
 965   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
 966}
 967
 968void
 969SiS_DisplayOff(struct SiS_Private *SiS_Pr)
 970{
 971   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
 972}
 973
 974
 975/*********************************************/
 976/*        HELPER: Init Port Addresses        */
 977/*********************************************/
 978
 979void
 980SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
 981{
 982   SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
 983   SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
 984   SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
 985   SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
 986   SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
 987   SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
 988   SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
 989   SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
 990   SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
 991   SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
 992   SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
 993   SiS_Pr->SiS_P3cc = BaseAddr + 0x1c;
 994   SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
 995   SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
 996   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;
 997   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;
 998   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;
 999   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;
1000   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
1001   SiS_Pr->SiS_DDC_Port  = BaseAddr + 0x14;
1002   SiS_Pr->SiS_VidCapt   = BaseAddr + SIS_VIDEO_CAPTURE;
1003   SiS_Pr->SiS_VidPlay   = BaseAddr + SIS_VIDEO_PLAYBACK;
1004}
1005
1006/*********************************************/
1007/*             HELPER: GetSysFlags           */
1008/*********************************************/
1009
1010static void
1011SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
1012{
1013   unsigned char cr5f, temp1, temp2;
1014
1015   /* 661 and newer: NEVER write non-zero to SR11[7:4] */
1016   /* (SR11 is used for DDC and in enable/disablebridge) */
1017   SiS_Pr->SiS_SensibleSR11 = false;
1018   SiS_Pr->SiS_MyCR63 = 0x63;
1019   if(SiS_Pr->ChipType >= SIS_330) {
1020      SiS_Pr->SiS_MyCR63 = 0x53;
1021      if(SiS_Pr->ChipType >= SIS_661) {
1022         SiS_Pr->SiS_SensibleSR11 = true;
1023      }
1024   }
1025
1026   /* You should use the macros, not these flags directly */
1027
1028   SiS_Pr->SiS_SysFlags = 0;
1029   if(SiS_Pr->ChipType == SIS_650) {
1030      cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
1031      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
1032      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1033      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
1034      temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1035      if((!temp1) || (temp2)) {
1036	 switch(cr5f) {
1037	    case 0x80:
1038	    case 0x90:
1039	    case 0xc0:
1040	       SiS_Pr->SiS_SysFlags |= SF_IsM650;
1041	       break;
1042	    case 0xa0:
1043	    case 0xb0:
1044	    case 0xe0:
1045	       SiS_Pr->SiS_SysFlags |= SF_Is651;
1046	       break;
1047	 }
1048      } else {
1049	 switch(cr5f) {
1050	    case 0x90:
1051	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
1052	       switch(temp1) {
1053		  case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
1054		  case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
1055		  default:   SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
1056	       }
1057	       break;
1058	    case 0xb0:
1059	       SiS_Pr->SiS_SysFlags |= SF_Is652;
1060	       break;
1061	    default:
1062	       SiS_Pr->SiS_SysFlags |= SF_IsM650;
1063	       break;
1064	 }
1065      }
1066   }
1067
1068   if(SiS_Pr->ChipType >= SIS_760 && SiS_Pr->ChipType <= SIS_761) {
1069      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x30) {
1070         SiS_Pr->SiS_SysFlags |= SF_760LFB;
1071      }
1072      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0xf0) {
1073         SiS_Pr->SiS_SysFlags |= SF_760UMA;
1074      }
1075   }
1076}
1077
1078/*********************************************/
1079/*         HELPER: Init PCI & Engines        */
1080/*********************************************/
1081
1082static void
1083SiSInitPCIetc(struct SiS_Private *SiS_Pr)
1084{
1085   switch(SiS_Pr->ChipType) {
1086#ifdef CONFIG_FB_SIS_300
1087   case SIS_300:
1088   case SIS_540:
1089   case SIS_630:
1090   case SIS_730:
1091      /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
1092       *     - RELOCATED VGA IO ENABLED (0x20)
1093       *     - MMIO ENABLED (0x01)
1094       * Leave other bits untouched.
1095       */
1096      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1097      /*  - Enable 2D (0x40)
1098       *  - Enable 3D (0x02)
1099       *  - Enable 3D Vertex command fetch (0x10) ?
1100       *  - Enable 3D command parser (0x08) ?
1101       */
1102      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
1103      break;
1104#endif
1105#ifdef CONFIG_FB_SIS_315
1106   case SIS_315H:
1107   case SIS_315:
1108   case SIS_315PRO:
1109   case SIS_650:
1110   case SIS_740:
1111   case SIS_330:
1112   case SIS_661:
1113   case SIS_741:
1114   case SIS_660:
1115   case SIS_760:
1116   case SIS_761:
1117   case SIS_340:
1118   case XGI_40:
1119      /* See above */
1120      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1121      /*  - Enable 3D G/L transformation engine (0x80)
1122       *  - Enable 2D (0x40)
1123       *  - Enable 3D vertex command fetch (0x10)
1124       *  - Enable 3D command parser (0x08)
1125       *  - Enable 3D (0x02)
1126       */
1127      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
1128      break;
1129   case XGI_20:
1130   case SIS_550:
1131      /* See above */
1132      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x20,0xa1);
1133      /* No 3D engine ! */
1134      /*  - Enable 2D (0x40)
1135       *  - disable 3D
1136       */
1137      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0x60,0x40);
1138      break;
1139#endif
1140   default:
1141      break;
1142   }
1143}
1144
1145/*********************************************/
1146/*             HELPER: SetLVDSetc            */
1147/*********************************************/
1148
1149static
1150void
1151SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
1152{
1153   unsigned short temp;
1154
1155   SiS_Pr->SiS_IF_DEF_LVDS = 0;
1156   SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
1157   SiS_Pr->SiS_IF_DEF_CH70xx = 0;
1158   SiS_Pr->SiS_IF_DEF_CONEX = 0;
1159
1160   SiS_Pr->SiS_ChrontelInit = 0;
1161
1162   if(SiS_Pr->ChipType == XGI_20) return;
1163
1164   /* Check for SiS30x first */
1165   temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1166   if((temp == 1) || (temp == 2)) return;
1167
1168   switch(SiS_Pr->ChipType) {
1169#ifdef CONFIG_FB_SIS_300
1170   case SIS_540:
1171   case SIS_630:
1172   case SIS_730:
1173	temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1174	if((temp >= 2) && (temp <= 5))	SiS_Pr->SiS_IF_DEF_LVDS = 1;
1175	if(temp == 3)			SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
1176	if((temp == 4) || (temp == 5)) {
1177		/* Save power status (and error check) - UNUSED */
1178		SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
1179		SiS_Pr->SiS_IF_DEF_CH70xx = 1;
1180	}
1181	break;
1182#endif
1183#ifdef CONFIG_FB_SIS_315
1184   case SIS_550:
1185   case SIS_650:
1186   case SIS_740:
1187   case SIS_330:
1188	temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) & 0x0e) >> 1;
1189	if((temp >= 2) && (temp <= 3))	SiS_Pr->SiS_IF_DEF_LVDS = 1;
1190	if(temp == 3)			SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1191	break;
1192   case SIS_661:
1193   case SIS_741:
1194   case SIS_660:
1195   case SIS_760:
1196   case SIS_761:
1197   case SIS_340:
1198   case XGI_20:
1199   case XGI_40:
1200	temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0xe0) >> 5;
1201	if((temp >= 2) && (temp <= 3)) 	SiS_Pr->SiS_IF_DEF_LVDS = 1;
1202	if(temp == 3)			SiS_Pr->SiS_IF_DEF_CH70xx = 2;
1203	if(temp == 4)			SiS_Pr->SiS_IF_DEF_CONEX = 1;  /* Not yet supported */
1204	break;
1205#endif
1206   default:
1207	break;
1208   }
1209}
1210
1211/*********************************************/
1212/*          HELPER: Enable DSTN/FSTN         */
1213/*********************************************/
1214
1215void
1216SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable)
1217{
1218   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
1219}
1220
1221void
1222SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable)
1223{
1224   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
1225}
1226
1227/*********************************************/
1228/*            HELPER: Get modeflag           */
1229/*********************************************/
1230
1231unsigned short
1232SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1233		unsigned short ModeIdIndex)
1234{
1235   if(SiS_Pr->UseCustomMode) {
1236      return SiS_Pr->CModeFlag;
1237   } else if(ModeNo <= 0x13) {
1238      return SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
1239   } else {
1240      return SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
1241   }
1242}
1243
1244/*********************************************/
1245/*        HELPER: Determine ROM usage        */
1246/*********************************************/
1247
1248bool
1249SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
1250{
1251   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
1252   unsigned short romversoffs, romvmaj = 1, romvmin = 0;
1253
1254   if(SiS_Pr->ChipType >= XGI_20) {
1255      /* XGI ROMs don't qualify */
1256      return false;
1257   } else if(SiS_Pr->ChipType >= SIS_761) {
1258      /* I very much assume 761, 340 and newer will use new layout */
1259      return true;
1260   } else if(SiS_Pr->ChipType >= SIS_661) {
1261      if((ROMAddr[0x1a] == 'N') &&
1262	 (ROMAddr[0x1b] == 'e') &&
1263	 (ROMAddr[0x1c] == 'w') &&
1264	 (ROMAddr[0x1d] == 'V')) {
1265	 return true;
1266      }
1267      romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
1268      if(romversoffs) {
1269	 if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
1270	    romvmaj = ROMAddr[romversoffs] - '0';
1271	    romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
1272	 }
1273      }
1274      if((romvmaj != 0) || (romvmin >= 92)) {
1275	 return true;
1276      }
1277   } else if(IS_SIS650740) {
1278      if((ROMAddr[0x1a] == 'N') &&
1279	 (ROMAddr[0x1b] == 'e') &&
1280	 (ROMAddr[0x1c] == 'w') &&
1281	 (ROMAddr[0x1d] == 'V')) {
1282	 return true;
1283      }
1284   }
1285   return false;
1286}
1287
1288static void
1289SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
1290{
1291   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
1292   unsigned short romptr = 0;
1293
1294   SiS_Pr->SiS_UseROM = false;
1295   SiS_Pr->SiS_ROMNew = false;
1296   SiS_Pr->SiS_PWDOffset = 0;
1297
1298   if(SiS_Pr->ChipType >= XGI_20) return;
1299
1300   if((ROMAddr) && (SiS_Pr->UseROM)) {
1301      if(SiS_Pr->ChipType == SIS_300) {
1302	 /* 300: We check if the code starts below 0x220 by
1303	  * checking the jmp instruction at the beginning
1304	  * of the BIOS image.
1305	  */
1306	 if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
1307	    SiS_Pr->SiS_UseROM = true;
1308      } else if(SiS_Pr->ChipType < SIS_315H) {
1309	 /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
1310	  * the others do as well
1311	  */
1312	 SiS_Pr->SiS_UseROM = true;
1313      } else {
1314	 /* 315/330 series stick to the standard(s) */
1315	 SiS_Pr->SiS_UseROM = true;
1316	 if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
1317	    SiS_Pr->SiS_EMIOffset = 14;
1318	    SiS_Pr->SiS_PWDOffset = 17;
1319	    SiS_Pr->SiS661LCD2TableSize = 36;
1320	    /* Find out about LCD data table entry size */
1321	    if((romptr = SISGETROMW(0x0102))) {
1322	       if(ROMAddr[romptr + (32 * 16)] == 0xff)
1323		  SiS_Pr->SiS661LCD2TableSize = 32;
1324	       else if(ROMAddr[romptr + (34 * 16)] == 0xff)
1325		  SiS_Pr->SiS661LCD2TableSize = 34;
1326	       else if(ROMAddr[romptr + (36 * 16)] == 0xff)	   /* 0.94, 2.05.00+ */
1327		  SiS_Pr->SiS661LCD2TableSize = 36;
1328	       else if( (ROMAddr[romptr + (38 * 16)] == 0xff) ||   /* 2.00.00 - 2.02.00 */
1329		 	(ROMAddr[0x6F] & 0x01) ) {		   /* 2.03.00 - <2.05.00 */
1330		  SiS_Pr->SiS661LCD2TableSize = 38;		   /* UMC data layout abandoned at 2.05.00 */
1331		  SiS_Pr->SiS_EMIOffset = 16;
1332		  SiS_Pr->SiS_PWDOffset = 19;
1333	       }
1334	    }
1335	 }
1336      }
1337   }
1338}
1339
1340/*********************************************/
1341/*        HELPER: SET SEGMENT REGISTERS      */
1342/*********************************************/
1343
1344static void
1345SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value)
1346{
1347   unsigned short temp;
1348
1349   value &= 0x00ff;
1350   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
1351   temp |= (value >> 4);
1352   SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1353   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0;
1354   temp |= (value & 0x0f);
1355   SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1356}
1357
1358static void
1359SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value)
1360{
1361   unsigned short temp;
1362
1363   value &= 0x00ff;
1364   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
1365   temp |= (value & 0xf0);
1366   SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
1367   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f;
1368   temp |= (value << 4);
1369   SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
1370}
1371
1372static void
1373SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value)
1374{
1375   SiS_SetSegRegLower(SiS_Pr, value);
1376   SiS_SetSegRegUpper(SiS_Pr, value);
1377}
1378
1379static void
1380SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr)
1381{
1382   SiS_SetSegmentReg(SiS_Pr, 0);
1383}
1384
1385static void
1386SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value)
1387{
1388   unsigned short temp = value >> 8;
1389
1390   temp &= 0x07;
1391   temp |= (temp << 4);
1392   SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
1393   SiS_SetSegmentReg(SiS_Pr, value);
1394}
1395
1396static void
1397SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr)
1398{
1399   SiS_SetSegmentRegOver(SiS_Pr, 0);
1400}
1401
1402static void
1403SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
1404{
1405   if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) {
1406      SiS_ResetSegmentReg(SiS_Pr);
1407      SiS_ResetSegmentRegOver(SiS_Pr);
1408   }
1409}
1410
1411/*********************************************/
1412/*             HELPER: GetVBType             */
1413/*********************************************/
1414
1415static
1416void
1417SiS_GetVBType(struct SiS_Private *SiS_Pr)
1418{
1419   unsigned short flag = 0, rev = 0, nolcd = 0;
1420   unsigned short p4_0f, p4_25, p4_27;
1421
1422   SiS_Pr->SiS_VBType = 0;
1423
1424   if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
1425      return;
1426
1427   if(SiS_Pr->ChipType == XGI_20)
1428      return;
1429
1430   flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
1431
1432   if(flag > 3)
1433      return;
1434
1435   rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
1436
1437   if(flag >= 2) {
1438      SiS_Pr->SiS_VBType = VB_SIS302B;
1439   } else if(flag == 1) {
1440      if(rev >= 0xC0) {
1441	 SiS_Pr->SiS_VBType = VB_SIS301C;
1442      } else if(rev >= 0xB0) {
1443	 SiS_Pr->SiS_VBType = VB_SIS301B;
1444	 /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
1445	 nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
1446	 if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
1447      } else {
1448	 SiS_Pr->SiS_VBType = VB_SIS301;
1449      }
1450   }
1451   if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
1452      if(rev >= 0xE0) {
1453	 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
1454	 if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
1455	 else 	 	  SiS_Pr->SiS_VBType = VB_SIS301C;  /* VB_SIS302ELV; */
1456      } else if(rev >= 0xD0) {
1457	 SiS_Pr->SiS_VBType = VB_SIS301LV;
1458      }
1459   }
1460   if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
1461      p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f);
1462      p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25);
1463      p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27);
1464      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f);
1465      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08);
1466      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd);
1467      if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) {
1468         SiS_Pr->SiS_VBType |= VB_UMC;
1469      }
1470      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27);
1471      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25);
1472      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f);
1473   }
1474}
1475
1476/*********************************************/
1477/*           HELPER: Check RAM size          */
1478/*********************************************/
1479
1480static bool
1481SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
1482		unsigned short ModeIdIndex)
1483{
1484   unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024);
1485   unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
1486   unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
1487
1488   if(!AdapterMemSize) return true;
1489
1490   if(AdapterMemSize < memorysize) return false;
1491   return true;
1492}
1493
1494/*********************************************/
1495/*           HELPER: Get DRAM type           */
1496/*********************************************/
1497
1498#ifdef CONFIG_FB_SIS_315
1499static unsigned char
1500SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
1501{
1502   unsigned char data;
1503
1504   if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
1505      data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
1506   } else {
1507      if(SiS_Pr->ChipType >= XGI_20) {
1508         /* Do I need this? SR17 seems to be zero anyway... */
1509	 data = 0;
1510      } else if(SiS_Pr->ChipType >= SIS_340) {
1511	 /* TODO */
1512	 data = 0;
1513      } if(SiS_Pr->ChipType >= SIS_661) {
1514	 if(SiS_Pr->SiS_ROMNew) {
1515	    data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
1516	 } else {
1517	    data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
1518	 }
1519      } else if(IS_SIS550650740) {
1520	 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
1521      } else {	/* 315, 330 */
1522	 data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
1523	 if(SiS_Pr->ChipType == SIS_330) {
1524	    if(data > 1) {
1525	       switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) {
1526	       case 0x00: data = 1; break;
1527	       case 0x10: data = 3; break;
1528	       case 0x20: data = 3; break;
1529	       case 0x30: data = 2; break;
1530	       }
1531	    } else {
1532	       data = 0;
1533	    }
1534	 }
1535      }
1536   }
1537
1538   return data;
1539}
1540
1541static unsigned short
1542SiS_GetMCLK(struct SiS_Private *SiS_Pr)
1543{
1544   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
1545   unsigned short index;
1546
1547   index = SiS_Get310DRAMType(SiS_Pr);
1548   if(SiS_Pr->ChipType >= SIS_661) {
1549      if(SiS_Pr->SiS_ROMNew) {
1550	 return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3))));
1551      }
1552      return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1553   } else if(index >= 4) {
1554      return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK);
1555   } else {
1556      return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
1557   }
1558}
1559#endif
1560
1561/*********************************************/
1562/*           HELPER: ClearBuffer             */
1563/*********************************************/
1564
1565static void
1566SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
1567{
1568   unsigned char  SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress;
1569   unsigned int   memsize = SiS_Pr->VideoMemorySize;
1570   unsigned short SISIOMEMTYPE *pBuffer;
1571   int i;
1572
1573   if(!memaddr || !memsize) return;
1574
1575   if(SiS_Pr->SiS_ModeType >= ModeEGA) {
1576      if(ModeNo > 0x13) {
1577	 memset_io(memaddr, 0, memsize);
1578      } else {
1579	 pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1580	 for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
1581      }
1582   } else if(SiS_Pr->SiS_ModeType < ModeCGA) {
1583      pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
1584      for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
1585   } else {
1586      memset_io(memaddr, 0, 0x8000);
1587   }
1588}
1589
1590/*********************************************/
1591/*           HELPER: SearchModeID            */
1592/*********************************************/
1593
1594bool
1595SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
1596		unsigned short *ModeIdIndex)
1597{
1598   unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO;
1599
1600   if((*ModeNo) <= 0x13) {
1601
1602      if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
1603
1604      for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1605	 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
1606	 if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return false;
1607      }
1608
1609      if((*ModeNo) == 0x07) {
1610	  if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
1611	  /* else 350 lines */
1612      }
1613      if((*ModeNo) <= 0x03) {
1614	 if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
1615	 if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
1616	 /* else 350 lines  */
1617      }
1618      /* else 200 lines  */
1619
1620   } else {
1621
1622      for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
1623	 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
1624	 if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return false;
1625      }
1626
1627   }
1628   return true;
1629}
1630
1631/*********************************************/
1632/*            HELPER: GetModePtr             */
1633/*********************************************/
1634
1635unsigned short
1636SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
1637{
1638   unsigned short index;
1639
1640   if(ModeNo <= 0x13) {
1641      index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
1642   } else {
1643      if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
1644      else index = 0x0F;
1645   }
1646   return index;
1647}
1648
1649/****************************************…

Large files files are truncated, but you can click here to view the full file