brintos

brintos / linux-shallow public Read only

0
0
Text · 351.2 KiB · 0932907 Raw
11380 lines · c
1/* $XFree86$ */2/* $XdotOrg$ */3/*4 * Mode initializing code (CRT2 section)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 V3XT/V5/V8, Z78 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)9 *10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria11 *12 * If distributed as part of the Linux kernel, the following license terms13 * apply:14 *15 * * This program is free software; you can redistribute it and/or modify16 * * it under the terms of the GNU General Public License as published by17 * * 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 of22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the23 * * GNU General Public License for more details.24 * *25 * * You should have received a copy of the GNU General Public License26 * * along with this program; if not, write to the Free Software27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA28 *29 * Otherwise, the following license terms apply:30 *31 * * Redistribution and use in source and binary forms, with or without32 * * modification, are permitted provided that the following conditions33 * * are met:34 * * 1) Redistributions of source code must retain the above copyright35 * *    notice, this list of conditions and the following disclaimer.36 * * 2) Redistributions in binary form must reproduce the above copyright37 * *    notice, this list of conditions and the following disclaimer in the38 * *    documentation and/or other materials provided with the distribution.39 * * 3) The name of the author may not be used to endorse or promote products40 * *    derived from this software without specific prior written permission.41 * *42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES44 * * 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, BUT47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF51 * * 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 60#if 161#define SET_EMI		/* 302LV/ELV: Set EMI values */62#endif63 64#if 165#define SET_PWD		/* 301/302LV: Set PWD */66#endif67 68#define COMPAL_HACK	/* Needed for Compal 1400x1050 (EMI) */69#define COMPAQ_HACK	/* Needed for Inventec/Compaq 1280x1024 (EMI) */70#define ASUS_HACK	/* Needed for Asus A2H 1024x768 (EMI) */71 72#include "init301.h"73 74#ifdef CONFIG_FB_SIS_30075#include "oem300.h"76#endif77 78#ifdef CONFIG_FB_SIS_31579#include "oem310.h"80#endif81 82#define SiS_I2CDELAY      100083#define SiS_I2CDELAYSHORT  15084 85static const unsigned char SiS_YPbPrTable[3][64] = {86  {87    0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,88    0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,89    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,90    0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,91    0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,92    0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,93    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,94    0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x0095  },96  {97    0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,98    0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,99    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,100    0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,101    0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,102    0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,103    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,104    0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00105  },106  {107#if 0 /* OK, but sticks to left edge */108    0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,109    0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,110    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,111    0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,112    0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,113    0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,114    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,115    0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00116#endif117#if 1 /* Perfect */118    0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,119    0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,120    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,121    0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,122    0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,123    0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,124    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,125    0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00126#endif127  }128};129 130static const unsigned char SiS_TVPhase[] =131{132	0x21,0xED,0xBA,0x08,	/* 0x00 SiS_NTSCPhase */133	0x2A,0x05,0xE3,0x00,	/* 0x01 SiS_PALPhase */134	0x21,0xE4,0x2E,0x9B,	/* 0x02 SiS_PALMPhase */135	0x21,0xF4,0x3E,0xBA,	/* 0x03 SiS_PALNPhase */136	0x1E,0x8B,0xA2,0xA7,137	0x1E,0x83,0x0A,0xE0,	/* 0x05 SiS_SpecialPhaseM */138	0x00,0x00,0x00,0x00,139	0x00,0x00,0x00,0x00,140	0x21,0xF0,0x7B,0xD6,	/* 0x08 SiS_NTSCPhase2 */141	0x2A,0x09,0x86,0xE9,	/* 0x09 SiS_PALPhase2 */142	0x21,0xE6,0xEF,0xA4,	/* 0x0a SiS_PALMPhase2 */143	0x21,0xF6,0x94,0x46,	/* 0x0b SiS_PALNPhase2 */144	0x1E,0x8B,0xA2,0xA7,145	0x1E,0x83,0x0A,0xE0,	/* 0x0d SiS_SpecialPhaseM */146	0x00,0x00,0x00,0x00,147	0x00,0x00,0x00,0x00,148	0x1e,0x8c,0x5c,0x7a,	/* 0x10 SiS_SpecialPhase */149	0x25,0xd4,0xfd,0x5e	/* 0x11 SiS_SpecialPhaseJ */150};151 152static const unsigned char SiS_HiTVGroup3_1[] = {153    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,154    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,155    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,156    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,157    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,158    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,159    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,160    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01161};162 163static const unsigned char SiS_HiTVGroup3_2[] = {164    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,165    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,166    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,167    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,168    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,169    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,170    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,171    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01172};173 174/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */175#ifdef CONFIG_FB_SIS_315176static const unsigned char SiS_Part2CLVX_1[] = {177    0x00,0x00,178    0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,179    0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,180    0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,181    0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E182};183 184static const unsigned char SiS_Part2CLVX_2[] = {185    0x00,0x00,186    0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,187    0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,188    0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,189    0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E190};191 192static const unsigned char SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */193    0xE0,0x01,194    0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,195    0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,196    0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,197    0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,198    0x58,0x02,199    0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,200    0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,201    0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,202    0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,203    0x00,0x03,204    0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,205    0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,206    0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,207    0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,208    0xFF,0xFF209};210 211static const unsigned char SiS_Part2CLVX_4[] = {   /* PAL */212    0x58,0x02,213    0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,214    0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,215    0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,216    0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,217    0x00,0x03,218    0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,219    0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,220    0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,221    0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,222    0x40,0x02,223    0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,224    0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,225    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,226    0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,227    0xFF,0xFF228};229 230static const unsigned char SiS_Part2CLVX_5[] = {   /* 750p */231    0x00,0x03,232    0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,233    0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,234    0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,235    0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,236    0xFF,0xFF237};238 239static const unsigned char SiS_Part2CLVX_6[] = {   /* 1080i */240    0x00,0x04,241    0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,242    0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,243    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,244    0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,245    0xFF,0xFF,246};247 248/* 661 et al LCD data structure (2.03.00) */249static const unsigned char SiS_LCDStruct661[] = {250    /* 1024x768 */251/*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */252    0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,253    0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,254    /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */255    /*					      VESA    non-VESA  noscale */256    /* 1280x1024 */257    0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,258    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,259    /* 1400x1050 */260    0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,261    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,262    /* 1600x1200 */263    0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,264    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,265    /* 1280x768 (_2) */266    0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,267    0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,268    /* 1280x720 */269    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,270    0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,271    /* 1280x800 (_2) */272    0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,273    0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,274    /* 1680x1050 */275    0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,276    0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,277    /* 1280x800_3 */278    0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,279    0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,280    /* 800x600 */281    0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,282    0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,283    /* 1280x854 */284    0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,285    0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08286};287#endif288 289#ifdef CONFIG_FB_SIS_300290static unsigned char SiS300_TrumpionData[14][80] = {291  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,292    0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,293    0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,294    0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,295    0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },296  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,297    0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,298    0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,299    0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,300    0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },301  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,302    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,303    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,304    0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,305    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },306  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,307    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,308    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,309    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,310    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },311  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,312    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,313    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,314    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,315    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },316  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,317    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,318    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,319    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,320    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },321  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,322    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,323    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,324    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,325    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },326  /* variant 2 */327  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,328    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,329    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,330    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,331    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },332  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,333    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,334    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,335    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,336    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },337  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,338    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,339    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,340    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,341    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },342  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,343    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,344    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,345    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,346    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },347  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,348    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,349    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,350    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,351    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },352  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,353    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,354    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,355    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,356    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },357  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,358    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,359    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,360    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,361    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }362};363#endif364 365#ifdef CONFIG_FB_SIS_315366static void	SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);367static void	SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);368static void	SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);369static void	SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);370#endif /* 315 */371 372#ifdef CONFIG_FB_SIS_300373static  bool	SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);374#endif375 376static unsigned short	SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,377				int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,378				bool checkcr32, unsigned int VBFlags2);379static unsigned short	SiS_ProbeDDC(struct SiS_Private *SiS_Pr);380static unsigned short	SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,381				unsigned char *buffer);382static void		SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);383static unsigned short	SiS_SetStart(struct SiS_Private *SiS_Pr);384static unsigned short	SiS_SetStop(struct SiS_Private *SiS_Pr);385static unsigned short	SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);386static unsigned short	SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);387static unsigned short	SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);388static unsigned short	SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);389static unsigned short	SiS_CheckACK(struct SiS_Private *SiS_Pr);390static unsigned short	SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);391static unsigned short	SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);392static unsigned short	SiS_PrepareDDC(struct SiS_Private *SiS_Pr);393static void		SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);394static unsigned short	SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);395 396#ifdef CONFIG_FB_SIS_300397static void		SiS_OEM300Setting(struct SiS_Private *SiS_Pr,398				unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);399static void		SetOEMLCDData2(struct SiS_Private *SiS_Pr,400				unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);401#endif402#ifdef CONFIG_FB_SIS_315403static void		SiS_OEM310Setting(struct SiS_Private *SiS_Pr,404				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);405static void		SiS_OEM661Setting(struct SiS_Private *SiS_Pr,406				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);407static void		SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);408#endif409 410static unsigned short	SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);411static void		SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);412 413/*********************************************/414/*         HELPER: Lock/Unlock CRT2          */415/*********************************************/416 417void418SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)419{420   if(SiS_Pr->ChipType == XGI_20)421      return;422   else if(SiS_Pr->ChipType >= SIS_315H)423      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);424   else425      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);426}427 428static429void430SiS_LockCRT2(struct SiS_Private *SiS_Pr)431{432   if(SiS_Pr->ChipType == XGI_20)433      return;434   else if(SiS_Pr->ChipType >= SIS_315H)435      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);436   else437      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);438}439 440/*********************************************/441/*            HELPER: Write SR11             */442/*********************************************/443 444static void445SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)446{447   if(SiS_Pr->ChipType >= SIS_661) {448      DataAND &= 0x0f;449      DataOR  &= 0x0f;450   }451   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);452}453 454/*********************************************/455/*    HELPER: Get Pointer to LCD structure   */456/*********************************************/457 458#ifdef CONFIG_FB_SIS_315459static unsigned char *460GetLCDStructPtr661(struct SiS_Private *SiS_Pr)461{462   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;463   unsigned char  *myptr = NULL;464   unsigned short romindex = 0, reg = 0, idx = 0;465 466   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable467    * due to the variaty of panels the BIOS doesn't know about.468    * Exception: If the BIOS has better knowledge (such as in case469    * of machines with a 301C and a panel that does not support DDC)470    * use the BIOS data as well.471    */472 473   if((SiS_Pr->SiS_ROMNew) &&474      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {475 476      if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;477      else                           reg = 0x7d;478 479      idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;480 481      if(idx < (8*26)) {482         myptr = (unsigned char *)&SiS_LCDStruct661[idx];483      }484      romindex = SISGETROMW(0x100);485      if(romindex) {486         romindex += idx;487         myptr = &ROMAddr[romindex];488      }489   }490   return myptr;491}492 493static unsigned short494GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)495{496   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;497   unsigned short romptr = 0;498 499   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable500    * due to the variaty of panels the BIOS doesn't know about.501    * Exception: If the BIOS has better knowledge (such as in case502    * of machines with a 301C and a panel that does not support DDC)503    * use the BIOS data as well.504    */505 506   if((SiS_Pr->SiS_ROMNew) &&507      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {508      romptr = SISGETROMW(0x102);509      romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);510   }511 512   return romptr;513}514#endif515 516/*********************************************/517/*           Adjust Rate for CRT2            */518/*********************************************/519 520static bool521SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,522		unsigned short RRTI, unsigned short *i)523{524   unsigned short checkmask=0, modeid, infoflag;525 526   modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;527 528   if(SiS_Pr->SiS_VBType & VB_SISVB) {529 530      if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {531 532	 checkmask |= SupportRAMDAC2;533	 if(SiS_Pr->ChipType >= SIS_315H) {534	    checkmask |= SupportRAMDAC2_135;535	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {536	       checkmask |= SupportRAMDAC2_162;537	       if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {538		  checkmask |= SupportRAMDAC2_202;539	       }540	    }541	 }542 543      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {544 545	 checkmask |= SupportLCD;546	 if(SiS_Pr->ChipType >= SIS_315H) {547	    if(SiS_Pr->SiS_VBType & VB_SISVB) {548	       if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {549	          if(modeid == 0x2e) checkmask |= Support64048060Hz;550	       }551	    }552	 }553 554      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {555 556	 checkmask |= SupportHiVision;557 558      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {559 560	 checkmask |= SupportTV;561	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {562	    checkmask |= SupportTV1024;563	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {564	       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {565	          checkmask |= SupportYPbPr750p;566	       }567	    }568	 }569 570      }571 572   } else {	/* LVDS */573 574      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {575	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {576	    checkmask |= SupportCHTV;577	 }578      }579 580      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {581	 checkmask |= SupportLCD;582      }583 584   }585 586   /* Look backwards in table for matching CRT2 mode */587   for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {588      infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;589      if(infoflag & checkmask) return true;590      if((*i) == 0) break;591   }592 593   /* Look through the whole mode-section of the table from the beginning594    * for a matching CRT2 mode if no mode was found yet.595    */596   for((*i) = 0; ; (*i)++) {597      if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;598      infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;599      if(infoflag & checkmask) return true;600   }601   return false;602}603 604/*********************************************/605/*              Get rate index               */606/*********************************************/607 608unsigned short609SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)610{611   unsigned short RRTI,i,backup_i;612   unsigned short modeflag,index,temp,backupindex;613   static const unsigned short LCDRefreshIndex[] = {614		0x00, 0x00, 0x01, 0x01,615		0x01, 0x01, 0x01, 0x01,616		0x01, 0x01, 0x01, 0x01,617		0x01, 0x01, 0x01, 0x01,618		0x00, 0x00, 0x00, 0x00619   };620 621   /* Do NOT check for UseCustomMode here, will skrew up FIFO */622   if(ModeNo == 0xfe) return 0;623 624   if(ModeNo <= 0x13) {625      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;626   } else {627      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;628   }629 630   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {631      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {632	 if(modeflag & HalfDCLK) return 0;633      }634   }635 636   if(ModeNo < 0x14) return 0xFFFF;637 638   index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;639   backupindex = index;640 641   if(index > 0) index--;642 643   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {644      if(SiS_Pr->SiS_VBType & VB_SISVB) {645	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {646	    if(SiS_Pr->SiS_VBType & VB_NoLCD)		 index = 0;647	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;648	 }649	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {650	    if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {651	       temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];652	       if(index > temp) index = temp;653	    }654	 }655      } else {656	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;657	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {658	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;659	 }660      }661   }662 663   RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;664   ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;665 666   if(SiS_Pr->ChipType >= SIS_315H) {667      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {668	 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||669	     (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {670	    if(backupindex <= 1) RRTI++;671	 }672      }673   }674 675   i = 0;676   do {677      if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;678      temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;679      temp &= ModeTypeMask;680      if(temp < SiS_Pr->SiS_ModeType) break;681      i++;682      index--;683   } while(index != 0xFFFF);684 685   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {686      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {687	 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;688	 if(temp & InterlaceMode) i++;689      }690   }691 692   i--;693 694   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {695      backup_i = i;696      if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {697	 i = backup_i;698      }699   }700 701   return (RRTI + i);702}703 704/*********************************************/705/*            STORE CRT2 INFO in CR34        */706/*********************************************/707 708static void709SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)710{711   unsigned short temp1, temp2;712 713   /* Store CRT1 ModeNo in CR34 */714   SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);715   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;716   temp2 = ~(SetInSlaveMode >> 8);717   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);718}719 720/*********************************************/721/*    HELPER: GET SOME DATA FROM BIOS ROM    */722/*********************************************/723 724#ifdef CONFIG_FB_SIS_300725static bool726SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)727{728   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;729   unsigned short temp,temp1;730 731   if(SiS_Pr->SiS_UseROM) {732      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {733	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);734	 temp1 = SISGETROMW(0x23b);735	 if(temp1 & temp) return true;736      }737   }738   return false;739}740 741static bool742SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)743{744   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;745   unsigned short temp,temp1;746 747   if(SiS_Pr->SiS_UseROM) {748      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {749	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);750	 temp1 = SISGETROMW(0x23d);751	 if(temp1 & temp) return true;752      }753   }754   return false;755}756#endif757 758/*********************************************/759/*          HELPER: DELAY FUNCTIONS          */760/*********************************************/761 762void763SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)764{765   while (delaytime-- > 0)766      SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);767}768 769#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)770static void771SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)772{773   SiS_DDC2Delay(SiS_Pr, delay * 36);774}775#endif776 777#ifdef CONFIG_FB_SIS_315778static void779SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)780{781   while(delay--) {782      SiS_GenericDelay(SiS_Pr, 6623);783   }784}785#endif786 787#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)788static void789SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)790{791   while(delay--) {792      SiS_GenericDelay(SiS_Pr, 66);793   }794}795#endif796 797static void798SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)799{800#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)801   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;802   unsigned short PanelID, DelayIndex, Delay=0;803#endif804 805   if(SiS_Pr->ChipType < SIS_315H) {806 807#ifdef CONFIG_FB_SIS_300808 809      PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);810      if(SiS_Pr->SiS_VBType & VB_SISVB) {811	 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;812	 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;813      }814      DelayIndex = PanelID >> 4;815      if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {816	 Delay = 3;817      } else {818	 if(DelayTime >= 2) DelayTime -= 2;819	 if(!(DelayTime & 0x01)) {820	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];821	 } else {822	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];823	 }824	 if(SiS_Pr->SiS_UseROM) {825	    if(ROMAddr[0x220] & 0x40) {826	       if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];827	       else 	    	       Delay = (unsigned short)ROMAddr[0x226];828	    }829	 }830      }831      SiS_ShortDelay(SiS_Pr, Delay);832 833#endif  /* CONFIG_FB_SIS_300 */834 835   } else {836 837#ifdef CONFIG_FB_SIS_315838 839      if((SiS_Pr->ChipType >= SIS_661)    ||840	 (SiS_Pr->ChipType <= SIS_315PRO) ||841	 (SiS_Pr->ChipType == SIS_330)    ||842	 (SiS_Pr->SiS_ROMNew)) {843 844	 if(!(DelayTime & 0x01)) {845	    SiS_DDC2Delay(SiS_Pr, 0x1000);846	 } else {847	    SiS_DDC2Delay(SiS_Pr, 0x4000);848	 }849 850      } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS; Special */851 852	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {853	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);854	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {855	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;856	    }857	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {858	       DelayIndex = PanelID & 0x0f;859	    } else {860	       DelayIndex = PanelID >> 4;861	    }862	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {863	       Delay = 3;864	    } else {865	       if(DelayTime >= 2) DelayTime -= 2;866	       if(!(DelayTime & 0x01)) {867		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];868		} else {869		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];870	       }871	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {872		  if(ROMAddr[0x13c] & 0x40) {873		     if(!(DelayTime & 0x01)) {874			Delay = (unsigned short)ROMAddr[0x17e];875		     } else {876			Delay = (unsigned short)ROMAddr[0x17f];877		     }878		  }879	       }880	    }881	    SiS_ShortDelay(SiS_Pr, Delay);882	 }883 884      } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */885 886	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;887	 if(!(DelayTime & 0x01)) {888	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];889	 } else {890	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];891	 }892	 Delay <<= 8;893	 SiS_DDC2Delay(SiS_Pr, Delay);894 895      }896 897#endif /* CONFIG_FB_SIS_315 */898 899   }900}901 902#ifdef CONFIG_FB_SIS_315903static void904SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)905{906   int i;907   for(i = 0; i < DelayLoop; i++) {908      SiS_PanelDelay(SiS_Pr, DelayTime);909   }910}911#endif912 913/*********************************************/914/*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */915/*********************************************/916 917void918SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)919{920   unsigned short watchdog;921 922   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;923   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;924 925   watchdog = 65535;926   while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);927   watchdog = 65535;928   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);929}930 931#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)932static void933SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)934{935   unsigned short watchdog;936 937   watchdog = 65535;938   while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);939   watchdog = 65535;940   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);941}942#endif943 944static void945SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)946{947   if(SiS_Pr->ChipType < SIS_315H) {948#ifdef CONFIG_FB_SIS_300949      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {950	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;951      }952      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {953	 SiS_WaitRetrace1(SiS_Pr);954      } else {955	 SiS_WaitRetrace2(SiS_Pr, 0x25);956      }957#endif958   } else {959#ifdef CONFIG_FB_SIS_315960      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {961	 SiS_WaitRetrace1(SiS_Pr);962      } else {963	 SiS_WaitRetrace2(SiS_Pr, 0x30);964      }965#endif966   }967}968 969static void970SiS_VBWait(struct SiS_Private *SiS_Pr)971{972   unsigned short tempal,temp,i,j;973 974   temp = 0;975   for(i = 0; i < 3; i++) {976     for(j = 0; j < 100; j++) {977        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);978        if(temp & 0x01) {979	   if((tempal & 0x08))  continue;980	   else break;981        } else {982	   if(!(tempal & 0x08)) continue;983	   else break;984        }985     }986     temp ^= 0x01;987   }988}989 990static void991SiS_VBLongWait(struct SiS_Private *SiS_Pr)992{993   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {994      SiS_VBWait(SiS_Pr);995   } else {996      SiS_WaitRetrace1(SiS_Pr);997   }998}999 1000/*********************************************/1001/*               HELPER: MISC                */1002/*********************************************/1003 1004#ifdef CONFIG_FB_SIS_3001005static bool1006SiS_Is301B(struct SiS_Private *SiS_Pr)1007{1008   if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;1009   return false;1010}1011#endif1012 1013static bool1014SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)1015{1016   if(SiS_Pr->ChipType == SIS_730) {1017      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;1018   }1019   if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;1020   return false;1021}1022 1023bool1024SiS_IsDualEdge(struct SiS_Private *SiS_Pr)1025{1026#ifdef CONFIG_FB_SIS_3151027   if(SiS_Pr->ChipType >= SIS_315H) {1028      if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {1029	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;1030      }1031   }1032#endif1033   return false;1034}1035 1036bool1037SiS_IsVAMode(struct SiS_Private *SiS_Pr)1038{1039#ifdef CONFIG_FB_SIS_3151040   unsigned short flag;1041 1042   if(SiS_Pr->ChipType >= SIS_315H) {1043      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);1044      if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;1045   }1046#endif1047   return false;1048}1049 1050#ifdef CONFIG_FB_SIS_3151051static bool1052SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)1053{1054   if(SiS_IsVAMode(SiS_Pr))  return true;1055   if(SiS_CRT2IsLCD(SiS_Pr)) return true;1056   return false;1057}1058#endif1059 1060static bool1061SiS_IsDualLink(struct SiS_Private *SiS_Pr)1062{1063#ifdef CONFIG_FB_SIS_3151064   if(SiS_Pr->ChipType >= SIS_315H) {1065      if((SiS_CRT2IsLCD(SiS_Pr)) ||1066         (SiS_IsVAMode(SiS_Pr))) {1067	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;1068      }1069   }1070#endif1071   return false;1072}1073 1074#ifdef CONFIG_FB_SIS_3151075static bool1076SiS_TVEnabled(struct SiS_Private *SiS_Pr)1077{1078   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;1079   if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {1080      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;1081   }1082   return false;1083}1084#endif1085 1086#ifdef CONFIG_FB_SIS_3151087static bool1088SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)1089{1090   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;1091   return false;1092}1093#endif1094 1095#ifdef CONFIG_FB_SIS_3151096static bool1097SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)1098{1099   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {1100      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;1101   }1102   return false;1103}1104#endif1105 1106#ifdef CONFIG_FB_SIS_3151107static bool1108SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)1109{1110   unsigned short flag;1111 1112   if(SiS_Pr->ChipType == SIS_650) {1113      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;1114      /* Check for revision != A0 only */1115      if((flag == 0xe0) || (flag == 0xc0) ||1116         (flag == 0xb0) || (flag == 0x90)) return false;1117   } else if(SiS_Pr->ChipType >= SIS_661) return false;1118   return true;1119}1120#endif1121 1122#ifdef CONFIG_FB_SIS_3151123static bool1124SiS_IsYPbPr(struct SiS_Private *SiS_Pr)1125{1126   if(SiS_Pr->ChipType >= SIS_315H) {1127      /* YPrPb = 0x08 */1128      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;1129   }1130   return false;1131}1132#endif1133 1134#ifdef CONFIG_FB_SIS_3151135static bool1136SiS_IsChScart(struct SiS_Private *SiS_Pr)1137{1138   if(SiS_Pr->ChipType >= SIS_315H) {1139      /* Scart = 0x04 */1140      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;1141   }1142   return false;1143}1144#endif1145 1146#ifdef CONFIG_FB_SIS_3151147static bool1148SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)1149{1150   unsigned short flag;1151 1152   if(SiS_Pr->ChipType >= SIS_315H) {1153      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);1154      if(flag & SetCRT2ToTV)        return true;1155      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);1156      if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */1157      if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */1158   } else {1159      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);1160      if(flag & SetCRT2ToTV)        return true;1161   }1162   return false;1163}1164#endif1165 1166#ifdef CONFIG_FB_SIS_3151167static bool1168SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)1169{1170   unsigned short flag;1171 1172   if(SiS_Pr->ChipType >= SIS_315H) {1173      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);1174      if(flag & SetCRT2ToLCD) return true;1175      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);1176      if(flag & SetToLCDA)    return true;1177   } else {1178      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);1179      if(flag & SetCRT2ToLCD) return true;1180   }1181   return false;1182}1183#endif1184 1185static bool1186SiS_HaveBridge(struct SiS_Private *SiS_Pr)1187{1188   unsigned short flag;1189 1190   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {1191      return true;1192   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {1193      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);1194      if((flag == 1) || (flag == 2)) return true;1195   }1196   return false;1197}1198 1199static bool1200SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)1201{1202   unsigned short flag;1203 1204   if(SiS_HaveBridge(SiS_Pr)) {1205      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);1206      if(SiS_Pr->ChipType < SIS_315H) {1207	flag &= 0xa0;1208	if((flag == 0x80) || (flag == 0x20)) return true;1209      } else {1210	flag &= 0x50;1211	if((flag == 0x40) || (flag == 0x10)) return true;1212      }1213   }1214   return false;1215}1216 1217static bool1218SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)1219{1220   unsigned short flag1;1221 1222   flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);1223   if(flag1 & (SetInSlaveMode >> 8)) return true;1224   return false;1225}1226 1227/*********************************************/1228/*       GET VIDEO BRIDGE CONFIG INFO        */1229/*********************************************/1230 1231/* Setup general purpose IO for Chrontel communication */1232#ifdef CONFIG_FB_SIS_3001233void1234SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)1235{1236   unsigned int   acpibase;1237   unsigned short temp;1238 1239   if(!(SiS_Pr->SiS_ChSW)) return;1240 1241   acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);1242   acpibase &= 0xFFFF;1243   if(!acpibase) return;1244   temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */1245   temp &= 0xFEFF;1246   SiS_SetRegShort((acpibase + 0x3c), temp);1247   temp = SiS_GetRegShort((acpibase + 0x3c));1248   temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */1249   temp &= 0xFEFF;1250   if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;1251   SiS_SetRegShort((acpibase + 0x3a), temp);1252   temp = SiS_GetRegShort((acpibase + 0x3a));1253}1254#endif1255 1256void1257SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,1258		unsigned short ModeIdIndex, int checkcrt2mode)1259{1260   unsigned short tempax, tempbx, temp;1261   unsigned short modeflag, resinfo = 0;1262 1263   SiS_Pr->SiS_SetFlag = 0;1264 1265   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);1266 1267   SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;1268 1269   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {1270      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;1271   }1272 1273   tempbx = 0;1274 1275   if(SiS_HaveBridge(SiS_Pr)) {1276 1277	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);1278	tempbx |= temp;1279	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;1280	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);1281	tempbx |= tempax;1282 1283#ifdef CONFIG_FB_SIS_3151284	if(SiS_Pr->ChipType >= SIS_315H) {1285	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {1286	      if(ModeNo == 0x03) {1287		 /* Mode 0x03 is never in driver mode */1288		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);1289	      }1290	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {1291		 /* Reset LCDA setting if not driver mode */1292		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);1293	      }1294	      if(IS_SIS650) {1295		 if(SiS_Pr->SiS_UseLCDA) {1296		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {1297		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {1298			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));1299		       }1300		    }1301		 }1302	      }1303	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);1304	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {1305		 tempbx |= SetCRT2ToLCDA;1306	      }1307	   }1308 1309	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */1310	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);1311	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {1312		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;1313		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;1314		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {1315		    tempbx |= SetCRT2ToYPbPr525750;1316		 }1317	      }1318	   }1319 1320	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {1321	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);1322	      if(temp & SetToLCDA) {1323		 tempbx |= SetCRT2ToLCDA;1324	      }1325	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {1326		 if(temp & EnableCHYPbPr) {1327		    tempbx |= SetCRT2ToCHYPbPr;1328		 }1329	      }1330	   }1331	}1332 1333#endif  /* CONFIG_FB_SIS_315 */1334 1335        if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {1336	   tempbx &= ~(SetCRT2ToRAMDAC);1337	}1338 1339	if(SiS_Pr->SiS_VBType & VB_SISVB) {1340	   temp = SetCRT2ToSVIDEO   |1341		  SetCRT2ToAVIDEO   |1342		  SetCRT2ToSCART    |1343		  SetCRT2ToLCDA     |1344		  SetCRT2ToLCD      |1345		  SetCRT2ToRAMDAC   |1346		  SetCRT2ToHiVision |1347		  SetCRT2ToYPbPr525750;1348	} else {1349	   if(SiS_Pr->ChipType >= SIS_315H) {1350	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {1351		 temp = SetCRT2ToAVIDEO |1352		        SetCRT2ToSVIDEO |1353		        SetCRT2ToSCART  |1354		        SetCRT2ToLCDA   |1355		        SetCRT2ToLCD    |1356		        SetCRT2ToCHYPbPr;1357	      } else {1358		 temp = SetCRT2ToLCDA   |1359		        SetCRT2ToLCD;1360	      }1361	   } else {1362	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {1363		 temp = SetCRT2ToTV | SetCRT2ToLCD;1364	      } else {1365		 temp = SetCRT2ToLCD;1366	      }1367	   }1368	}1369 1370	if(!(tempbx & temp)) {1371	   tempax = DisableCRT2Display;1372	   tempbx = 0;1373	}1374 1375	if(SiS_Pr->SiS_VBType & VB_SISVB) {1376 1377	   unsigned short clearmask = ( DriverMode |1378				DisableCRT2Display |1379				LoadDACFlag 	   |1380				SetNotSimuMode 	   |1381				SetInSlaveMode 	   |1382				SetPALTV 	   |1383				SwitchCRT2	   |1384				SetSimuScanMode );1385 1386	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);1387	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);1388	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);1389	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);1390	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);1391	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);1392 1393	} else {1394 1395	   if(SiS_Pr->ChipType >= SIS_315H) {1396	      if(tempbx & SetCRT2ToLCDA) {1397		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);1398	      }1399	   }1400	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {1401	      if(tempbx & SetCRT2ToTV) {1402		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);1403	      }1404	   }1405	   if(tempbx & SetCRT2ToLCD) {1406	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);1407	   }1408	   if(SiS_Pr->ChipType >= SIS_315H) {1409	      if(tempbx & SetCRT2ToLCDA) {1410	         tempbx |= SetCRT2ToLCD;1411	      }1412	   }1413 1414	}1415 1416	if(tempax & DisableCRT2Display) {1417	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {1418	      tempbx = SetSimuScanMode | DisableCRT2Display;1419	   }1420	}1421 1422	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;1423 1424	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */1425	if(SiS_Pr->SiS_ModeType <= ModeVGA) {1426	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||1427	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {1428	      modeflag &= (~CRT2Mode);1429	   }1430	}1431 1432	if(!(tempbx & SetSimuScanMode)) {1433	   if(tempbx & SwitchCRT2) {1434	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {1435		 if(resinfo != SIS_RI_1600x1200) {1436		    tempbx |= SetSimuScanMode;1437		 }1438              }1439	   } else {1440	      if(SiS_BridgeIsEnabled(SiS_Pr)) {1441		 if(!(tempbx & DriverMode)) {1442		    if(SiS_BridgeInSlavemode(SiS_Pr)) {1443		       tempbx |= SetSimuScanMode;1444		    }1445		 }1446	      }1447	   }1448	}1449 1450	if(!(tempbx & DisableCRT2Display)) {1451	   if(tempbx & DriverMode) {1452	      if(tempbx & SetSimuScanMode) {1453		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {1454		    if(resinfo != SIS_RI_1600x1200) {1455		       tempbx |= SetInSlaveMode;1456		    }1457		 }1458	      }1459	   } else {1460	      tempbx |= SetInSlaveMode;1461	   }1462	}1463 1464   }1465 1466   SiS_Pr->SiS_VBInfo = tempbx;1467 1468#ifdef CONFIG_FB_SIS_3001469   if(SiS_Pr->ChipType == SIS_630) {1470      SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);1471   }1472#endif1473 1474#if 01475   printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",1476      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);1477#endif1478}1479 1480/*********************************************/1481/*           DETERMINE YPbPr MODE            */1482/*********************************************/1483 1484void1485SiS_SetYPbPr(struct SiS_Private *SiS_Pr)1486{1487 1488   unsigned char temp;1489 1490   /* Note: This variable is only used on 30xLV systems.1491    * CR38 has a different meaning on LVDS/CH7019 systems.1492    * On 661 and later, these bits moved to CR35.1493    *1494    * On 301, 301B, only HiVision 1080i is supported.1495    * On 30xLV, 301C, only YPbPr 1080i is supported.1496    */1497 1498   SiS_Pr->SiS_YPbPr = 0;1499   if(SiS_Pr->ChipType >= SIS_661) return;1500 1501   if(SiS_Pr->SiS_VBType) {1502      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {1503	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;1504      }1505   }1506 1507   if(SiS_Pr->ChipType >= SIS_315H) {1508      if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {1509	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);1510	 if(temp & 0x08) {1511	    switch((temp >> 4)) {1512	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;1513	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;1514	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;1515	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;1516	    }1517	 }1518      }1519   }1520 1521}1522 1523/*********************************************/1524/*           DETERMINE TVMode flag           */1525/*********************************************/1526 1527void1528SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)1529{1530   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;1531   unsigned short temp, temp1, resinfo = 0, romindex = 0;1532   unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;1533 1534   SiS_Pr->SiS_TVMode = 0;1535 1536   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;1537   if(SiS_Pr->UseCustomMode) return;1538 1539   if(ModeNo > 0x13) {1540      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;1541   }1542 1543   if(SiS_Pr->ChipType < SIS_661) {1544 1545      if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;1546 1547      if(SiS_Pr->SiS_VBType & VB_SISVB) {1548	 temp = 0;1549	 if((SiS_Pr->ChipType == SIS_630) ||1550	    (SiS_Pr->ChipType == SIS_730)) {1551	    temp = 0x35;1552	    romindex = 0xfe;1553	 } else if(SiS_Pr->ChipType >= SIS_315H) {1554	    temp = 0x38;1555	    if(SiS_Pr->ChipType < XGI_20) {1556	       romindex = 0xf3;1557	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;1558	    }1559	 }1560	 if(temp) {1561	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {1562	       OutputSelect = ROMAddr[romindex];1563	       if(!(OutputSelect & EnablePALMN)) {1564		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);1565	       }1566	    }1567	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);1568	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {1569	       if(temp1 & EnablePALM) {		/* 0x40 */1570		  SiS_Pr->SiS_TVMode |= TVSetPALM;1571		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;1572	       } else if(temp1 & EnablePALN) {	/* 0x80 */1573		  SiS_Pr->SiS_TVMode |= TVSetPALN;1574	       }1575	    } else {1576	       if(temp1 & EnableNTSCJ) {	/* 0x40 */1577		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;1578	       }1579	    }1580	 }1581	 /* Translate HiVision/YPbPr to our new flags */1582	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {1583	    if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;1584	    else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;1585	    else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;1586	    else				        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;1587	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {1588	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;1589	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;1590	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {1591	       SiS_Pr->SiS_TVMode |= TVSetPAL;1592	    }1593	 }1594      } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {1595	 if(SiS_Pr->SiS_CHOverScan) {1596	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {1597	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);1598	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {1599		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;1600	       }1601	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {1602	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);1603	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {1604		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;1605	       }1606	    }1607	    if(SiS_Pr->SiS_CHSOverScan) {1608	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;1609	    }1610	 }1611	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {1612	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);1613	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {1614	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;1615	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;1616	    } else {1617	       if(temp & EnableNTSCJ) {1618		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;1619	       }1620	    }1621	 }1622      }1623 1624   } else {  /* 661 and later */1625 1626      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);1627      if(temp1 & 0x01) {1628	 SiS_Pr->SiS_TVMode |= TVSetPAL;1629	 if(temp1 & 0x08) {1630	    SiS_Pr->SiS_TVMode |= TVSetPALN;1631	 } else if(temp1 & 0x04) {1632	    if(SiS_Pr->SiS_VBType & VB_SISVB) {1633	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;1634	    }1635	    SiS_Pr->SiS_TVMode |= TVSetPALM;1636	 }1637      } else {1638	 if(temp1 & 0x02) {1639	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;1640	 }1641      }1642      if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {1643	 if(SiS_Pr->SiS_CHOverScan) {1644	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {1645	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;1646	    }1647	 }1648      }1649      if(SiS_Pr->SiS_VBType & VB_SISVB) {1650	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {1651	    temp1 &= 0xe0;1652	    if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;1653	    else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;1654	    else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;1655	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {1656	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);1657	 }1658	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {1659	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {1660	       SiS_Pr->SiS_TVMode |= TVAspect169;1661	    } else {1662	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);1663	       if(temp1 & 0x02) {1664		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {1665		     SiS_Pr->SiS_TVMode |= TVAspect169;1666		  } else {1667		     SiS_Pr->SiS_TVMode |= TVAspect43LB;1668		  }1669	       } else {1670		  SiS_Pr->SiS_TVMode |= TVAspect43;1671	       }1672	    }1673	 }1674      }1675   }1676 1677   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;1678 1679   if(SiS_Pr->SiS_VBType & VB_SISVB) {1680 1681      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {1682	 SiS_Pr->SiS_TVMode |= TVSetPAL;1683	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);1684      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {1685	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {1686	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);1687	 }1688      }1689 1690      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {1691	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {1692	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;1693	 }1694      }1695 1696      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {1697	 if(resinfo == SIS_RI_1024x768) {1698	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {1699	       SiS_Pr->SiS_TVMode |= TVSet525p1024;1700	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {1701	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;1702	    }1703	 }1704      }1705 1706      SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;1707      if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&1708	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {1709	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;1710      } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {1711	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;1712      } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {1713	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {1714	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;1715	 }1716      }1717 1718   }1719 1720   SiS_Pr->SiS_VBInfo &= ~SetPALTV;1721}1722 1723/*********************************************/1724/*               GET LCD INFO                */1725/*********************************************/1726 1727static unsigned short1728SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)1729{1730   unsigned short temp = SiS_Pr->SiS_LCDResInfo;1731   /* Translate my LCDResInfo to BIOS value */1732   switch(temp) {1733   case Panel_1280x768_2: temp = Panel_1280x768;    break;1734   case Panel_1280x800_2: temp = Panel_1280x800;    break;1735   case Panel_1280x854:   temp = Panel661_1280x854; break;1736   }1737   return temp;1738}1739 1740static void1741SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)1742{1743#ifdef CONFIG_FB_SIS_3151744   unsigned char  *ROMAddr;1745   unsigned short temp;1746 1747   if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {1748      if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {1749	 SiS_Pr->SiS_NeedRomModeData = true;1750	 SiS_Pr->PanelHT  = temp;1751      }1752      if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {1753	 SiS_Pr->SiS_NeedRomModeData = true;1754	 SiS_Pr->PanelVT  = temp;1755      }1756      SiS_Pr->PanelHRS = SISGETROMW(10);1757      SiS_Pr->PanelHRE = SISGETROMW(12);1758      SiS_Pr->PanelVRS = SISGETROMW(14);1759      SiS_Pr->PanelVRE = SISGETROMW(16);1760      SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;1761      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =1762	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);1763      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =1764	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];1765      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =1766	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];1767 1768   }1769#endif1770}1771 1772static void1773SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,1774			const unsigned char *nonscalingmodes)1775{1776   int i = 0;1777   while(nonscalingmodes[i] != 0xff) {1778      if(nonscalingmodes[i++] == resinfo) {1779	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||1780	    (SiS_Pr->UsePanelScaler == -1)) {1781	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;1782	 }1783	 break;1784      }1785   }1786}1787 1788void1789SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)1790{1791  unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;1792  bool panelcanscale = false;1793#ifdef CONFIG_FB_SIS_3001794  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;1795  static const unsigned char SiS300SeriesLCDRes[] =1796          { 0,  1,  2,  3,  7,  4,  5,  8,1797	    0,  0, 10,  0,  0,  0,  0, 15 };1798#endif1799#ifdef CONFIG_FB_SIS_3151800  unsigned char   *myptr = NULL;1801#endif1802 1803  SiS_Pr->SiS_LCDResInfo  = 0;1804  SiS_Pr->SiS_LCDTypeInfo = 0;1805  SiS_Pr->SiS_LCDInfo     = 0;1806  SiS_Pr->PanelHRS        = 999; /* HSync start */1807  SiS_Pr->PanelHRE        = 999; /* HSync end */1808  SiS_Pr->PanelVRS        = 999; /* VSync start */1809  SiS_Pr->PanelVRE        = 999; /* VSync end */1810  SiS_Pr->SiS_NeedRomModeData = false;1811 1812  /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */1813  SiS_Pr->Alternate1600x1200 = false;1814 1815  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;1816 1817  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);1818 1819  if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {1820     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;1821     modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;1822     modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;1823  }1824 1825  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);1826 1827  /* For broken BIOSes: Assume 1024x768 */1828  if(temp == 0) temp = 0x02;1829 1830  if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {1831     SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;1832  } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {1833     SiS_Pr->SiS_LCDTypeInfo = temp >> 4;1834  } else {1835     SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;1836  }1837  temp &= 0x0f;1838#ifdef CONFIG_FB_SIS_3001839  if(SiS_Pr->ChipType < SIS_315H) {1840     /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */1841     if(SiS_Pr->SiS_VBType & VB_SIS301) {1842        if(temp < 0x0f) temp &= 0x07;1843     }1844     /* Translate 300 series LCDRes to 315 series for unified usage */1845     temp = SiS300SeriesLCDRes[temp];1846  }1847#endif1848 1849  /* Translate to our internal types */1850#ifdef CONFIG_FB_SIS_3151851  if(SiS_Pr->ChipType == SIS_550) {1852     if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */1853     else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;1854     else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;1855  } else if(SiS_Pr->ChipType >= SIS_661) {1856     if(temp == Panel661_1280x854)       temp = Panel_1280x854;1857  }1858#endif1859 1860  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */1861     if(temp == Panel310_1280x768) {1862        temp = Panel_1280x768_2;1863     }1864     if(SiS_Pr->SiS_ROMNew) {1865	if(temp == Panel661_1280x800) {1866	   temp = Panel_1280x800_2;1867	}1868     }1869  }1870 1871  SiS_Pr->SiS_LCDResInfo = temp;1872 1873#ifdef CONFIG_FB_SIS_3001874  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {1875     if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {1876	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;1877     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {1878	SiS_Pr->SiS_LCDResInfo = Panel_848x480;1879     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {1880	SiS_Pr->SiS_LCDResInfo = Panel_856x480;1881     }1882  }1883#endif1884 1885  if(SiS_Pr->SiS_VBType & VB_SISVB) {1886     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)1887	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;1888  } else {1889     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)1890	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;1891  }1892 1893  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);1894  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;1895  /* Need temp below! */1896 1897  /* These must/can't scale no matter what */1898  switch(SiS_Pr->SiS_LCDResInfo) {1899  case Panel_320x240_1:1900  case Panel_320x240_2:1901  case Panel_320x240_3:1902  case Panel_1280x960:1903      SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;1904      break;1905  case Panel_640x480:1906      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;1907  }1908 1909  panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);1910 1911  if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;1912  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;1913 1914  /* Dual link, Pass 1:1 BIOS default, etc. */1915#ifdef CONFIG_FB_SIS_3151916  if(SiS_Pr->ChipType >= SIS_661) {1917     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {1918	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;1919     }1920     if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {1921	if(SiS_Pr->SiS_ROMNew) {1922	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;1923	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {1924	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;1925	}1926     }1927  } else if(SiS_Pr->ChipType >= SIS_315H) {1928     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {1929	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;1930     }1931     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {1932	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);1933	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);1934	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;1935	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {1936	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;1937	}1938     } else if(!(SiS_Pr->SiS_ROMNew)) {1939	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {1940	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&1941	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {1942	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;1943	   }1944	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||1945	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||1946	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||1947	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {1948	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;1949	   }1950	}1951     }1952  }1953#endif1954 1955  /* Pass 1:1 */1956  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {1957     /* Always center screen on LVDS (if scaling is disabled) */1958     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;1959  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {1960     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {1961	/* Always center screen on SiS LVDS (if scaling is disabled) */1962	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;1963     } else {1964	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */1965	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;1966	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;1967     }1968  }1969 1970  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;1971  SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;1972 1973  switch(SiS_Pr->SiS_LCDResInfo) {1974     case Panel_320x240_1:1975     case Panel_320x240_2:1976     case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;1977			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;1978			    SiS_Pr->PanelVCLKIdx300 = VCLK28;1979			    SiS_Pr->PanelVCLKIdx315 = VCLK28;1980			    break;1981     case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;1982						      SiS_Pr->PanelVRE  =    3;1983			    SiS_Pr->PanelVCLKIdx300 = VCLK28;1984			    SiS_Pr->PanelVCLKIdx315 = VCLK28;1985			    break;1986     case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;1987     			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;1988			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;1989			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;1990			    SiS_Pr->PanelVCLKIdx300 = VCLK40;1991			    SiS_Pr->PanelVCLKIdx315 = VCLK40;1992			    break;1993     case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;1994			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;1995			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;1996			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;1997			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;1998			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;1999			    break;2000     case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;2001			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;2002			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;2003			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;2004			    if(SiS_Pr->ChipType < SIS_315H) {2005			       SiS_Pr->PanelHRS = 23;2006						      SiS_Pr->PanelVRE  =    5;2007			    }2008			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;2009			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;2010			    SiS_GetLCDInfoBIOS(SiS_Pr);2011			    break;2012     case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;2013			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;2014			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;2015			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;2016			    if(SiS_Pr->ChipType < SIS_315H) {2017			       SiS_Pr->PanelHRS = 23;2018						      SiS_Pr->PanelVRE  =    5;2019			    }2020			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;2021			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;2022			    break;2023     case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;2024			    break;2025     case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;2026			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;2027			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;2028			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;2029			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;2030			    /* Data above for TMDS (projector); get from BIOS for LVDS */2031			    SiS_GetLCDInfoBIOS(SiS_Pr);2032			    break;2033     case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;2034			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {2035			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;2036			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */2037			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */2038			    } else {2039			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;2040			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;2041			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;2042			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;2043			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;2044			    }2045			    break;2046     case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;2047			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;2048			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;2049			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;2050			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;2051			    SiS_GetLCDInfoBIOS(SiS_Pr);2052			    break;2053     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;2054			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;2055			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;2056			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;2057			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;2058			    SiS_GetLCDInfoBIOS(SiS_Pr);2059			    break;2060     case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;2061			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;2062			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;2063			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;2064			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;2065			    SiS_GetLCDInfoBIOS(SiS_Pr);2066			    break;2067     case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;2068			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;2069			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;2070			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;2071			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;2072			    SiS_GetLCDInfoBIOS(SiS_Pr);2073			    break;2074     case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;2075			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;2076			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;2077			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;2078			    if(resinfo == SIS_RI_1280x1024) {2079			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;2080			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;2081			    }2082			    break;2083     case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;2084			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;2085			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;2086			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;2087			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;2088			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;2089			    SiS_GetLCDInfoBIOS(SiS_Pr);2090			    break;2091     case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;2092			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;2093			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;2094			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;2095			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;2096			    SiS_GetLCDInfoBIOS(SiS_Pr);2097			    break;2098     case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;2099			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;2100			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;2101			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;2102			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;2103			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {2104			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {2105				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;2106				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;2107				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;2108				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;2109				  SiS_Pr->Alternate1600x1200 = true;2110			       }2111			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {2112			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;2113			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;2114			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;2115			    }2116			    SiS_GetLCDInfoBIOS(SiS_Pr);2117			    break;2118     case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;2119			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;2120			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;2121			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;2122			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;2123			    SiS_GetLCDInfoBIOS(SiS_Pr);2124			    break;2125     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;2126			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;2127			    break;2128     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;2129			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;2130			    break;2131     case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;2132			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;2133			    break;2134     case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;2135			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;2136			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;2137			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;2138			    if(SiS_Pr->CP_PreferredIndex != -1) {2139			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];2140			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];2141			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];2142			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];2143			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];2144			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];2145			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];2146			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];2147			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;2148			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;2149			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;2150			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;2151			       if(SiS_Pr->CP_PrefClock) {2152				  int idx;2153				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;2154				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;2155				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;2156				  else				   idx = VCLK_CUSTOM_315;2157				  SiS_Pr->SiS_VCLKData[idx].CLOCK =2158				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;2159				  SiS_Pr->SiS_VCLKData[idx].SR2B =2160				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;2161				  SiS_Pr->SiS_VCLKData[idx].SR2C =2162				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;2163			       }2164			    }2165			    break;2166     default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;2167			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;2168			    break;2169  }2170 2171  /* Special cases */2172  if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||2173      (SiS_Pr->SiS_IF_DEF_DSTN)              ||2174      (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||2175      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||2176      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||2177      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {2178     SiS_Pr->PanelHRS = 999;2179     SiS_Pr->PanelHRE = 999;2180  }2181 2182  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||2183      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||2184      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||2185      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {2186     SiS_Pr->PanelVRS = 999;2187     SiS_Pr->PanelVRE = 999;2188  }2189 2190  /* DontExpand overrule */2191  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {2192 2193     if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {2194	/* No scaling for this mode on any panel (LCD=CRT2)*/2195	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2196     }2197 2198     switch(SiS_Pr->SiS_LCDResInfo) {2199 2200     case Panel_Custom:2201     case Panel_1152x864:2202     case Panel_1280x768:	/* TMDS only */2203	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2204	break;2205 2206     case Panel_800x600: {2207	static const unsigned char nonscalingmodes[] = {2208	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff2209	};2210	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2211	break;2212     }2213     case Panel_1024x768: {2214	static const unsigned char nonscalingmodes[] = {2215	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2216	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2217	   0xff2218	};2219	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2220	break;2221     }2222     case Panel_1280x720: {2223	static const unsigned char nonscalingmodes[] = {2224	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2225	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2226	   0xff2227	};2228	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2229	if(SiS_Pr->PanelHT == 1650) {2230	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2231	}2232	break;2233     }2234     case Panel_1280x768_2: {  /* LVDS only */2235	static const unsigned char nonscalingmodes[] = {2236	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2237	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2238	   SIS_RI_1152x768,0xff2239	};2240	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2241	switch(resinfo) {2242	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {2243				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2244			       }2245			       break;2246	}2247	break;2248     }2249     case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */2250	static const unsigned char nonscalingmodes[] = {2251	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2252	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2253	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff2254	};2255	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2256	break;2257     }2258     case Panel_1280x800_2:  { 	/* SiS LVDS */2259	static const unsigned char nonscalingmodes[] = {2260	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2261	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2262	   SIS_RI_1152x768,0xff2263	};2264	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2265	switch(resinfo) {2266	case SIS_RI_1280x720:2267	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {2268				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2269			       }2270			       break;2271	}2272	break;2273     }2274     case Panel_1280x854: {  	/* SiS LVDS */2275	static const unsigned char nonscalingmodes[] = {2276	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2277	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2278	   SIS_RI_1152x768,0xff2279	};2280	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2281	switch(resinfo) {2282	case SIS_RI_1280x720:2283	case SIS_RI_1280x768:2284	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {2285				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2286			       }2287			       break;2288	}2289	break;2290     }2291     case Panel_1280x960: {2292	static const unsigned char nonscalingmodes[] = {2293	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2294	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2295	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,2296	   SIS_RI_1280x854,0xff2297	};2298	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2299	break;2300     }2301     case Panel_1280x1024: {2302	static const unsigned char nonscalingmodes[] = {2303	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2304	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2305	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,2306	   SIS_RI_1280x854,SIS_RI_1280x960,0xff2307	};2308	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2309	break;2310     }2311     case Panel_1400x1050: {2312	static const unsigned char nonscalingmodes[] = {2313	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2314	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2315	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,2316	     SIS_RI_1280x960,0xff2317	};2318	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2319	switch(resinfo) {2320	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {2321				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2322			       }2323			       break;2324	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;2325			       break;2326	}2327	break;2328     }2329     case Panel_1600x1200: {2330	static const unsigned char nonscalingmodes[] = {2331	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2332	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2333	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,2334	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff2335	};2336	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2337	break;2338     }2339     case Panel_1680x1050: {2340	static const unsigned char nonscalingmodes[] = {2341	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,2342	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,2343	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,2344	     SIS_RI_1360x1024,0xff2345	};2346	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);2347	break;2348     }2349     }2350  }2351 2352#ifdef CONFIG_FB_SIS_3002353  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {2354     if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {2355	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */2356     }2357  }2358 2359  if(SiS_Pr->ChipType < SIS_315H) {2360     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {2361	if(SiS_Pr->SiS_UseROM) {2362	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {2363	      if(!(ROMAddr[0x235] & 0x02)) {2364		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);2365	      }2366	   }2367	}2368     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {2369	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {2370	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);2371	}2372     }2373  }2374#endif2375 2376  /* Special cases */2377 2378  if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {2379     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;2380  }2381 2382  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {2383     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);2384  }2385 2386  switch(SiS_Pr->SiS_LCDResInfo) {2387  case Panel_640x480:2388     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);2389     break;2390  case Panel_1280x800:2391     /* Don't pass 1:1 by default (TMDS special) */2392     if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;2393     break;2394  case Panel_1280x960:2395     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;2396     break;2397  case Panel_Custom:2398     if((!SiS_Pr->CP_PrefClock) ||2399        (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {2400        SiS_Pr->SiS_LCDInfo |= LCDPass11;2401     }2402     break;2403  }2404 2405  if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {2406     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);2407  }2408 2409  /* (In)validate LCDPass11 flag */2410  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {2411     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;2412  }2413 2414  /* LVDS DDA */2415  if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {2416 2417     if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {2418	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {2419	   if(ModeNo == 0x12) {2420	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {2421		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;2422	      }2423	   } else if(ModeNo > 0x13) {2424	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {2425		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {2426		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {2427		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;2428		    }2429		 }2430	      }2431	   }2432	}2433     }2434 2435     if(modeflag & HalfDCLK) {2436	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {2437	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;2438	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {2439	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;2440	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {2441	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;2442	} else if(ModeNo > 0x13) {2443	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {2444	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;2445	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {2446	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;2447	   }2448	}2449     }2450 2451  }2452 2453  /* VESA timing */2454  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {2455     if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {2456	SiS_Pr->SiS_SetFlag |= LCDVESATiming;2457     }2458  } else {2459     SiS_Pr->SiS_SetFlag |= LCDVESATiming;2460  }2461 2462#if 02463  printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",2464	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);2465#endif2466}2467 2468/*********************************************/2469/*                 GET VCLK                  */2470/*********************************************/2471 2472unsigned short2473SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,2474		unsigned short RefreshRateTableIndex)2475{2476  unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;2477  unsigned short resinfo, tempbx;2478  const unsigned char *CHTVVCLKPtr = NULL;2479 2480  if(ModeNo <= 0x13) {2481     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;2482     CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;2483     VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;2484     VCLKIndexGENCRT = VCLKIndexGEN;2485  } else {2486     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;2487     CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;2488     VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;2489     VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,2490		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);2491  }2492 2493  if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */2494 2495     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {2496 2497	CRT2Index >>= 6;2498	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */2499 2500	   if(SiS_Pr->ChipType < SIS_315H) {2501	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;2502	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {2503		 VCLKIndex = VCLKIndexGEN;2504	      }2505	   } else {2506	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;2507	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {2508		 switch(resinfo) {2509		 /* Correct those whose IndexGEN doesn't match VBVCLK array */2510		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;2511		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;2512		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;2513		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;2514		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;2515		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;2516		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;2517		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;2518		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;2519		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;2520		 default:              VCLKIndex = VCLKIndexGEN;2521		 }2522 2523		 if(ModeNo <= 0x13) {2524		    if(SiS_Pr->ChipType <= SIS_315PRO) {2525		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;2526		    } else {2527		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;2528		    }2529		 }2530		 if(SiS_Pr->ChipType <= SIS_315PRO) {2531		    if(VCLKIndex == 0) VCLKIndex = 0x41;2532		    if(VCLKIndex == 1) VCLKIndex = 0x43;2533		    if(VCLKIndex == 4) VCLKIndex = 0x44;2534		 }2535	      }2536	   }2537 2538	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */2539 2540	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {2541	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;2542	      else                                  	   VCLKIndex = HiTVVCLK;2543	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;2544	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;2545	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;2546	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;2547	   else						   VCLKIndex = TVVCLK;2548 2549	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;2550	   else				   VCLKIndex += TVCLKBASE_315;2551 2552	} else {							/* VGA2 */2553 2554	   VCLKIndex = VCLKIndexGENCRT;2555	   if(SiS_Pr->ChipType < SIS_315H) {2556	      if(ModeNo > 0x13) {2557		 if( (SiS_Pr->ChipType == SIS_630) &&2558		     (SiS_Pr->ChipRevision >= 0x30)) {2559		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;2560		 }2561		 /* Better VGA2 clock for 1280x1024@75 */2562		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;2563	      }2564	   }2565	}2566 2567     } else {   /* If not programming CRT2 */2568 2569	VCLKIndex = VCLKIndexGENCRT;2570	if(SiS_Pr->ChipType < SIS_315H) {2571	   if(ModeNo > 0x13) {2572	      if( (SiS_Pr->ChipType != SIS_630) &&2573		  (SiS_Pr->ChipType != SIS_300) ) {2574		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;2575	      }2576	   }2577	}2578     }2579 2580  } else {       /*   LVDS  */2581 2582     VCLKIndex = CRT2Index;2583 2584     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {2585 2586	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {2587 2588	   VCLKIndex &= 0x1f;2589	   tempbx = 0;2590	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;2591	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {2592	      tempbx += 2;2593	      if(SiS_Pr->SiS_ModeType > ModeVGA) {2594		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;2595	      }2596	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {2597		 tempbx = 4;2598		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;2599	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {2600		 tempbx = 6;2601		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;2602	      }2603	   }2604	   switch(tempbx) {2605	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;2606	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;2607	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;2608	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;2609	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;2610	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;2611	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;2612	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;2613	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;2614	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;2615	   }2616	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];2617 2618	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {2619 2620	   if(SiS_Pr->ChipType < SIS_315H) {2621	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;2622	   } else {2623	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;2624	   }2625 2626#ifdef CONFIG_FB_SIS_3002627	   /* Special Timing: Barco iQ Pro R series */2628	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;2629 2630	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */2631	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {2632	      if(SiS_Pr->ChipType < SIS_315H) {2633		 VCLKIndex = VCLK34_300;2634		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */2635	      } else {2636		 VCLKIndex = VCLK34_315;2637		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */2638	      }2639	   }2640#endif2641 2642	} else {2643 2644	   VCLKIndex = VCLKIndexGENCRT;2645	   if(SiS_Pr->ChipType < SIS_315H) {2646	      if(ModeNo > 0x13) {2647		 if( (SiS_Pr->ChipType == SIS_630) &&2648		     (SiS_Pr->ChipRevision >= 0x30) ) {2649		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;2650		 }2651	      }2652	   }2653	}2654 2655     } else {  /* if not programming CRT2 */2656 2657	VCLKIndex = VCLKIndexGENCRT;2658	if(SiS_Pr->ChipType < SIS_315H) {2659	   if(ModeNo > 0x13) {2660	      if( (SiS_Pr->ChipType != SIS_630) &&2661		  (SiS_Pr->ChipType != SIS_300) ) {2662		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;2663	      }2664#if 02665	      if(SiS_Pr->ChipType == SIS_730) {2666		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */2667		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */2668	      }2669#endif2670	   }2671        }2672 2673     }2674 2675  }2676 2677  return VCLKIndex;2678}2679 2680/*********************************************/2681/*        SET CRT2 MODE TYPE REGISTERS       */2682/*********************************************/2683 2684static void2685SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)2686{2687  unsigned short i, j, modeflag, tempah=0;2688  short tempcl;2689#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)2690  unsigned short tempbl;2691#endif2692#ifdef CONFIG_FB_SIS_3152693  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;2694  unsigned short tempah2, tempbl2;2695#endif2696 2697  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);2698 2699  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {2700 2701     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);2702     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);2703 2704  } else {2705 2706     for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);2707     if(SiS_Pr->ChipType >= SIS_315H) {2708        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);2709     }2710 2711     tempcl = SiS_Pr->SiS_ModeType;2712 2713     if(SiS_Pr->ChipType < SIS_315H) {2714 2715#ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */2716 2717	/* For 301BDH: (with LCD via LVDS) */2718	if(SiS_Pr->SiS_VBType & VB_NoLCD) {2719	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);2720	   tempbl &= 0xef;2721	   tempbl |= 0x02;2722	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {2723	      tempbl |= 0x10;2724	      tempbl &= 0xfd;2725	   }2726	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);2727	}2728 2729	if(ModeNo > 0x13) {2730	   tempcl -= ModeVGA;2731	   if(tempcl >= 0) {2732	      tempah = ((0x10 >> tempcl) | 0x80);2733	   }2734	} else tempah = 0x80;2735 2736	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;2737 2738#endif  /* CONFIG_FB_SIS_300 */2739 2740     } else {2741 2742#ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */2743 2744	if(ModeNo > 0x13) {2745	   tempcl -= ModeVGA;2746	   if(tempcl >= 0) {2747	      tempah = (0x08 >> tempcl);2748	      if (tempah == 0) tempah = 1;2749	      tempah |= 0x40;2750	   }2751	} else tempah = 0x40;2752 2753	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;2754 2755#endif  /* CONFIG_FB_SIS_315 */2756 2757     }2758 2759     if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;2760 2761     if(SiS_Pr->ChipType < SIS_315H) {2762	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);2763     } else {2764#ifdef CONFIG_FB_SIS_3152765	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {2766	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);2767	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {2768	   if(IS_SIS740) {2769	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);2770	   } else {2771	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);2772	   }2773	}2774#endif2775     }2776 2777     if(SiS_Pr->SiS_VBType & VB_SISVB) {2778 2779	tempah = 0x01;2780	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {2781	   tempah |= 0x02;2782	}2783	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {2784	   tempah ^= 0x05;2785	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {2786	      tempah ^= 0x01;2787	   }2788	}2789 2790	if(SiS_Pr->ChipType < SIS_315H) {2791 2792	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;2793 2794	   tempah = (tempah << 5) & 0xFF;2795	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);2796	   tempah = (tempah >> 5) & 0xFF;2797 2798	} else {2799 2800	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;2801	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;2802	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);2803	   tempah &= ~0x08;2804 2805	}2806 2807	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {2808	   tempah |= 0x10;2809	}2810 2811	tempah |= 0x80;2812	if(SiS_Pr->SiS_VBType & VB_SIS301) {2813	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;2814	}2815 2816	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {2817	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {2818	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {2819		 tempah |= 0x20;2820	      }2821	   }2822	}2823 2824	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);2825 2826	tempah = 0x80;2827	if(SiS_Pr->SiS_VBType & VB_SIS301) {2828	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;2829	}2830 2831	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;2832 2833	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {2834	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {2835	      tempah |= 0x40;2836	   }2837	}2838 2839	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);2840 2841     } else {  /* LVDS */2842 2843	if(SiS_Pr->ChipType >= SIS_315H) {2844 2845#ifdef CONFIG_FB_SIS_3152846	   /* LVDS can only be slave in 8bpp modes */2847	   tempah = 0x80;2848	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {2849	      if(SiS_Pr->SiS_VBInfo & DriverMode) {2850	         tempah |= 0x02;2851	      }2852	   }2853 2854	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;2855 2856	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;2857 2858	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;2859 2860	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);2861#endif2862 2863	} else {2864 2865#ifdef CONFIG_FB_SIS_3002866	   tempah = 0;2867	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {2868	      tempah |= 0x02;2869	   }2870	   tempah <<= 5;2871 2872	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;2873 2874	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);2875#endif2876 2877	}2878 2879     }2880 2881  }  /* LCDA */2882 2883  if(SiS_Pr->SiS_VBType & VB_SISVB) {2884 2885     if(SiS_Pr->ChipType >= SIS_315H) {2886 2887#ifdef CONFIG_FB_SIS_3152888	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */2889 2890	/* The following is nearly unpreditable and varies from machine2891	 * to machine. Especially the 301DH seems to be a real trouble2892	 * maker. Some BIOSes simply set the registers (like in the2893	 * NoLCD-if-statements here), some set them according to the2894	 * LCDA stuff. It is very likely that some machines are not2895	 * treated correctly in the following, very case-orientated2896	 * code. What do I do then...?2897	 */2898 2899	/* 740 variants match for 30xB, 301B-DH, 30xLV */2900 2901	if(!(IS_SIS740)) {2902	   tempah = 0x04;						   /* For all bridges */2903	   tempbl = 0xfb;2904	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {2905	      tempah = 0x00;2906	      if(SiS_IsDualEdge(SiS_Pr)) {2907	         tempbl = 0xff;2908	      }2909	   }2910	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);2911	}2912 2913	/* The following two are responsible for eventually wrong colors2914	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the2915	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version2916	 * in a 650 box (Jake). What is the criteria?2917	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same2918	 * treatment like the 651+301B-DH(b0) case. Seems more to be the2919	 * chipset than the bridge revision.2920	 */2921 2922	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {2923	   tempah = 0x30;2924	   tempbl = 0xc0;2925	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||2926	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {2927	      tempah = 0x00;2928	      tempbl = 0x00;2929	   }2930	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);2931	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);2932	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {2933	   /* Fixes "TV-blue-bug" on 315+301 */2934	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */2935	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);2936	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {2937	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */2938	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);2939	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */2940	   tempah = 0x30; tempah2 = 0xc0;2941	   tempbl = 0xcf; tempbl2 = 0x3f;2942	   if(SiS_Pr->SiS_TVBlue == 0) {2943	         tempah = tempah2 = 0x00;2944	   } else if(SiS_Pr->SiS_TVBlue == -1) {2945	      /* Set on 651/M650, clear on 315/650 */2946	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {2947	         tempah = tempah2 = 0x00;2948	      }2949	   }2950	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);2951	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);2952	} else {2953	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */2954	   tempbl = 0xcf; tempbl2 = 0x3f;2955	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {2956	      tempah = tempah2 = 0x00;2957	      if(SiS_IsDualEdge(SiS_Pr)) {2958		 tempbl = tempbl2 = 0xff;2959	      }2960	   }2961	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);2962	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);2963	}2964 2965	if(IS_SIS740) {2966	   tempah = 0x80;2967	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;2968	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);2969	} else {2970	   tempah = 0x00;2971	   tempbl = 0x7f;2972	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {2973	      tempbl = 0xff;2974	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;2975	   }2976	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);2977	}2978 2979#endif /* CONFIG_FB_SIS_315 */2980 2981     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {2982 2983#ifdef CONFIG_FB_SIS_3002984	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);2985 2986	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||2987	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&2988	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {2989	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);2990	} else {2991	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);2992	}2993#endif2994 2995     }2996 2997     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {2998	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);2999	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {3000	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);3001        }3002     }3003 3004  } else {  /* LVDS */3005 3006#ifdef CONFIG_FB_SIS_3153007     if(SiS_Pr->ChipType >= SIS_315H) {3008 3009	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {3010 3011	   tempah = 0x04;3012	   tempbl = 0xfb;3013	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {3014	      tempah = 0x00;3015	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;3016	   }3017	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);3018 3019	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {3020	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);3021	   }3022 3023	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);3024 3025	} else if(SiS_Pr->ChipType == SIS_550) {3026 3027	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);3028	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);3029 3030	}3031 3032     }3033#endif3034 3035  }3036 3037}3038 3039/*********************************************/3040/*            GET RESOLUTION DATA            */3041/*********************************************/3042 3043unsigned short3044SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)3045{3046   if(ModeNo <= 0x13)3047      return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);3048   else3049      return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);3050}3051 3052static void3053SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)3054{3055   unsigned short xres, yres, modeflag=0, resindex;3056 3057   if(SiS_Pr->UseCustomMode) {3058      xres = SiS_Pr->CHDisplay;3059      if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;3060      SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;3061      /* DoubleScanMode-check done in CheckCalcCustomMode()! */3062      SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;3063      return;3064   }3065 3066   resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);3067 3068   if(ModeNo <= 0x13) {3069      xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;3070      yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;3071   } else {3072      xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;3073      yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;3074      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;3075   }3076 3077   if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {3078 3079      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {3080	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {3081	    if(yres == 350) yres = 400;3082	 }3083	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {3084	    if(ModeNo == 0x12) yres = 400;3085	 }3086      }3087 3088      if(modeflag & HalfDCLK)       xres <<= 1;3089      if(modeflag & DoubleScanMode) yres <<= 1;3090 3091   }3092 3093   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {3094 3095      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {3096	 switch(SiS_Pr->SiS_LCDResInfo) {3097	   case Panel_1024x768:3098	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {3099		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {3100		    if(yres == 350) yres = 357;3101		    if(yres == 400) yres = 420;3102		    if(yres == 480) yres = 525;3103		 }3104	      }3105	      break;3106	   case Panel_1280x1024:3107	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {3108		 /* BIOS bug - does this regardless of scaling */3109		 if(yres == 400) yres = 405;3110	      }3111	      if(yres == 350) yres = 360;3112	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {3113		 if(yres == 360) yres = 375;3114	      }3115	      break;3116	   case Panel_1600x1200:3117	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {3118		 if(yres == 1024) yres = 1056;3119	      }3120	      break;3121	 }3122      }3123 3124   } else {3125 3126      if(SiS_Pr->SiS_VBType & VB_SISVB) {3127	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {3128	    if(xres == 720) xres = 640;3129	 }3130      } else if(xres == 720) xres = 640;3131 3132      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {3133	 yres = 400;3134	 if(SiS_Pr->ChipType >= SIS_315H) {3135	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;3136	 } else {3137	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;3138	 }3139	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;3140      }3141 3142   }3143   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;3144   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;3145}3146 3147/*********************************************/3148/*           GET CRT2 TIMING DATA            */3149/*********************************************/3150 3151static void3152SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,3153	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,3154	       unsigned short *ResIndex)3155{3156  unsigned short tempbx=0, tempal=0, resinfo=0;3157 3158  if(ModeNo <= 0x13) {3159     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;3160  } else {3161     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;3162     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;3163  }3164 3165  if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {3166 3167     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */3168 3169	tempbx = SiS_Pr->SiS_LCDResInfo;3170	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;3171 3172	/* patch index */3173	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {3174	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;3175	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;3176	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||3177		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||3178		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {3179	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;3180	}3181 3182	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {3183	   /* Pass 1:1 only (center-screen handled outside) */3184	   /* This is never called for the panel's native resolution */3185	   /* since Pass1:1 will not be set in this case */3186	   tempbx = 100;3187	   if(ModeNo >= 0x13) {3188	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;3189	   }3190	}3191 3192#ifdef CONFIG_FB_SIS_3153193	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {3194	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {3195	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {3196		 tempbx = 200;3197		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;3198	      }3199	   }3200	}3201#endif3202 3203     } else {						  	/* TV */3204 3205	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {3206	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */3207	   tempbx = 2;3208	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {3209	      tempbx = 13;3210	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;3211	   }3212	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {3213	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;3214	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;3215	   else						tempbx = 5;3216	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;3217	} else {3218	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;3219	   else						tempbx = 4;3220	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;3221	}3222 3223     }3224 3225     tempal &= 0x3F;3226 3227     if(ModeNo > 0x13) {3228        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {3229	   switch(resinfo) {3230	   case SIS_RI_720x480:3231	      tempal = 6;3232	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))	tempal = 9;3233	      break;3234	   case SIS_RI_720x576:3235	   case SIS_RI_768x576:3236	   case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */3237	      tempal = 6;3238	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {3239		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 8;3240	      }3241	      break;3242	   case SIS_RI_800x480:3243	      tempal = 4;3244	      break;3245	   case SIS_RI_512x384:3246	   case SIS_RI_1024x768:3247	      tempal = 7;3248	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {3249		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempal = 8;3250	      }3251	      break;3252	   case SIS_RI_1280x720:3253	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {3254		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 9;3255	      }3256	      break;3257	   }3258	}3259     }3260 3261     *CRT2Index = tempbx;3262     *ResIndex = tempal;3263 3264  } else {   /* LVDS, 301B-DH (if running on LCD) */3265 3266     tempbx = 0;3267     if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {3268 3269	tempbx = 90;3270	if(SiS_Pr->SiS_TVMode & TVSetPAL) {3271	   tempbx = 92;3272	   if(SiS_Pr->SiS_ModeType > ModeVGA) {3273	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;3274	   }3275	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;3276	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;3277	}3278	if(tempbx != 99) {3279	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;3280	}3281 3282     } else {3283 3284	switch(SiS_Pr->SiS_LCDResInfo) {3285	case Panel_640x480:   tempbx = 12; break;3286	case Panel_320x240_1: tempbx = 10; break;3287	case Panel_320x240_2:3288	case Panel_320x240_3: tempbx = 14; break;3289	case Panel_800x600:   tempbx = 16; break;3290	case Panel_1024x600:  tempbx = 18; break;3291	case Panel_1152x768:3292	case Panel_1024x768:  tempbx = 20; break;3293	case Panel_1280x768:  tempbx = 22; break;3294	case Panel_1280x1024: tempbx = 24; break;3295	case Panel_1400x1050: tempbx = 26; break;3296	case Panel_1600x1200: tempbx = 28; break;3297#ifdef CONFIG_FB_SIS_3003298	case Panel_Barco1366: tempbx = 80; break;3299#endif3300	}3301 3302	switch(SiS_Pr->SiS_LCDResInfo) {3303	case Panel_320x240_1:3304	case Panel_320x240_2:3305	case Panel_320x240_3:3306	case Panel_640x480:3307	   break;3308	default:3309	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;3310	}3311 3312	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;3313 3314#ifdef CONFIG_FB_SIS_3003315	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {3316	   tempbx = 82;3317	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;3318	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {3319	   tempbx = 84;3320	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;3321	}3322#endif3323 3324     }3325 3326     (*CRT2Index) = tempbx;3327     (*ResIndex) = tempal & 0x1F;3328  }3329}3330 3331static void3332SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,3333		unsigned short RefreshRateTableIndex)3334{3335  unsigned short tempax=0, tempbx=0, index, dotclock;3336  unsigned short temp1=0, modeflag=0, tempcx=0;3337 3338  SiS_Pr->SiS_RVBHCMAX  = 1;3339  SiS_Pr->SiS_RVBHCFACT = 1;3340 3341  if(ModeNo <= 0x13) {3342 3343     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;3344     index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);3345 3346     tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];3347     tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];3348     temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];3349 3350     dotclock = (modeflag & Charx8Dot) ? 8 : 9;3351 3352  } else {3353 3354     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;3355     index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);3356 3357     tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];3358     tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);3359     tempax &= 0x03FF;3360     tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];3361     tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;3362     tempcx &= 0x0100;3363     tempcx <<= 2;3364     tempbx |= tempcx;3365     temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];3366 3367     dotclock = 8;3368 3369  }3370 3371  if(temp1 & 0x01) tempbx |= 0x0100;3372  if(temp1 & 0x20) tempbx |= 0x0200;3373 3374  tempax += 5;3375  tempax *= dotclock;3376  if(modeflag & HalfDCLK) tempax <<= 1;3377 3378  tempbx++;3379 3380  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;3381  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;3382}3383 3384static void3385SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,3386		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)3387{3388   unsigned short ResIndex;3389 3390   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {3391      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {3392	 if(SiS_Pr->UseCustomMode) {3393	    ResIndex = SiS_Pr->CHTotal;3394	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;3395	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;3396	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;3397	 } else {3398	    if(ModeNo < 0x13) {3399	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;3400	    } else {3401	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;3402	    }3403	    if(ResIndex == 0x09) {3404	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */3405	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */3406	    }3407	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;3408	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;3409	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;3410	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;3411	 }3412      } else {3413	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;3414	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;3415      }3416   } else {3417      /* This handles custom modes and custom panels */3418      SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;3419      SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;3420      SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;3421      SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;3422      SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);3423      SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);3424   }3425}3426 3427static void3428SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,3429                    unsigned short RefreshRateTableIndex)3430{3431   unsigned short CRT2Index, ResIndex, backup;3432   const struct SiS_LVDSData *LVDSData = NULL;3433 3434   SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);3435 3436   if(SiS_Pr->SiS_VBType & VB_SISVB) {3437      SiS_Pr->SiS_RVBHCMAX  = 1;3438      SiS_Pr->SiS_RVBHCFACT = 1;3439      SiS_Pr->SiS_NewFlickerMode = 0;3440      SiS_Pr->SiS_RVBHRS = 50;3441      SiS_Pr->SiS_RY1COE = 0;3442      SiS_Pr->SiS_RY2COE = 0;3443      SiS_Pr->SiS_RY3COE = 0;3444      SiS_Pr->SiS_RY4COE = 0;3445      SiS_Pr->SiS_RVBHRS2 = 0;3446   }3447 3448   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {3449 3450#ifdef CONFIG_FB_SIS_3153451      SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);3452      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);3453#endif3454 3455   } else {3456 3457      /* 301BDH needs LVDS Data */3458      backup = SiS_Pr->SiS_IF_DEF_LVDS;3459      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {3460	 SiS_Pr->SiS_IF_DEF_LVDS = 1;3461      }3462 3463      SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,3464                     		            &CRT2Index, &ResIndex);3465 3466      SiS_Pr->SiS_IF_DEF_LVDS = backup;3467 3468      switch(CRT2Index) {3469	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;3470	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;3471	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;3472	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;3473	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;3474	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;3475#ifdef CONFIG_FB_SIS_3003476	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;3477	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;3478	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;3479	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;3480	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;3481#endif3482	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;3483	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;3484	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;3485	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;3486	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;3487	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;3488	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;3489	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;3490	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;3491      }3492 3493      if(LVDSData) {3494	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;3495	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;3496	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;3497	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;3498      } else {3499	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);3500      }3501 3502      if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&3503	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&3504	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {3505	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||3506	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {3507	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;3508            SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;3509#ifdef CONFIG_FB_SIS_3003510	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {3511	       if(ResIndex < 0x08) {3512		  SiS_Pr->SiS_HDE = 1280;3513		  SiS_Pr->SiS_VDE = 1024;3514	       }3515	    }3516#endif3517         }3518      }3519   }3520}3521 3522static void3523SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,3524		unsigned short RefreshRateTableIndex)3525{3526  unsigned char  *ROMAddr = NULL;3527  unsigned short tempax, tempbx, modeflag, romptr=0;3528  unsigned short resinfo, CRT2Index, ResIndex;3529  const struct SiS_LCDData *LCDPtr = NULL;3530  const struct SiS_TVData  *TVPtr  = NULL;3531#ifdef CONFIG_FB_SIS_3153532  short resinfo661;3533#endif3534 3535  if(ModeNo <= 0x13) {3536     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;3537     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;3538  } else if(SiS_Pr->UseCustomMode) {3539     modeflag = SiS_Pr->CModeFlag;3540     resinfo = 0;3541  } else {3542     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;3543     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;3544#ifdef CONFIG_FB_SIS_3153545     resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;3546     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&3547	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&3548	 (resinfo661 >= 0)                     &&3549	 (SiS_Pr->SiS_NeedRomModeData) ) {3550	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {3551	   if((romptr = (SISGETROMW(21)))) {3552	      romptr += (resinfo661 * 10);3553	      ROMAddr = SiS_Pr->VirtualRomBase;3554	   }3555	}3556     }3557#endif3558  }3559 3560  SiS_Pr->SiS_NewFlickerMode = 0;3561  SiS_Pr->SiS_RVBHRS = 50;3562  SiS_Pr->SiS_RY1COE = 0;3563  SiS_Pr->SiS_RY2COE = 0;3564  SiS_Pr->SiS_RY3COE = 0;3565  SiS_Pr->SiS_RY4COE = 0;3566  SiS_Pr->SiS_RVBHRS2 = 0;3567 3568  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);3569 3570  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {3571 3572     if(SiS_Pr->UseCustomMode) {3573 3574	SiS_Pr->SiS_RVBHCMAX  = 1;3575	SiS_Pr->SiS_RVBHCFACT = 1;3576	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;3577	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;3578 3579	tempax = SiS_Pr->CHTotal;3580	if(modeflag & HalfDCLK) tempax <<= 1;3581	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;3582	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;3583 3584     } else {3585 3586	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);3587 3588     }3589 3590  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {3591 3592     SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,3593		    &CRT2Index,&ResIndex);3594 3595     switch(CRT2Index) {3596	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;3597	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;3598	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;3599	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;3600	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;3601	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;3602	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;3603	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;3604	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;3605	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;3606	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;3607	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;3608	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;3609	default: TVPtr = SiS_Pr->SiS_StPALData;     break;3610     }3611 3612     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;3613     SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;3614     SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;3615     SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;3616     SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;3617     SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;3618     SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;3619     if(modeflag & HalfDCLK) {3620	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;3621	if(SiS_Pr->SiS_RVBHRS2) {3622	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;3623	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;3624	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;3625	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;3626	}3627     } else {3628	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;3629     }3630     SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;3631 3632     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {3633 3634	if((resinfo == SIS_RI_960x600)   ||3635	   (resinfo == SIS_RI_1024x768)  ||3636	   (resinfo == SIS_RI_1280x1024) ||3637	   (resinfo == SIS_RI_1280x720)) {3638	   SiS_Pr->SiS_NewFlickerMode = 0x40;3639	}3640 3641	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;3642 3643	SiS_Pr->SiS_HT = ExtHiTVHT;3644	SiS_Pr->SiS_VT = ExtHiTVVT;3645	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {3646	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {3647	      SiS_Pr->SiS_HT = StHiTVHT;3648	      SiS_Pr->SiS_VT = StHiTVVT;3649	   }3650	}3651 3652     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {3653 3654	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {3655	   SiS_Pr->SiS_HT = 1650;3656	   SiS_Pr->SiS_VT = 750;3657	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {3658	   SiS_Pr->SiS_HT = NTSCHT;3659	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;3660	   SiS_Pr->SiS_VT = NTSCVT;3661	} else {3662	   SiS_Pr->SiS_HT = NTSCHT;3663	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;3664	   SiS_Pr->SiS_VT = NTSCVT;3665	}3666 3667     } else {3668 3669	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;3670	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;3671	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;3672	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;3673 3674	if(modeflag & HalfDCLK) {3675	   SiS_Pr->SiS_RY1COE = 0x00;3676	   SiS_Pr->SiS_RY2COE = 0xf4;3677	   SiS_Pr->SiS_RY3COE = 0x10;3678	   SiS_Pr->SiS_RY4COE = 0x38;3679	}3680 3681	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {3682	   SiS_Pr->SiS_HT = NTSCHT;3683	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;3684	   SiS_Pr->SiS_VT = NTSCVT;3685	} else {3686	   SiS_Pr->SiS_HT = PALHT;3687	   SiS_Pr->SiS_VT = PALVT;3688	}3689 3690     }3691 3692  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {3693 3694     SiS_Pr->SiS_RVBHCMAX  = 1;3695     SiS_Pr->SiS_RVBHCFACT = 1;3696 3697     if(SiS_Pr->UseCustomMode) {3698 3699	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;3700	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;3701 3702	tempax = SiS_Pr->CHTotal;3703	if(modeflag & HalfDCLK) tempax <<= 1;3704	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;3705	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;3706 3707     } else {3708 3709	bool gotit = false;3710 3711	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {3712 3713	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;3714	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;3715	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;3716	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;3717	   gotit = true;3718 3719	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {3720 3721#ifdef CONFIG_FB_SIS_3153722	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];3723	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];3724	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);3725	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);3726	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);3727	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);3728	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);3729	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {3730	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;3731	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;3732	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;3733	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;3734	   }3735	   if(SiS_Pr->SiS_VGAHT) gotit = true;3736	   else {3737	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;3738	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;3739	      SiS_Pr->SiS_RVBHCMAX  = 1;3740	      SiS_Pr->SiS_RVBHCFACT = 1;3741	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;3742	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;3743	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;3744	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;3745	      SiS_Pr->SiS_RVBHRS2 = 0;3746	      gotit = true;3747	   }3748#endif3749 3750	}3751 3752	if(!gotit) {3753 3754	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,3755			  &CRT2Index,&ResIndex);3756 3757	   switch(CRT2Index) {3758	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;3759	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;3760	      case Panel_1280x720      :3761	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;3762	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;3763	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;3764	      case Panel_1280x800      :3765	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;3766	      case Panel_1280x800_2    :3767	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;3768	      case Panel_1280x854      :3769	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;3770	      case Panel_1280x960      :3771	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;3772	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;3773	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;3774	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;3775	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;3776	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;3777	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;3778	      case Panel_1680x1050     :3779	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;3780	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;3781#ifdef CONFIG_FB_SIS_3153782	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;3783	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;3784#endif3785	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;3786	   }3787 3788	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;3789	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;3790	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;3791	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;3792	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;3793	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;3794 3795        }3796 3797	tempax = SiS_Pr->PanelXRes;3798	tempbx = SiS_Pr->PanelYRes;3799 3800	switch(SiS_Pr->SiS_LCDResInfo) {3801	case Panel_1024x768:3802	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {3803	      if(SiS_Pr->ChipType < SIS_315H) {3804		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;3805		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;3806	      }3807	   } else {3808	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;3809	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;3810	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;3811	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;3812	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;3813	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;3814	   }3815	   break;3816	case Panel_1280x960:3817	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;3818	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;3819	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;3820	   break;3821	case Panel_1280x1024:3822	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;3823	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;3824	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;3825	   break;3826	case Panel_1600x1200:3827	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {3828	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;3829	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;3830	   }3831	   break;3832	}3833 3834	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {3835	   tempax = SiS_Pr->SiS_VGAHDE;3836	   tempbx = SiS_Pr->SiS_VGAVDE;3837	}3838 3839	SiS_Pr->SiS_HDE = tempax;3840	SiS_Pr->SiS_VDE = tempbx;3841     }3842  }3843}3844 3845static void3846SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,3847                unsigned short RefreshRateTableIndex)3848{3849 3850   if(SiS_Pr->SiS_VBType & VB_SISVB) {3851 3852      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {3853         SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);3854      } else {3855	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {3856	    /* Need LVDS Data for LCD on 301B-DH */3857	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);3858	 } else {3859	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);3860	 }3861      }3862 3863   } else {3864 3865      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);3866 3867   }3868}3869 3870/*********************************************/3871/*         GET LVDS DES (SKEW) DATA          */3872/*********************************************/3873 3874static const struct SiS_LVDSDes *3875SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)3876{3877   const struct SiS_LVDSDes *PanelDesPtr = NULL;3878 3879#ifdef CONFIG_FB_SIS_3003880   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {3881 3882      if(SiS_Pr->ChipType < SIS_315H) {3883	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {3884	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {3885	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;3886	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {3887		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;3888	       }3889            } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {3890	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;3891	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {3892		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;3893	       }3894	    }3895	 }3896      }3897   }3898#endif3899   return PanelDesPtr;3900}3901 3902static void3903SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,3904                   unsigned short RefreshRateTableIndex)3905{3906  unsigned short modeflag, ResIndex;3907  const struct SiS_LVDSDes *PanelDesPtr = NULL;3908 3909  SiS_Pr->SiS_LCDHDES = 0;3910  SiS_Pr->SiS_LCDVDES = 0;3911 3912  /* Some special cases */3913  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {3914 3915     /* Trumpion */3916     if(SiS_Pr->SiS_IF_DEF_TRUMPION) {3917	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {3918	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {3919	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;3920	   }3921	}3922	return;3923     }3924 3925     /* 640x480 on LVDS */3926     if(SiS_Pr->ChipType < SIS_315H) {3927	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {3928	   SiS_Pr->SiS_LCDHDES = 8;3929	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;3930	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;3931	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;3932	   return;3933	}3934     }3935 3936  } /* LCD */3937 3938  if( (SiS_Pr->UseCustomMode) 		         ||3939      (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||3940      (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||3941      (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||3942      (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {3943     return;3944  }3945 3946  if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;3947  else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;3948 3949  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {3950 3951#ifdef CONFIG_FB_SIS_3153952     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {3953	/* non-pass 1:1 only, see above */3954	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {3955	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);3956	}3957	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {3958	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);3959	}3960     }3961     if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {3962	switch(SiS_Pr->SiS_CustomT) {3963	case CUT_UNIWILL1024:3964	case CUT_UNIWILL10242:3965	case CUT_CLEVO1400:3966	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {3967	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;3968	   }3969	   break;3970	}3971	switch(SiS_Pr->SiS_LCDResInfo) {3972	case Panel_1280x1024:3973	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {3974	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;3975	   }3976	   break;3977	case Panel_1280x800:	/* Verified for Averatec 6240 */3978	case Panel_1280x800_2:	/* Verified for Asus A4L */3979	case Panel_1280x854:    /* Not verified yet FIXME */3980	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;3981	   break;3982	}3983     }3984#endif3985 3986  } else {3987 3988     if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {3989 3990	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {3991	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;3992	}3993 3994     } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {3995 3996	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;3997	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;3998 3999     } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {4000 4001	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {4002	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);4003	}4004	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {4005	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);4006	} else {4007	   if(SiS_Pr->ChipType < SIS_315H) {4008	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;4009	   } else {4010	      switch(SiS_Pr->SiS_LCDResInfo) {4011	      case Panel_800x600:4012	      case Panel_1024x768:4013	      case Panel_1280x1024:4014		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;4015		 break;4016	      case Panel_1400x1050:4017		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;4018		 break;4019	      }4020	   }4021	}4022 4023     } else {4024 4025        if(SiS_Pr->ChipType < SIS_315H) {4026#ifdef CONFIG_FB_SIS_3004027	   switch(SiS_Pr->SiS_LCDResInfo) {4028	   case Panel_800x600:4029	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {4030		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;4031	      } else {4032		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;4033		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;4034		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;4035		 else                          SiS_Pr->SiS_LCDVDES -= 4;4036	      }4037	      break;4038	   case Panel_1024x768:4039	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {4040		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;4041	      } else {4042		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;4043		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;4044		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;4045	      }4046	      break;4047	   case Panel_1024x600:4048	   default:4049	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&4050		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {4051		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;4052	      } else {4053		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;4054	      }4055	      break;4056	   }4057 4058	   switch(SiS_Pr->SiS_LCDTypeInfo) {4059	   case 1:4060	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;4061	      break;4062	   case 3: /* 640x480 only? */4063	      SiS_Pr->SiS_LCDHDES = 8;4064	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;4065	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;4066	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;4067	      break;4068	   }4069#endif4070        } else {4071#ifdef CONFIG_FB_SIS_3154072	   switch(SiS_Pr->SiS_LCDResInfo) {4073	   case Panel_1024x768:4074	   case Panel_1280x1024:4075	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {4076	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;4077	      }4078	      break;4079	   case Panel_320x240_1:4080	   case Panel_320x240_2:4081	   case Panel_320x240_3:4082	      SiS_Pr->SiS_LCDVDES = 524;4083	      break;4084	   }4085#endif4086	}4087     }4088 4089     if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {4090	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;4091	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {4092	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;4093	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {4094	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {4095	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {4096	         if(SiS_Pr->ChipType < SIS_315H) {4097	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;4098	         } else {4099#ifdef CONFIG_FB_SIS_3154100		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;4101		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;4102		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;4103		    if(!(modeflag & HalfDCLK)) {4104		       SiS_Pr->SiS_LCDHDES = 320;4105		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;4106		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;4107        	    }4108#endif4109		 }4110	      }4111	   }4112	}4113     }4114  }4115}4116 4117/*********************************************/4118/*           DISABLE VIDEO BRIDGE            */4119/*********************************************/4120 4121#ifdef CONFIG_FB_SIS_3154122static int4123SiS_HandlePWD(struct SiS_Private *SiS_Pr)4124{4125   int ret = 0;4126#ifdef SET_PWD4127   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;4128   unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);4129   unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;4130   unsigned short temp;4131 4132   if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&4133       (romptr)				&&4134       (SiS_Pr->SiS_PWDOffset) ) {4135      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);4136      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);4137      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);4138      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);4139      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);4140      temp = 0x00;4141      if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {4142         temp = 0x80;4143	 ret = 1;4144      }4145      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);4146   }4147#endif4148   return ret;4149}4150#endif4151 4152/* NEVER use any variables (VBInfo), this will be called4153 * from outside the context of modeswitch!4154 * MUST call getVBType before calling this4155 */4156void4157SiS_DisableBridge(struct SiS_Private *SiS_Pr)4158{4159#ifdef CONFIG_FB_SIS_3154160  unsigned short tempah, pushax=0, modenum;4161#endif4162  unsigned short temp=0;4163 4164  if(SiS_Pr->SiS_VBType & VB_SISVB) {4165 4166     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */4167 4168	if(SiS_Pr->ChipType < SIS_315H) {4169 4170#ifdef CONFIG_FB_SIS_300	   /* 300 series */4171 4172	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {4173	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4174		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);4175	      } else {4176		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);4177	      }4178	      SiS_PanelDelay(SiS_Pr, 3);4179	   }4180	   if(SiS_Is301B(SiS_Pr)) {4181	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);4182	      SiS_ShortDelay(SiS_Pr,1);4183	   }4184	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);4185	   SiS_DisplayOff(SiS_Pr);4186	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);4187	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);4188	   SiS_UnLockCRT2(SiS_Pr);4189	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {4190	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);4191	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);4192	   }4193	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||4194	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {4195	      SiS_PanelDelay(SiS_Pr, 2);4196	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4197	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);4198	      } else {4199		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);4200	      }4201	   }4202 4203#endif  /* CONFIG_FB_SIS_300 */4204 4205        } else {4206 4207#ifdef CONFIG_FB_SIS_315	   /* 315 series */4208 4209	   int didpwd = 0;4210	   bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||4211	                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);4212 4213	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;4214 4215	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4216 4217#ifdef SET_EMI4218	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {4219		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {4220		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);4221		 }4222	      }4223#endif4224 4225	      didpwd = SiS_HandlePWD(SiS_Pr);4226 4227	      if( (modenum <= 0x13)           ||4228		  (SiS_IsVAMode(SiS_Pr))      ||4229		  (!(SiS_IsDualEdge(SiS_Pr))) ) {4230		 if(!didpwd) {4231		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);4232		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);4233		 } else {4234		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);4235		 }4236	      }4237 4238	      if(!custom1) {4239		 SiS_DDC2Delay(SiS_Pr,0xff00);4240		 SiS_DDC2Delay(SiS_Pr,0xe000);4241		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);4242		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);4243		 if(IS_SIS740) {4244		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);4245		 }4246	         SiS_PanelDelay(SiS_Pr, 3);4247	      }4248 4249	   }4250 4251	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {4252	      /* if(SiS_Pr->ChipType < SIS_340) {*/4253		 tempah = 0xef;4254		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;4255		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);4256	      /*}*/4257	   }4258 4259	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4260	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);4261	   }4262 4263	   tempah = 0x3f;4264	   if(SiS_IsDualEdge(SiS_Pr)) {4265	      tempah = 0x7f;4266	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;4267	   }4268	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);4269 4270	   if((SiS_IsVAMode(SiS_Pr)) ||4271	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {4272 4273	      SiS_DisplayOff(SiS_Pr);4274	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4275		 SiS_PanelDelay(SiS_Pr, 2);4276	      }4277	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);4278	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);4279 4280	   }4281 4282	   if((!(SiS_IsVAMode(SiS_Pr))) ||4283	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {4284 4285	      if(!(SiS_IsDualEdge(SiS_Pr))) {4286		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);4287		 SiS_DisplayOff(SiS_Pr);4288	      }4289	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);4290 4291	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4292		 SiS_PanelDelay(SiS_Pr, 2);4293	      }4294 4295	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);4296	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);4297	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);4298	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);4299	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);4300 4301	   }4302 4303	   if(SiS_IsNotM650orLater(SiS_Pr)) {4304	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);4305	   }4306 4307	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4308 4309	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&4310		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&4311		  (!(SiS_IsDualEdge(SiS_Pr))) ) {4312 4313		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);4314		 if(!didpwd) {4315		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);4316		 }4317		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);4318	      }4319 4320	      if(!custom1) {4321		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);4322		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {4323		    if(SiS_IsVAorLCD(SiS_Pr)) {4324		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);4325		    }4326		 }4327	      }4328 4329	   }4330 4331#endif /* CONFIG_FB_SIS_315 */4332 4333	}4334 4335     } else {     /* ============ For 301 ================ */4336 4337        if(SiS_Pr->ChipType < SIS_315H) {4338#ifdef CONFIG_FB_SIS_3004339	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {4340	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);4341	      SiS_PanelDelay(SiS_Pr, 3);4342	   }4343#endif4344	}4345 4346	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */4347	SiS_DisplayOff(SiS_Pr);4348 4349	if(SiS_Pr->ChipType >= SIS_315H) {4350	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);4351	}4352 4353	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */4354 4355	if(SiS_Pr->ChipType >= SIS_315H) {4356	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);4357	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);4358	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);4359	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);4360	} else {4361#ifdef CONFIG_FB_SIS_3004362	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */4363	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||4364		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {4365		SiS_PanelDelay(SiS_Pr, 2);4366		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);4367	    }4368#endif4369	}4370 4371      }4372 4373  } else {     /* ============ For LVDS =============*/4374 4375    if(SiS_Pr->ChipType < SIS_315H) {4376 4377#ifdef CONFIG_FB_SIS_300	/* 300 series */4378 4379	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {4380	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);4381	}4382 4383	if(SiS_Pr->ChipType == SIS_730) {4384	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {4385	      SiS_WaitVBRetrace(SiS_Pr);4386	   }4387	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {4388	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);4389	      SiS_PanelDelay(SiS_Pr, 3);4390	   }4391	} else {4392	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {4393	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {4394		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {4395		    SiS_WaitVBRetrace(SiS_Pr);4396		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {4397		       SiS_DisplayOff(SiS_Pr);4398		    }4399		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);4400		    SiS_PanelDelay(SiS_Pr, 3);4401		 }4402	      }4403	   }4404	}4405 4406	SiS_DisplayOff(SiS_Pr);4407 4408	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);4409 4410	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);4411	SiS_UnLockCRT2(SiS_Pr);4412	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);4413	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);4414 4415	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||4416	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {4417	   SiS_PanelDelay(SiS_Pr, 2);4418	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);4419	}4420 4421#endif  /* CONFIG_FB_SIS_300 */4422 4423    } else {4424 4425#ifdef CONFIG_FB_SIS_315	/* 315 series */4426 4427	if(!(SiS_IsNotM650orLater(SiS_Pr))) {4428	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */4429	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);4430	   /* } */4431	}4432 4433	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {4434 4435	   if(SiS_Pr->ChipType == SIS_740) {4436	      temp = SiS_GetCH701x(SiS_Pr,0x61);4437	      if(temp < 1) {4438		 SiS_SetCH701x(SiS_Pr,0x76,0xac);4439		 SiS_SetCH701x(SiS_Pr,0x66,0x00);4440	      }4441 4442	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||4443		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {4444		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);4445	      }4446	   }4447 4448	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||4449	       (SiS_IsVAMode(SiS_Pr)) ) {4450	      SiS_Chrontel701xBLOff(SiS_Pr);4451	      SiS_Chrontel701xOff(SiS_Pr);4452	   }4453 4454	   if(SiS_Pr->ChipType != SIS_740) {4455	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||4456		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {4457		 SiS_SetCH701x(SiS_Pr,0x49,0x01);4458	      }4459	   }4460 4461	}4462 4463	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {4464	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);4465	   SiS_PanelDelay(SiS_Pr, 3);4466	}4467 4468	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||4469	    (!(SiS_IsDualEdge(SiS_Pr))) ||4470	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {4471	   SiS_DisplayOff(SiS_Pr);4472	}4473 4474	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||4475	    (!(SiS_IsDualEdge(SiS_Pr))) ||4476	    (!(SiS_IsVAMode(SiS_Pr))) ) {4477	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);4478	}4479 4480	if(SiS_Pr->ChipType == SIS_740) {4481	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);4482	}4483 4484	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);4485 4486	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||4487	    (!(SiS_IsDualEdge(SiS_Pr))) ||4488	    (!(SiS_IsVAMode(SiS_Pr))) ) {4489	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);4490	}4491 4492	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {4493	   if(SiS_CRT2IsLCD(SiS_Pr)) {4494	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);4495	      if(SiS_Pr->ChipType == SIS_550) {4496		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);4497		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);4498	      }4499	   }4500	} else {4501	   if(SiS_Pr->ChipType == SIS_740) {4502	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {4503		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);4504	      }4505	   } else if(SiS_IsVAMode(SiS_Pr)) {4506	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);4507	   }4508	}4509 4510	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {4511	   if(SiS_IsDualEdge(SiS_Pr)) {4512	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */4513	   } else {4514	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);4515	   }4516	}4517 4518	SiS_UnLockCRT2(SiS_Pr);4519 4520	if(SiS_Pr->ChipType == SIS_550) {4521	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/4522	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */4523	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||4524		   (!(SiS_IsDualEdge(SiS_Pr))) ||4525		   (!(SiS_IsVAMode(SiS_Pr))) ) {4526	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);4527	}4528 4529        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {4530	   if(SiS_CRT2IsLCD(SiS_Pr)) {4531	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {4532		 SiS_PanelDelay(SiS_Pr, 2);4533		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);4534	      }4535	   }4536        }4537 4538#endif  /* CONFIG_FB_SIS_315 */4539 4540    }  /* 315 series */4541 4542  }  /* LVDS */4543 4544}4545 4546/*********************************************/4547/*            ENABLE VIDEO BRIDGE            */4548/*********************************************/4549 4550/* NEVER use any variables (VBInfo), this will be called4551 * from outside the context of a mode switch!4552 * MUST call getVBType before calling this4553 */4554static4555void4556SiS_EnableBridge(struct SiS_Private *SiS_Pr)4557{4558  unsigned short temp=0, tempah;4559#ifdef CONFIG_FB_SIS_3154560  unsigned short temp1, pushax=0;4561  bool delaylong = false;4562#endif4563 4564  if(SiS_Pr->SiS_VBType & VB_SISVB) {4565 4566    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */4567 4568      if(SiS_Pr->ChipType < SIS_315H) {4569 4570#ifdef CONFIG_FB_SIS_300     /* 300 series */4571 4572	 if(SiS_CRT2IsLCD(SiS_Pr)) {4573	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4574	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);4575	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {4576	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);4577	    }4578	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {4579	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {4580		  SiS_PanelDelay(SiS_Pr, 0);4581	       }4582	    }4583	 }4584 4585	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&4586	    (SiS_CRT2IsLCD(SiS_Pr))) {4587 4588	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */4589	    SiS_DisplayOn(SiS_Pr);4590	    SiS_UnLockCRT2(SiS_Pr);4591	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);4592	    if(SiS_BridgeInSlavemode(SiS_Pr)) {4593	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);4594	    } else {4595	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);4596	    }4597	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {4598	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {4599		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {4600		     SiS_PanelDelay(SiS_Pr, 1);4601		  }4602		  SiS_WaitVBRetrace(SiS_Pr);4603		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);4604	       }4605	    }4606 4607	 } else {4608 4609	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */4610	    if(SiS_BridgeInSlavemode(SiS_Pr)) {4611	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);4612	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;4613	    }4614	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);4615	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);4616	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */4617	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);4618	    SiS_DisplayOn(SiS_Pr);4619	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4620	       if(SiS_CRT2IsLCD(SiS_Pr)) {4621		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {4622		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {4623		        SiS_PanelDelay(SiS_Pr, 1);4624		     }4625		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);4626		  }4627	       }4628	    }4629 4630	 }4631 4632 4633#endif /* CONFIG_FB_SIS_300 */4634 4635      } else {4636 4637#ifdef CONFIG_FB_SIS_315    /* 315 series */4638 4639#ifdef SET_EMI4640	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;4641	 int didpwd = 0;4642	 /* unsigned short  emidelay=0; */4643#endif4644 4645	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4646	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);4647#ifdef SET_EMI4648	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {4649	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);4650	    }4651#endif4652	 }4653 4654	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {4655	    /*if(SiS_Pr->ChipType < SIS_340) { */4656	       tempah = 0x10;4657	       if(SiS_LCDAEnabled(SiS_Pr)) {4658		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;4659		  else			    tempah = 0x08;4660	       }4661	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);4662	    /*}*/4663	 }4664 4665	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4666 4667	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);4668	    SiS_DisplayOff(SiS_Pr);4669	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);4670	    if(IS_SIS740) {4671	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);4672	    }4673 4674	    didpwd = SiS_HandlePWD(SiS_Pr);4675 4676	    if(SiS_IsVAorLCD(SiS_Pr)) {4677	       if(!didpwd) {4678		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {4679		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);4680		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);4681		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);4682		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {4683		        SiS_GenericDelay(SiS_Pr, 17664);4684		     }4685		  }4686	       } else {4687		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);4688		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {4689		     SiS_GenericDelay(SiS_Pr, 17664);4690		  }4691	       }4692	    }4693 4694	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {4695	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);4696	       delaylong = true;4697	    }4698 4699	 }4700 4701	 if(!(SiS_IsVAMode(SiS_Pr))) {4702 4703	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;4704	    if(SiS_BridgeInSlavemode(SiS_Pr)) {4705	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);4706	       if(!(tempah & SetCRT2ToRAMDAC)) {4707		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;4708	       }4709	    }4710	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);4711 4712	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */4713 4714	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);4715	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);4716 4717	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4718	       SiS_PanelDelay(SiS_Pr, 2);4719	    }4720 4721	 } else {4722 4723	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);4724 4725	 }4726 4727	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);4728	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);4729 4730	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {4731	    if( (SiS_LCDAEnabled(SiS_Pr)) ||4732	        (SiS_CRT2IsLCD(SiS_Pr)) ) {4733	       /* Enable "LVDS PLL power on" (even on 301C) */4734	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);4735	       /* Enable "LVDS Driver Power on" (even on 301C) */4736	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);4737	    }4738	 }4739 4740	 tempah = 0xc0;4741	 if(SiS_IsDualEdge(SiS_Pr)) {4742	    tempah = 0x80;4743	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;4744	 }4745	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);4746 4747	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {4748 4749	    SiS_PanelDelay(SiS_Pr, 2);4750 4751	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);4752	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);4753 4754	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {4755#ifdef SET_EMI4756	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {4757		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);4758		  SiS_GenericDelay(SiS_Pr, 2048);4759	       }4760#endif4761	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);4762 4763	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {4764#ifdef SET_EMI4765		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);4766 4767		  if(SiS_Pr->SiS_ROMNew) {4768		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;4769		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);4770		     if(romptr) {4771			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */4772			SiS_Pr->EMI_30 = 0;4773			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];4774			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];4775			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];4776			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;4777			/* emidelay = SISGETROMW((romptr + 0x22)); */4778			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;4779		     }4780		  }4781 4782		  /*                                              (P4_30|0x40)  */4783		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */4784		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */4785		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */4786		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */4787		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */4788		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */4789		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */4790		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */4791		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */4792 4793		  if(SiS_Pr->HaveEMI) {4794		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;4795		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;4796		  } else {4797		     r30 = 0;4798		  }4799 4800		  /* EMI_30 is read at driver start; however, the BIOS sets this4801		   * (if it is used) only if the LCD is in use. In case we caught4802		   * the machine while on TV output, this bit is not set and we4803		   * don't know if it should be set - hence our detection is wrong.4804		   * Work-around this here:4805		   */4806 4807		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {4808		     switch((cr36 & 0x0f)) {4809		     case 2:4810			r30 |= 0x40;4811			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;4812			if(!SiS_Pr->HaveEMI) {4813			   r31 = 0x05; r32 = 0x60; r33 = 0x33;4814			   if((cr36 & 0xf0) == 0x30) {4815			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;4816			   }4817			}4818			break;4819		     case 3:  /* 1280x1024 */4820			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;4821			if(!SiS_Pr->HaveEMI) {4822			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;4823			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {4824			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;4825			   }4826			}4827			break;4828		     case 9:  /* 1400x1050 */4829			r30 |= 0x40;4830			if(!SiS_Pr->HaveEMI) {4831			   r31 = 0x05; r32 = 0x60; r33 = 0x00;4832			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {4833			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */4834			   }4835			}4836			break;4837		     case 11: /* 1600x1200 - unknown */4838			r30 |= 0x40;4839			if(!SiS_Pr->HaveEMI) {4840			   r31 = 0x05; r32 = 0x60; r33 = 0x00;4841			}4842		     }4843                  }4844 4845		  /* BIOS values don't work so well sometimes */4846		  if(!SiS_Pr->OverruleEMI) {4847#ifdef COMPAL_HACK4848		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {4849			if((cr36 & 0x0f) == 0x09) {4850			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;4851			}4852 		     }4853#endif4854#ifdef COMPAQ_HACK4855		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {4856			if((cr36 & 0x0f) == 0x03) {4857			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;4858			}4859		     }4860#endif4861#ifdef ASUS_HACK4862		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {4863			if((cr36 & 0x0f) == 0x02) {4864			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */4865			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */4866			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */4867			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */4868			}4869		     }4870#endif4871		  }4872 4873		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {4874		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */4875		     SiS_GenericDelay(SiS_Pr, 2048);4876		  }4877		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);4878		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);4879		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);4880#endif	/* SET_EMI */4881 4882		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);4883 4884#ifdef SET_EMI4885		  if( (SiS_LCDAEnabled(SiS_Pr)) ||4886		      (SiS_CRT2IsLCD(SiS_Pr)) ) {4887		     if(r30 & 0x40) {4888			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/4889			SiS_PanelDelayLoop(SiS_Pr, 3, 5);4890			if(delaylong) {4891			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);4892			   delaylong = false;4893			}4894			SiS_WaitVBRetrace(SiS_Pr);4895			SiS_WaitVBRetrace(SiS_Pr);4896			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {4897			   SiS_GenericDelay(SiS_Pr, 1280);4898			}4899			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */4900			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/4901		     }4902		  }4903#endif4904	       }4905	    }4906 4907	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {4908	       if(SiS_IsVAorLCD(SiS_Pr)) {4909		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);4910		  if(delaylong) {4911		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);4912		  }4913		  SiS_WaitVBRetrace(SiS_Pr);4914		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {4915		     SiS_GenericDelay(SiS_Pr, 2048);4916		     SiS_WaitVBRetrace(SiS_Pr);4917		  }4918		  if(!didpwd) {4919		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);4920		  } else {4921		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);4922		  }4923	       }4924	    }4925 4926	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);4927	    SiS_DisplayOn(SiS_Pr);4928	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);4929 4930	 }4931 4932	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {4933	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);4934	 }4935 4936#endif /* CONFIG_FB_SIS_315 */4937 4938      }4939 4940    } else {	/* ============  For 301 ================ */4941 4942       if(SiS_Pr->ChipType < SIS_315H) {4943	  if(SiS_CRT2IsLCD(SiS_Pr)) {4944	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);4945	     SiS_PanelDelay(SiS_Pr, 0);4946	  }4947       }4948 4949       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */4950       if(SiS_BridgeInSlavemode(SiS_Pr)) {4951	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);4952	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;4953       }4954       SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);4955 4956       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */4957 4958       if(SiS_Pr->ChipType >= SIS_315H) {4959	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);4960	  if(!(temp & 0x80)) {4961	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */4962	  }4963       }4964 4965       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */4966 4967       SiS_VBLongWait(SiS_Pr);4968       SiS_DisplayOn(SiS_Pr);4969       if(SiS_Pr->ChipType >= SIS_315H) {4970	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);4971       }4972       SiS_VBLongWait(SiS_Pr);4973 4974       if(SiS_Pr->ChipType < SIS_315H) {4975	  if(SiS_CRT2IsLCD(SiS_Pr)) {4976	     SiS_PanelDelay(SiS_Pr, 1);4977	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);4978	  }4979       }4980 4981    }4982 4983  } else {   /* =================== For LVDS ================== */4984 4985    if(SiS_Pr->ChipType < SIS_315H) {4986 4987#ifdef CONFIG_FB_SIS_300    /* 300 series */4988 4989       if(SiS_CRT2IsLCD(SiS_Pr)) {4990	  if(SiS_Pr->ChipType == SIS_730) {4991	     SiS_PanelDelay(SiS_Pr, 1);4992	     SiS_PanelDelay(SiS_Pr, 1);4993	     SiS_PanelDelay(SiS_Pr, 1);4994	  }4995	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);4996	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {4997	     SiS_PanelDelay(SiS_Pr, 0);4998	  }4999       }5000 5001       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);5002       SiS_DisplayOn(SiS_Pr);5003       SiS_UnLockCRT2(SiS_Pr);5004       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);5005       if(SiS_BridgeInSlavemode(SiS_Pr)) {5006	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);5007       } else {5008	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);5009       }5010 5011       if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {5012	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {5013	     SiS_WaitVBRetrace(SiS_Pr);5014	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);5015	  }5016       }5017 5018       if(SiS_CRT2IsLCD(SiS_Pr)) {5019	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {5020	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {5021		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {5022		   SiS_PanelDelay(SiS_Pr, 1);5023		   SiS_PanelDelay(SiS_Pr, 1);5024		}5025		SiS_WaitVBRetrace(SiS_Pr);5026		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);5027	     }5028	  }5029       }5030 5031#endif  /* CONFIG_FB_SIS_300 */5032 5033    } else {5034 5035#ifdef CONFIG_FB_SIS_315    /* 315 series */5036 5037       if(!(SiS_IsNotM650orLater(SiS_Pr))) {5038	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */5039	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);5040	  /*}*/5041       }5042 5043       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {5044	  if(SiS_CRT2IsLCD(SiS_Pr)) {5045	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);5046	     SiS_PanelDelay(SiS_Pr, 0);5047	  }5048       }5049 5050       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);5051       SiS_UnLockCRT2(SiS_Pr);5052 5053       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);5054 5055       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {5056	  temp = SiS_GetCH701x(SiS_Pr,0x66);5057	  temp &= 0x20;5058	  SiS_Chrontel701xBLOff(SiS_Pr);5059       }5060 5061       if(SiS_Pr->ChipType != SIS_550) {5062	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);5063       }5064 5065       if(SiS_Pr->ChipType == SIS_740) {5066	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {5067	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {5068		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);5069	     }5070	  }5071       }5072 5073       temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);5074       if(!(temp1 & 0x80)) {5075	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);5076       }5077 5078       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {5079	  if(temp) {5080	     SiS_Chrontel701xBLOn(SiS_Pr);5081	  }5082       }5083 5084       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {5085	  if(SiS_CRT2IsLCD(SiS_Pr)) {5086	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);5087	     if(SiS_Pr->ChipType == SIS_550) {5088		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);5089		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);5090	     }5091	  }5092       } else if(SiS_IsVAMode(SiS_Pr)) {5093	  if(SiS_Pr->ChipType != SIS_740) {5094	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);5095	  }5096       }5097 5098       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {5099	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);5100       }5101 5102       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {5103	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {5104	     SiS_Chrontel701xOn(SiS_Pr);5105	  }5106	  if( (SiS_IsVAMode(SiS_Pr)) ||5107	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {5108	     SiS_ChrontelDoSomething1(SiS_Pr);5109	  }5110       }5111 5112       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {5113	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {5114	     if( (SiS_IsVAMode(SiS_Pr)) ||5115		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {5116		SiS_Chrontel701xBLOn(SiS_Pr);5117		SiS_ChrontelInitTVVSync(SiS_Pr);5118	     }5119	  }5120       } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {5121	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {5122	     if(SiS_CRT2IsLCD(SiS_Pr)) {5123		SiS_PanelDelay(SiS_Pr, 1);5124		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);5125	     }5126	  }5127       }5128 5129#endif  /* CONFIG_FB_SIS_315 */5130 5131    } /* 310 series */5132 5133  }  /* LVDS */5134 5135}5136 5137/*********************************************/5138/*         SET PART 1 REGISTER GROUP         */5139/*********************************************/5140 5141/* Set CRT2 OFFSET / PITCH */5142static void5143SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,5144		unsigned short RRTI)5145{5146   unsigned short offset;5147   unsigned char  temp;5148 5149   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;5150 5151   offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);5152 5153   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));5154   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));5155 5156   temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);5157   if(offset & 0x07) temp++;5158   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);5159}5160 5161/* Set CRT2 sync and PanelLink mode */5162static void5163SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)5164{5165   unsigned short tempah=0, tempbl, infoflag;5166 5167   tempbl = 0xC0;5168 5169   if(SiS_Pr->UseCustomMode) {5170      infoflag = SiS_Pr->CInfoFlag;5171   } else {5172      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;5173   }5174 5175   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */5176 5177      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {5178	 tempah = 0;5179      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {5180	 tempah = SiS_Pr->SiS_LCDInfo;5181      } else tempah = infoflag >> 8;5182      tempah &= 0xC0;5183      tempah |= 0x20;5184      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;5185      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {5186	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||5187	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {5188	    tempah |= 0xf0;5189	 }5190	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||5191	     (SiS_Pr->SiS_IF_DEF_DSTN) ||5192	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||5193	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||5194	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {5195	    tempah |= 0x30;5196	 }5197	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||5198	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {5199	    tempah &= ~0xc0;5200	 }5201      }5202      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {5203	 if(SiS_Pr->ChipType >= SIS_315H) {5204	    tempah >>= 3;5205	    tempah &= 0x18;5206	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);5207	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */5208	 } else {5209	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);5210	 }5211      } else {5212	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);5213      }5214 5215   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {5216 5217      if(SiS_Pr->ChipType < SIS_315H) {5218 5219#ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */5220 5221	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */5222 5223	    tempah = infoflag >> 8;5224	    tempbl = 0;5225	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {5226	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {5227		  tempah = SiS_Pr->SiS_LCDInfo;5228		  tempbl = (tempah >> 6) & 0x03;5229	       }5230	    }5231	    tempah &= 0xC0;5232	    tempah |= 0x20;5233	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;5234	    tempah |= 0xc0;5235	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);5236	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {5237	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);5238	    }5239 5240	 } else {							/* 630 - 301 */5241 5242	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;5243	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;5244	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);5245 5246	 }5247 5248#endif /* CONFIG_FB_SIS_300 */5249 5250      } else {5251 5252#ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */5253 5254	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */5255 5256	    tempbl = 0;5257	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&5258	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {5259	       tempah = infoflag >> 8;5260	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {5261		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);5262	       }5263	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&5264		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {5265	       tempah = infoflag >> 8;5266	       tempbl = 0x03;5267	    } else {5268	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);5269	       tempbl = (tempah >> 6) & 0x03;5270	       tempbl |= 0x08;5271	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;5272	    }5273	    tempah &= 0xC0;5274	    tempah |= 0x20;5275	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;5276	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;5277	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);5278	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {5279	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {5280		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);5281	       }5282	    }5283 5284	 } else {							/* 315 - TMDS */5285 5286	    tempah = tempbl = infoflag >> 8;5287	    if(!SiS_Pr->UseCustomMode) {5288	       tempbl = 0;5289	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {5290		  if(ModeNo <= 0x13) {5291		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));5292		  }5293	       }5294	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5295		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {5296		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {5297		       tempah = SiS_Pr->SiS_LCDInfo;5298		       tempbl = (tempah >> 6) & 0x03;5299		    }5300		  }5301	       }5302	    }5303	    tempah &= 0xC0;5304	    tempah |= 0x20;5305	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;5306	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {5307	       /* Imitate BIOS bug */5308	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;5309	    }5310	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {5311	       tempah >>= 3;5312	       tempah &= 0x18;5313	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);5314	    } else {5315	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);5316	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {5317		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {5318		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);5319		  }5320	       }5321	    }5322 5323         }5324#endif  /* CONFIG_FB_SIS_315 */5325      }5326   }5327}5328 5329/* Set CRT2 FIFO on 300/540/630/730 */5330#ifdef CONFIG_FB_SIS_3005331static void5332SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)5333{5334  unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;5335  unsigned short temp, index, modeidindex, refreshratetableindex;5336  unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;5337  unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;5338  unsigned int   data, pci50, pciA0;5339  static const unsigned char colortharray[] = {5340  	1, 1, 2, 2, 3, 45341  };5342 5343  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;5344 5345  if(!SiS_Pr->CRT1UsesCustomMode) {5346 5347     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */5348     SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);5349     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);5350     SiS_Pr->SiS_SelectCRT2Rate = 0;5351     refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);5352 5353     if(CRT1ModeNo >= 0x13) {5354        /* Get VCLK */5355	index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);5356	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;5357 5358	/* Get colordepth */5359	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;5360	if(!colorth) colorth++;5361     }5362 5363  } else {5364 5365     CRT1ModeNo = 0xfe;5366 5367     /* Get VCLK */5368     VCLK = SiS_Pr->CSRClock_CRT1;5369 5370     /* Get color depth */5371     colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];5372 5373  }5374 5375  if(CRT1ModeNo >= 0x13) {5376     /* Get MCLK */5377     if(SiS_Pr->ChipType == SIS_300) {5378        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);5379     } else {5380        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);5381     }5382     index &= 0x07;5383     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;5384 5385     temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;5386     if(!temp) temp++;5387     temp <<= 2;5388 5389     data2 = temp - ((colorth * VCLK) / MCLK);5390 5391     temp = (28 * 16) % data2;5392     data2 = (28 * 16) / data2;5393     if(temp) data2++;5394 5395     if(SiS_Pr->ChipType == SIS_300) {5396 5397	SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);5398	data = SiS_GetFIFOThresholdB300(tempbx, tempcl);5399 5400     } else {5401 5402	pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);5403	pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);5404 5405        if(SiS_Pr->ChipType == SIS_730) {5406 5407	   index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);5408	   index += (unsigned short)(((pci50 >> 9)) & 0x03);5409 5410	   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */5411	   index = 0;  /* -- do it like the BIOS anyway... */5412 5413	} else {5414 5415	   pci50 >>= 24;5416	   pciA0 >>= 24;5417 5418	   index = (pci50 >> 1) & 0x07;5419 5420	   if(pci50 & 0x01)    index += 6;5421	   if(!(pciA0 & 0x01)) index += 24;5422 5423	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;5424 5425	}5426 5427	data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;5428	if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;5429 5430     }5431 5432     data += data2;						/* CRT1 Request Period */5433 5434     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;5435     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;5436 5437     if(!SiS_Pr->UseCustomMode) {5438 5439	CRT2ModeNo = ModeNo;5440	SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);5441 5442	refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);5443 5444	/* Get VCLK  */5445	index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);5446	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;5447 5448	if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {5449	   if(SiS_Pr->SiS_UseROM) {5450	      if(ROMAddr[0x220] & 0x01) {5451		 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);5452	      }5453           }5454        }5455 5456     } else {5457 5458	/* Get VCLK */5459	CRT2ModeNo = 0xfe;5460	VCLK = SiS_Pr->CSRClock;5461 5462     }5463 5464     /* Get colordepth */5465     colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;5466     if(!colorth) colorth++;5467 5468     data = data * VCLK * colorth;5469     temp = data % (MCLK << 4);5470     data = data / (MCLK << 4);5471     if(temp) data++;5472 5473     if(data < 6) data = 6;5474     else if(data > 0x14) data = 0x14;5475 5476     if(SiS_Pr->ChipType == SIS_300) {5477        temp = 0x16;5478	if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))5479	   temp = 0x13;5480     } else {5481        temp = 0x16;5482	if(( (SiS_Pr->ChipType == SIS_630) ||5483	     (SiS_Pr->ChipType == SIS_730) )  &&5484	   (SiS_Pr->ChipRevision >= 0x30))5485	   temp = 0x1b;5486     }5487     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);5488 5489     if((SiS_Pr->ChipType == SIS_630) &&5490	(SiS_Pr->ChipRevision >= 0x30)) {5491	if(data > 0x13) data = 0x13;5492     }5493     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);5494 5495  } else {  /* If mode <= 0x13, we just restore everything */5496 5497     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;5498     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;5499 5500  }5501}5502#endif5503 5504/* Set CRT2 FIFO on 315/330 series */5505#ifdef CONFIG_FB_SIS_3155506static void5507SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)5508{5509  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);5510  if( (SiS_Pr->ChipType == SIS_760)      &&5511      (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&5512      (SiS_Pr->SiS_ModeType == Mode32Bpp) &&5513      (SiS_Pr->SiS_VGAHDE >= 1280)	  &&5514      (SiS_Pr->SiS_VGAVDE >= 1024) ) {5515     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);5516     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);5517     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);5518     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);5519     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);5520     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);5521  } else {5522     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);5523  }5524 5525}5526#endif5527 5528static unsigned short5529SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)5530{5531  unsigned int tempax,tempbx;5532 5533  tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;5534  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;5535  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;5536  return (unsigned short)tempax;5537}5538 5539/* Set Part 1 / SiS bridge slave mode */5540static void5541SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,5542                  unsigned short RefreshRateTableIndex)5543{5544  unsigned short temp, modeflag, i, j, xres=0, VGAVDE;5545  static const unsigned short CRTranslation[] = {5546       /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */5547	  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,5548       /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */5549	  0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,5550       /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */5551	  0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x005552  };5553 5554  if(ModeNo <= 0x13) {5555     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;5556  } else if(SiS_Pr->UseCustomMode) {5557     modeflag = SiS_Pr->CModeFlag;5558     xres = SiS_Pr->CHDisplay;5559  } else {5560     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;5561     xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;5562  }5563 5564  /* The following is only done if bridge is in slave mode: */5565 5566  if(SiS_Pr->ChipType >= SIS_315H) {5567     if(xres >= 1600) {  /* BIOS: == 1600 */5568        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);5569     }5570  }5571 5572  SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */5573 5574  SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;5575  if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;5576 5577  SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;5578  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {5579     SiS_Pr->CHBlankStart += 16;5580  }5581 5582  SiS_Pr->CHBlankEnd = 32;5583  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {5584     if(xres == 1600) SiS_Pr->CHBlankEnd += 80;5585  }5586 5587  temp = SiS_Pr->SiS_VGAHT - 96;5588  if(!(modeflag & HalfDCLK)) temp -= 32;5589  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {5590     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);5591     temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);5592     temp -= 3;5593     temp <<= 3;5594  } else {5595     if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;5596  }5597  SiS_Pr->CHSyncStart = temp;5598 5599  SiS_Pr->CHSyncEnd = 0xffe8; 	/* results in 0x2000 in registers */5600 5601  SiS_Pr->CVTotal = 2049;  	/* Max VT, 0x0801, results in 0x7ff in registers */5602 5603  VGAVDE = SiS_Pr->SiS_VGAVDE;5604  if     (VGAVDE ==  357) VGAVDE =  350;5605  else if(VGAVDE ==  360) VGAVDE =  350;5606  else if(VGAVDE ==  375) VGAVDE =  350;5607  else if(VGAVDE ==  405) VGAVDE =  400;5608  else if(VGAVDE ==  420) VGAVDE =  400;5609  else if(VGAVDE ==  525) VGAVDE =  480;5610  else if(VGAVDE == 1056) VGAVDE = 1024;5611  SiS_Pr->CVDisplay = VGAVDE;5612 5613  SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;5614 5615  SiS_Pr->CVBlankEnd = 1;5616  if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;5617 5618  temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;5619  SiS_Pr->CVSyncStart = VGAVDE + temp;5620 5621  temp >>= 3;5622  SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;5623 5624  SiS_CalcCRRegisters(SiS_Pr, 0);5625  SiS_Pr->CCRT1CRTC[16] &= ~0xE0;5626 5627  for(i = 0; i <= 7; i++) {5628     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);5629  }5630  for(i = 0x10, j = 8; i <= 0x12; i++, j++) {5631     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);5632  }5633  for(i = 0x15, j = 11; i <= 0x16; i++, j++) {5634     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);5635  }5636  for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {5637     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);5638  }5639 5640  temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;5641  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);5642 5643  temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;5644  if(modeflag & DoubleScanMode) temp |= 0x80;5645  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);5646 5647  temp = 0;5648  temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);5649  if(modeflag & HalfDCLK) temp |= 0x08;5650  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* SR01: HalfDCLK[3], 8/9 div dotclock[0] */5651 5652  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* CR14: (text mode: underline location) */5653  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* CR17: n/a */5654 5655  temp = 0;5656  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {5657     temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;5658  }5659  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* SR0E, dither[7] */5660 5661  temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));5662  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);			/* ? */5663}5664 5665/* Setup panel link5666 * This is used for LVDS, LCDA and Chrontel TV output5667 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA5668 */5669static void5670SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,5671		unsigned short RefreshRateTableIndex)5672{5673  unsigned short modeflag, resinfo = 0;5674  unsigned short push2, tempax, tempbx, tempcx, temp;5675  unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;5676  bool islvds = false, issis  = false, chkdclkfirst = false;5677#ifdef CONFIG_FB_SIS_3005678  unsigned short crt2crtc = 0;5679#endif5680#ifdef CONFIG_FB_SIS_3155681  unsigned short pushcx;5682#endif5683 5684  if(ModeNo <= 0x13) {5685     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;5686     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;5687#ifdef CONFIG_FB_SIS_3005688     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;5689#endif5690  } else if(SiS_Pr->UseCustomMode) {5691     modeflag = SiS_Pr->CModeFlag;5692  } else {5693     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;5694     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;5695#ifdef CONFIG_FB_SIS_3005696     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;5697#endif5698  }5699 5700  /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */5701  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {5702     islvds = true;5703  }5704 5705  /* is really sis if sis bridge, but not 301B-DH */5706  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {5707     issis = true;5708  }5709 5710  if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {5711     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {5712        chkdclkfirst = true;5713     }5714  }5715 5716#ifdef CONFIG_FB_SIS_3155717  if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {5718     if(IS_SIS330) {5719        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);5720     } else if(IS_SIS740) {5721        if(islvds) {5722           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);5723	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);5724        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {5725           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);5726        }5727     } else {5728        if(islvds) {5729           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);5730	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);5731        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {5732           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);5733	   if(SiS_Pr->SiS_VBType & VB_SIS30xC) {5734	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||5735	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {5736	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);5737	      }5738	   }5739        }5740     }5741  }5742#endif5743 5744  /* Horizontal */5745 5746  tempax = SiS_Pr->SiS_LCDHDES;5747  if(islvds) {5748     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5749	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {5750	   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&5751	      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {5752	      tempax -= 8;5753	   }5754	}5755     }5756  }5757 5758  temp = (tempax & 0x0007);5759  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */5760  temp = (tempax >> 3) & 0x00FF;5761  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */5762 5763  tempbx = SiS_Pr->SiS_HDE;5764  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5765     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {5766        tempbx = SiS_Pr->PanelXRes;5767     }5768     if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||5769        (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||5770        (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {5771        tempbx >>= 1;5772     }5773  }5774 5775  tempax += tempbx;5776  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;5777 5778  temp = tempax;5779  if(temp & 0x07) temp += 8;5780  temp >>= 3;5781  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */5782 5783  tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;5784 5785  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5786     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {5787        if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;5788     }5789  }5790 5791  tempcx += tempax;5792  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;5793 5794  temp = (tempcx >> 3) & 0x00FF;5795  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5796     if(SiS_Pr->SiS_IF_DEF_TRUMPION) {5797	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {5798	   switch(ModeNo) {5799	   case 0x04:5800	   case 0x05:5801	   case 0x0d: temp = 0x56; break;5802	   case 0x10: temp = 0x60; break;5803	   case 0x13: temp = 0x5f; break;5804	   case 0x40:5805	   case 0x41:5806	   case 0x4f:5807	   case 0x43:5808	   case 0x44:5809	   case 0x62:5810	   case 0x56:5811	   case 0x53:5812	   case 0x5d:5813	   case 0x5e: temp = 0x54; break;5814	   }5815	}5816     }5817  }5818  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */5819 5820  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5821     temp += 2;5822     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {5823	temp += 8;5824	if(SiS_Pr->PanelHRE != 999) {5825	   temp = tempcx + SiS_Pr->PanelHRE;5826	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;5827	   temp >>= 3;5828	}5829     }5830  } else {5831     temp += 10;5832  }5833 5834  temp &= 0x1F;5835  temp |= ((tempcx & 0x07) << 5);5836  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */5837 5838  /* Vertical */5839 5840  tempax = SiS_Pr->SiS_VGAVDE;5841  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5842     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {5843	tempax = SiS_Pr->PanelYRes;5844     }5845  }5846 5847  tempbx = SiS_Pr->SiS_LCDVDES + tempax;5848  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;5849 5850  push2 = tempbx;5851 5852  tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;5853  if(SiS_Pr->ChipType < SIS_315H) {5854     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5855	if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {5856	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;5857	}5858     }5859  }5860  if(islvds) tempcx >>= 1;5861  else       tempcx >>= 2;5862 5863  if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&5864      (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&5865      (SiS_Pr->PanelVRS != 999) ) {5866     tempcx = SiS_Pr->PanelVRS;5867     tempbx += tempcx;5868     if(issis) tempbx++;5869  } else {5870     tempbx += tempcx;5871     if(SiS_Pr->ChipType < SIS_315H) tempbx++;5872     else if(issis)                   tempbx++;5873  }5874 5875  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;5876 5877  temp = tempbx & 0x00FF;5878  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {5879     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {5880	if(ModeNo == 0x10) temp = 0xa9;5881     }5882  }5883  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);			/* BPLVRS */5884 5885  tempcx >>= 3;5886  tempcx++;5887 5888  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5889     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {5890        if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;5891     }5892  }5893 5894  tempcx += tempbx;5895  temp = tempcx & 0x000F;5896  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */5897 5898  temp = ((tempbx >> 8) & 0x07) << 3;5899  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {5900     if(SiS_Pr->SiS_HDE != 640) {5901        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;5902     }5903  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;5904  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;5905  tempbx = 0x87;5906  if((SiS_Pr->ChipType >= SIS_315H) ||5907     (SiS_Pr->ChipRevision >= 0x30)) {5908     tempbx = 0x07;5909     if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {5910	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;5911     }5912     /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */5913     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {5914	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {5915	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;5916	} else {5917	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;5918	}5919     }5920  }5921  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);5922 5923  tempbx = push2;						/* BPLVDEE */5924 5925  tempcx = SiS_Pr->SiS_LCDVDES;					/* BPLVDES */5926 5927  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {5928     switch(SiS_Pr->SiS_LCDResInfo) {5929     case Panel_640x480:5930	tempbx = SiS_Pr->SiS_VGAVDE - 1;5931	tempcx = SiS_Pr->SiS_VGAVDE;5932	break;5933     case Panel_800x600:5934	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {5935	   if(resinfo == SIS_RI_800x600) tempcx++;5936	}5937	break;5938     case Panel_1024x600:5939	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {5940	   if(resinfo == SIS_RI_1024x600) tempcx++;5941	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {5942	      if(resinfo == SIS_RI_800x600) tempcx++;5943	   }5944	}5945	break;5946     case Panel_1024x768:5947	if(SiS_Pr->ChipType < SIS_315H) {5948	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {5949	      if(resinfo == SIS_RI_1024x768) tempcx++;5950	   }5951	}5952	break;5953     }5954  }5955 5956  temp = ((tempbx >> 8) & 0x07) << 3;5957  temp |= ((tempcx >> 8) & 0x07);5958  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);5959  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);5960  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);5961 5962  /* Vertical scaling */5963 5964  if(SiS_Pr->ChipType < SIS_315H) {5965 5966#ifdef CONFIG_FB_SIS_300      /* 300 series */5967     tempeax = SiS_Pr->SiS_VGAVDE << 6;5968     temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);5969     tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;5970     if(temp) tempeax++;5971 5972     if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;5973 5974     temp = (unsigned short)(tempeax & 0x00FF);5975     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */5976     tempvcfact = temp;5977#endif /* CONFIG_FB_SIS_300 */5978 5979  } else {5980 5981#ifdef CONFIG_FB_SIS_315  /* 315 series */5982     tempeax = SiS_Pr->SiS_VGAVDE << 18;5983     tempebx = SiS_Pr->SiS_VDE;5984     temp = (tempeax % tempebx);5985     tempeax = tempeax / tempebx;5986     if(temp) tempeax++;5987     tempvcfact = tempeax;5988 5989     temp = (unsigned short)(tempeax & 0x00FF);5990     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);5991     temp = (unsigned short)((tempeax & 0x00FF00) >> 8);5992     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);5993     temp = (unsigned short)((tempeax & 0x00030000) >> 16);5994     if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;5995     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);5996 5997     if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {5998        temp = (unsigned short)(tempeax & 0x00FF);5999        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);6000        temp = (unsigned short)((tempeax & 0x00FF00) >> 8);6001        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);6002        temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);6003        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);6004        temp = 0;6005        if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;6006        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);6007     }6008#endif6009 6010  }6011 6012  /* Horizontal scaling */6013 6014  tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/6015  if(chkdclkfirst) {6016     if(modeflag & HalfDCLK) tempeax >>= 1;6017  }6018  tempebx = tempeax << 16;6019  if(SiS_Pr->SiS_HDE == tempeax) {6020     tempecx = 0xFFFF;6021  } else {6022     tempecx = tempebx / SiS_Pr->SiS_HDE;6023     if(SiS_Pr->ChipType >= SIS_315H) {6024        if(tempebx % SiS_Pr->SiS_HDE) tempecx++;6025     }6026  }6027 6028  if(SiS_Pr->ChipType >= SIS_315H) {6029     tempeax = (tempebx / tempecx) - 1;6030  } else {6031     tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;6032  }6033  tempecx = (tempecx << 16) | (tempeax & 0xFFFF);6034  temp = (unsigned short)(tempecx & 0x00FF);6035  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);6036 6037  if(SiS_Pr->ChipType >= SIS_315H) {6038     tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;6039     tempbx = (unsigned short)(tempeax & 0xFFFF);6040  } else {6041     tempeax = SiS_Pr->SiS_VGAVDE << 6;6042     tempbx = tempvcfact & 0x3f;6043     if(tempbx == 0) tempbx = 64;6044     tempeax /= tempbx;6045     tempbx = (unsigned short)(tempeax & 0xFFFF);6046  }6047  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;6048  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {6049     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;6050     else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;6051  }6052 6053  temp = ((tempbx >> 8) & 0x07) << 3;6054  temp = temp | ((tempecx >> 8) & 0x07);6055  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);6056  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);6057 6058  tempecx >>= 16;						/* BPLHCFACT  */6059  if(!chkdclkfirst) {6060     if(modeflag & HalfDCLK) tempecx >>= 1;6061  }6062  temp = (unsigned short)((tempecx & 0xFF00) >> 8);6063  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);6064  temp = (unsigned short)(tempecx & 0x00FF);6065  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);6066 6067#ifdef CONFIG_FB_SIS_3156068  if(SiS_Pr->ChipType >= SIS_315H) {6069     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {6070        if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {6071           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);6072	}6073     } else {6074        if(islvds) {6075           if(SiS_Pr->ChipType == SIS_740) {6076              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);6077           } else {6078	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);6079           }6080        }6081     }6082  }6083#endif6084 6085#ifdef CONFIG_FB_SIS_3006086  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {6087     unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;6088     unsigned char *trumpdata;6089     int   i, j = crt2crtc;6090     unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };6091     unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };6092     unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };6093 6094     if(SiS_Pr->SiS_UseROM) {6095	trumpdata = &ROMAddr[0x8001 + (j * 80)];6096     } else {6097	if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;6098	trumpdata = &SiS300_TrumpionData[j][0];6099     }6100 6101     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);6102     for(i=0; i<5; i++) {6103	SiS_SetTrumpionBlock(SiS_Pr, trumpdata);6104     }6105     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {6106	if(ModeNo == 0x13) {6107	   for(i=0; i<4; i++) {6108	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);6109	   }6110	} else if(ModeNo == 0x10) {6111	   for(i=0; i<4; i++) {6112	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);6113	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);6114	   }6115	}6116     }6117     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);6118  }6119#endif6120 6121#ifdef CONFIG_FB_SIS_3156122  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {6123     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);6124     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);6125     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);6126     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);6127     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);6128     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);6129     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);6130     tempax = SiS_Pr->SiS_HDE;					/* Blps = lcdhdee(lcdhdes+HDE) + 64 */6131     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||6132        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||6133        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;6134     tempax += 64;6135     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);6136     temp = (tempax >> 8) << 3;6137     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);6138     tempax += 32;						/* Blpe = lBlps+32 */6139     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);6140     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);		/* Bflml = 0 */6141     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);6142 6143     tempax = SiS_Pr->SiS_VDE;6144     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||6145        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||6146        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;6147     tempax >>= 1;6148     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);6149     temp = (tempax >> 8) << 3;6150     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);6151 6152     tempeax = SiS_Pr->SiS_HDE;6153     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||6154        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||6155        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;6156     tempeax <<= 2;			 			/* BDxFIFOSTOP = (HDE*4)/128 */6157     temp = tempeax & 0x7f;6158     tempeax >>= 7;6159     if(temp) tempeax++;6160     temp = tempeax & 0x3f;6161     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);6162     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);		/* BDxWadrst0 */6163     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);6164     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);6165     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);6166 6167     tempax = SiS_Pr->SiS_HDE;6168     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||6169        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||6170        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;6171     tempax >>= 4;						/* BDxWadroff = HDE*4/8/8 */6172     pushcx = tempax;6173     temp = tempax & 0x00FF;6174     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);6175     temp = ((tempax & 0xFF00) >> 8) << 3;6176     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);6177 6178     tempax = SiS_Pr->SiS_VDE;				 	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */6179     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||6180        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||6181        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;6182     tempeax = tempax * pushcx;6183     temp = tempeax & 0xFF;6184     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);6185     temp = (tempeax & 0xFF00) >> 8;6186     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);6187     temp = ((tempeax & 0xFF0000) >> 16) | 0x10;6188     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);6189     temp = ((tempeax & 0x01000000) >> 24) << 7;6190     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);6191 6192     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);6193     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);6194     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);6195     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);6196     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);6197 6198     if(SiS_Pr->SiS_IF_DEF_FSTN) {6199        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);6200        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);6201        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);6202        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);6203        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);6204        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);6205        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);6206        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);6207        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);6208        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);6209        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);6210        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);6211        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);6212        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);6213        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);6214        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);6215        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);6216        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);6217        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);6218        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);6219     }6220  }6221#endif  /* CONFIG_FB_SIS_315 */6222}6223 6224/* Set Part 1 */6225static void6226SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,6227		unsigned short RefreshRateTableIndex)6228{6229#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)6230  unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;6231#endif6232  unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;6233  unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;6234#ifdef CONFIG_FB_SIS_3156235  unsigned short  tempbl=0;6236#endif6237 6238  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {6239     SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);6240     return;6241  }6242 6243  if(ModeNo <= 0x13) {6244     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;6245  } else if(SiS_Pr->UseCustomMode) {6246     modeflag = SiS_Pr->CModeFlag;6247  } else {6248     CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);6249     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;6250     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;6251  }6252 6253  SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);6254 6255  if( ! ((SiS_Pr->ChipType >= SIS_315H) &&6256         (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&6257         (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {6258 6259     if(SiS_Pr->ChipType < SIS_315H ) {6260#ifdef CONFIG_FB_SIS_3006261	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);6262#endif6263     } else {6264#ifdef CONFIG_FB_SIS_3156265	SiS_SetCRT2FIFO_310(SiS_Pr);6266#endif6267     }6268 6269     /* 1. Horizontal setup */6270 6271     if(SiS_Pr->ChipType < SIS_315H ) {6272 6273#ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/6274 6275	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */6276	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */6277 6278	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;6279	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */6280 6281	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */6282	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */6283 6284	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */6285	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;6286	tempbx = pushbx + tempcx;6287	tempcx <<= 1;6288	tempcx += tempbx;6289 6290	bridgeadd = 12;6291 6292#endif /* CONFIG_FB_SIS_300 */6293 6294     } else {6295 6296#ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */6297 6298	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */6299	if(modeflag & HalfDCLK) {6300	   if(SiS_Pr->SiS_VBType & VB_SISVB) {6301	      tempcx >>= 1;6302	   } else {6303	      tempax = SiS_Pr->SiS_VGAHDE >> 1;6304	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;6305	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {6306	         tempcx = SiS_Pr->SiS_HT - tempax;6307	      }6308	   }6309	}6310	tempcx--;6311	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */6312	temp = (tempcx >> 4) & 0xF0;6313	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */6314 6315	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */6316	tempbx = SiS_Pr->SiS_VGAHDE;6317	tempcx -= tempbx;6318	tempcx >>= 2;6319	if(modeflag & HalfDCLK) {6320	   tempbx >>= 1;6321	   tempcx >>= 1;6322	}6323	tempbx += 16;6324 6325	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */6326 6327	pushbx = tempbx;6328	tempcx >>= 1;6329	tempbx += tempcx;6330	tempcx += tempbx;6331 6332	bridgeadd = 16;6333 6334	if(SiS_Pr->SiS_VBType & VB_SISVB) {6335	   if(SiS_Pr->ChipType >= SIS_661) {6336	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||6337		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {6338		 if(resinfo == SIS_RI_1280x1024) {6339		    tempcx = (tempcx & 0xff00) | 0x30;6340		 } else if(resinfo == SIS_RI_1600x1200) {6341		    tempcx = (tempcx & 0xff00) | 0xff;6342		 }6343	      }6344	   }6345        }6346 6347#endif  /* CONFIG_FB_SIS_315 */6348 6349     }  /* 315/330 series */6350 6351     if(SiS_Pr->SiS_VBType & VB_SISVB) {6352 6353	if(SiS_Pr->UseCustomMode) {6354	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;6355	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;6356	   tempax = SiS_Pr->SiS_VGAHT;6357	   if(modeflag & HalfDCLK) tempax >>= 1;6358	   tempax--;6359	   if(tempcx > tempax) tempcx = tempax;6360	}6361 6362	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {6363	   unsigned char cr4, cr14, cr5, cr15;6364	   if(SiS_Pr->UseCustomMode) {6365	      cr4  = SiS_Pr->CCRT1CRTC[4];6366	      cr14 = SiS_Pr->CCRT1CRTC[14];6367	      cr5  = SiS_Pr->CCRT1CRTC[5];6368	      cr15 = SiS_Pr->CCRT1CRTC[15];6369	   } else {6370	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];6371	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];6372	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];6373	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];6374	   }6375	   tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */6376	   tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */6377	   tempcx &= 0x00FF;6378	   tempcx |= (tempbx & 0xFF00);6379	   tempbx += bridgeadd;6380	   tempcx += bridgeadd;6381	   tempax = SiS_Pr->SiS_VGAHT;6382	   if(modeflag & HalfDCLK) tempax >>= 1;6383	   tempax--;6384	   if(tempcx > tempax) tempcx = tempax;6385	}6386 6387	if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {6388	   tempbx = 1040;6389	   tempcx = 1044;   /* HWCursor bug! */6390	}6391 6392     }6393 6394     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */6395 6396     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */6397 6398     temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);6399     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */6400 6401     /* 2. Vertical setup */6402 6403     tempcx = SiS_Pr->SiS_VGAVT - 1;6404     temp = tempcx & 0x00FF;6405 6406     if(SiS_Pr->ChipType < SIS_661) {6407        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {6408	   if(SiS_Pr->ChipType < SIS_315H) {6409	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {6410	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {6411	            temp--;6412	         }6413	      }6414	   } else {6415	      temp--;6416	   }6417	} else if(SiS_Pr->ChipType >= SIS_315H) {6418	   temp--;6419	}6420     }6421     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */6422 6423     tempbx = SiS_Pr->SiS_VGAVDE - 1;6424     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */6425 6426     temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);6427     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */6428 6429     if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {6430	tempbx++;6431	tempax = tempbx;6432	tempcx++;6433	tempcx -= tempax;6434	tempcx >>= 2;6435	tempbx += tempcx;6436	if(tempcx < 4) tempcx = 4;6437	tempcx >>= 2;6438	tempcx += tempbx;6439	tempcx++;6440     } else {6441	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */6442	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */6443     }6444 6445     if(SiS_Pr->SiS_VBType & VB_SISVB) {6446	if(SiS_Pr->UseCustomMode) {6447	   tempbx = SiS_Pr->CVSyncStart;6448	   tempcx = SiS_Pr->CVSyncEnd;6449	}6450	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {6451	   unsigned char cr8, cr7, cr13;6452	   if(SiS_Pr->UseCustomMode) {6453	      cr8    = SiS_Pr->CCRT1CRTC[8];6454	      cr7    = SiS_Pr->CCRT1CRTC[7];6455	      cr13   = SiS_Pr->CCRT1CRTC[13];6456	      tempcx = SiS_Pr->CCRT1CRTC[9];6457	   } else {6458	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];6459	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];6460	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];6461	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];6462	   }6463	   tempbx = cr8;6464	   if(cr7  & 0x04) tempbx |= 0x0100;6465	   if(cr7  & 0x80) tempbx |= 0x0200;6466	   if(cr13 & 0x08) tempbx |= 0x0400;6467	}6468     }6469     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */6470 6471     temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);6472     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */6473 6474     /* 3. Panel delay compensation */6475 6476     if(SiS_Pr->ChipType < SIS_315H) {6477 6478#ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */6479 6480	if(SiS_Pr->SiS_VBType & VB_SISVB) {6481	   temp = 0x20;6482	   if(SiS_Pr->ChipType == SIS_300) {6483	      temp = 0x10;6484	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;6485	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;6486	   }6487	   if(SiS_Pr->SiS_VBType & VB_SIS301) {6488	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;6489	   }6490	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;6491	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;6492	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;6493	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {6494	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;6495	      else 					    temp = 0x20;6496	   }6497	   if(SiS_Pr->SiS_UseROM) {6498	      if(ROMAddr[0x220] & 0x80) {6499		 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)6500		    temp = ROMAddr[0x221];6501		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)6502		    temp = ROMAddr[0x222];6503		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)6504		    temp = ROMAddr[0x223];6505		 else6506		    temp = ROMAddr[0x224];6507	      }6508	   }6509	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {6510	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;6511	   }6512 6513	} else {6514	   temp = 0x20;6515	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {6516	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;6517	   }6518	   if(SiS_Pr->SiS_UseROM) {6519	      if(ROMAddr[0x220] & 0x80) {6520	         temp = ROMAddr[0x220];6521	      }6522	   }6523	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {6524	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;6525	   }6526	}6527 6528	temp &= 0x3c;6529 6530	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */6531 6532#endif  /* CONFIG_FB_SIS_300 */6533 6534     } else {6535 6536#ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/6537 6538	if(SiS_Pr->ChipType < SIS_661) {6539 6540	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {6541 6542	      if(SiS_Pr->ChipType == SIS_740) temp = 0x03;6543	      else 		              temp = 0x00;6544 6545	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;6546	      tempbl = 0xF0;6547	      if(SiS_Pr->ChipType == SIS_650) {6548		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {6549		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;6550		 }6551	      }6552 6553	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {6554		 temp = 0x08;6555		 tempbl = 0;6556		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {6557		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;6558		 }6559	      }6560 6561	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */6562	   }6563 6564	} /* < 661 */6565 6566	tempax = 0;6567	if(modeflag & DoubleScanMode) tempax |= 0x80;6568	if(modeflag & HalfDCLK)       tempax |= 0x40;6569	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);6570 6571#endif  /* CONFIG_FB_SIS_315 */6572 6573     }6574 6575  }  /* Slavemode */6576 6577  if(SiS_Pr->SiS_VBType & VB_SISVB) {6578     if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {6579	/* For 301BDH with LCD, we set up the Panel Link */6580	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);6581     } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {6582	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);6583     }6584  } else {6585     if(SiS_Pr->ChipType < SIS_315H) {6586	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);6587     } else {6588	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {6589	   if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {6590	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);6591	   }6592	} else {6593	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);6594	}6595     }6596  }6597}6598 6599/*********************************************/6600/*         SET PART 2 REGISTER GROUP         */6601/*********************************************/6602 6603#ifdef CONFIG_FB_SIS_3156604static unsigned char *6605SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)6606{6607   const unsigned char *tableptr = NULL;6608   unsigned short      a, b, p = 0;6609 6610   a = SiS_Pr->SiS_VGAHDE;6611   b = SiS_Pr->SiS_HDE;6612   if(tabletype) {6613      a = SiS_Pr->SiS_VGAVDE;6614      b = SiS_Pr->SiS_VDE;6615   }6616 6617   if(a < b) {6618      tableptr = SiS_Part2CLVX_1;6619   } else if(a == b) {6620      tableptr = SiS_Part2CLVX_2;6621   } else {6622      if(SiS_Pr->SiS_TVMode & TVSetPAL) {6623	 tableptr = SiS_Part2CLVX_4;6624      } else {6625	 tableptr = SiS_Part2CLVX_3;6626      }6627      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {6628	 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	tableptr = SiS_Part2CLVX_3;6629	 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 	tableptr = SiS_Part2CLVX_3;6630	 else 				         	tableptr = SiS_Part2CLVX_5;6631      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {6632	 tableptr = SiS_Part2CLVX_6;6633      }6634      do {6635	 if((tableptr[p] | tableptr[p+1] << 8) == a) break;6636	 p += 0x42;6637      } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);6638      if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;6639   }6640   p += 2;6641   return ((unsigned char *)&tableptr[p]);6642}6643 6644static void6645SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,6646	      	    unsigned short RefreshRateTableIndex)6647{6648   unsigned char *tableptr;6649   unsigned char temp;6650   int i, j;6651 6652   if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;6653 6654   tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);6655   for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {6656      SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);6657   }6658   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {6659      tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);6660      for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {6661         SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);6662      }6663   }6664   temp = 0x10;6665   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;6666   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);6667}6668 6669static bool6670SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,6671		    unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,6672		    unsigned short *ResIndex)6673{6674 6675  if(SiS_Pr->ChipType < SIS_315H) return false;6676 6677  if(ModeNo <= 0x13)6678     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;6679  else6680     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;6681 6682  (*ResIndex) &= 0x3f;6683  (*CRT2Index) = 0;6684 6685  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {6686     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {6687        (*CRT2Index) = 200;6688     }6689  }6690 6691  if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {6692     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {6693        if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;6694     }6695  }6696  return (((*CRT2Index) != 0));6697}6698#endif6699 6700#ifdef CONFIG_FB_SIS_3006701static void6702SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)6703{6704   unsigned short tempcx;6705   static const unsigned char atable[] = {6706       0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,6707       0xab,0x87,0xab,0x9e,0xe7,0x02,0x026708   };6709 6710   if(!SiS_Pr->UseCustomMode) {6711      if( ( ( (SiS_Pr->ChipType == SIS_630) ||6712	      (SiS_Pr->ChipType == SIS_730) ) &&6713	    (SiS_Pr->ChipRevision > 2) )  &&6714	  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&6715	  (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&6716	  (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {6717	 if(ModeNo == 0x13) {6718	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);6719	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);6720	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);6721	 } else if((crt2crtc & 0x3F) == 4) {6722	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);6723	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);6724	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);6725	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);6726	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);6727	 }6728      }6729 6730      if(SiS_Pr->ChipType < SIS_315H) {6731	 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {6732	    crt2crtc &= 0x1f;6733	    tempcx = 0;6734	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {6735	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {6736		  tempcx += 7;6737	       }6738	    }6739	    tempcx += crt2crtc;6740	    if(crt2crtc >= 4) {6741	       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);6742	    }6743 6744	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {6745	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {6746		  if(crt2crtc == 4) {6747		     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);6748		  }6749	       }6750	    }6751	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);6752	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);6753	 }6754      }6755   }6756}6757 6758/* For ECS A907. Highly preliminary. */6759static void6760SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,6761		    unsigned short ModeNo)6762{6763  const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;6764  unsigned short crt2crtc, resindex;6765  int i, j;6766 6767  if(SiS_Pr->ChipType != SIS_300) return;6768  if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;6769  if(SiS_Pr->UseCustomMode) return;6770 6771  if(ModeNo <= 0x13) {6772     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;6773  } else {6774     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;6775  }6776 6777  resindex = crt2crtc & 0x3F;6778  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;6779  else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;6780 6781  /* The BIOS code (1.16.51,56) is obviously a fragment! */6782  if(ModeNo > 0x13) {6783     CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;6784     resindex = 4;6785  }6786 6787  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);6788  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);6789  for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {6790     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);6791  }6792  for(j = 0x1c; j <= 0x1d; i++, j++ ) {6793     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);6794  }6795  for(j = 0x1f; j <= 0x21; i++, j++ ) {6796     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);6797  }6798  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);6799  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);6800}6801#endif6802 6803static void6804SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)6805{6806  if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;6807  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;6808  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;6809 6810  if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {6811     if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {6812        static const unsigned char specialtv[] = {6813		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,6814		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,6815		0x58,0xe4,0x73,0xda,0x136816	};6817	int i, j;6818	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {6819	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);6820	}6821	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);6822	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {6823	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {6824	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);6825	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);6826	   } else {6827	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */6828	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */6829	   }6830	}6831     }6832  } else {6833     if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||6834        (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {6835        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */6836        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */6837     } else {6838        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */6839        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */6840     }6841  }6842}6843 6844static void6845SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)6846{6847  unsigned short temp;6848 6849  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {6850     if(SiS_Pr->SiS_VGAVDE == 525) {6851	temp = 0xc3;6852	if(SiS_Pr->SiS_ModeType <= ModeVGA) {6853	   temp++;6854	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;6855	}6856	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);6857	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);6858     } else if(SiS_Pr->SiS_VGAVDE == 420) {6859	temp = 0x4d;6860	if(SiS_Pr->SiS_ModeType <= ModeVGA) {6861	   temp++;6862	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;6863	}6864	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);6865     }6866  }6867 6868  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {6869     if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {6870	if(SiS_Pr->SiS_VBType & VB_SIS30xB) {6871	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);6872	   /* Not always for LV, see SetGrp2 */6873	}6874	temp = 1;6875	if(ModeNo <= 0x13) temp = 3;6876	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);6877     }6878#if 06879     /* 651+301C, for 1280x768 - do I really need that? */6880     if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {6881        if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {6882	   if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||6883	      ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {6884	      SiS_SetReg(SiS_Part2Port,0x01,0x2b);6885	      SiS_SetReg(SiS_Part2Port,0x02,0x13);6886	      SiS_SetReg(SiS_Part2Port,0x04,0xe5);6887	      SiS_SetReg(SiS_Part2Port,0x05,0x08);6888	      SiS_SetReg(SiS_Part2Port,0x06,0xe2);6889	      SiS_SetReg(SiS_Part2Port,0x1c,0x21);6890	      SiS_SetReg(SiS_Part2Port,0x1d,0x45);6891	      SiS_SetReg(SiS_Part2Port,0x1f,0x0b);6892	      SiS_SetReg(SiS_Part2Port,0x20,0x00);6893	      SiS_SetReg(SiS_Part2Port,0x21,0xa9);6894	      SiS_SetReg(SiS_Part2Port,0x23,0x0b);6895	      SiS_SetReg(SiS_Part2Port,0x25,0x04);6896	   }6897	}6898     }6899#endif6900  }6901}6902 6903static void6904SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,6905		unsigned short RefreshRateTableIndex)6906{6907  unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;6908  unsigned short push2, modeflag, crt2crtc, bridgeoffset;6909  unsigned int   longtemp, PhaseIndex;6910  bool           newtvphase;6911  const unsigned char *TimingPoint;6912#ifdef CONFIG_FB_SIS_3156913  unsigned short resindex, CRT2Index;6914  const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;6915 6916  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;6917#endif6918 6919  if(ModeNo <= 0x13) {6920     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;6921     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;6922  } else if(SiS_Pr->UseCustomMode) {6923     modeflag = SiS_Pr->CModeFlag;6924     crt2crtc = 0;6925  } else {6926     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;6927     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;6928  }6929 6930  temp = 0;6931  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;6932  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;6933  if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;6934  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;6935 6936  if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) 	      temp |= 0x10;6937 6938  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);6939 6940  PhaseIndex  = 0x01; /* SiS_PALPhase */6941  TimingPoint = SiS_Pr->SiS_PALTiming;6942 6943  newtvphase = false;6944  if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&6945      ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||6946	(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {6947     newtvphase = true;6948  }6949 6950  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {6951 6952     TimingPoint = SiS_Pr->SiS_HiTVExtTiming;6953     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {6954        TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;6955        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {6956	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;6957        }6958     }6959 6960  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {6961 6962     i = 0;6963     if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;6964     else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;6965 6966     TimingPoint = &SiS_YPbPrTable[i][0];6967 6968     PhaseIndex = 0x00; /* SiS_NTSCPhase */6969 6970  } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {6971 6972     if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */6973 6974  } else {6975 6976     TimingPoint = SiS_Pr->SiS_NTSCTiming;6977     PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;	/* SiS_PALPhase : SiS_NTSCPhase */6978     if(newtvphase) PhaseIndex += 8;					/* SiS_PALPhase2 : SiS_NTSCPhase2 */6979 6980  }6981 6982  if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {6983     PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;	/* SiS_PALMPhase : SiS_PALNPhase */6984     if(newtvphase) PhaseIndex += 8;					/* SiS_PALMPhase2 : SiS_PALNPhase2 */6985  }6986 6987  if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {6988     if(SiS_Pr->SiS_TVMode & TVSetPALM) {6989        PhaseIndex = 0x05; /* SiS_SpecialPhaseM */6990     } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {6991        PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */6992     } else {6993        PhaseIndex = 0x10; /* SiS_SpecialPhase */6994     }6995  }6996 6997  for(i = 0x31, j = 0; i <= 0x34; i++, j++) {6998     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);6999  }7000 7001  for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {7002     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);7003  }7004  for(i = 0x39; i <= 0x45; i++, j++) {7005     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);7006  }7007 7008  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {7009     if(SiS_Pr->SiS_ModeType != ModeText) {7010        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);7011     }7012  }7013 7014  SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);7015 7016  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);7017  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);7018  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);7019  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);7020 7021  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)	tempax = 950;7022  else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;7023  else if(SiS_Pr->SiS_TVMode & TVSetPAL)	tempax = 520;7024  else						tempax = 440; /* NTSC, YPbPr 525 */7025 7026  if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||7027      ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&7028        ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {7029 7030     tempax -= SiS_Pr->SiS_VDE;7031     tempax >>= 1;7032     if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {7033        tempax >>= 1;7034     }7035     tempax &= 0x00ff;7036 7037     temp = tempax + (unsigned short)TimingPoint[0];7038     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);7039 7040     temp = tempax + (unsigned short)TimingPoint[1];7041     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);7042 7043     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {7044        if(SiS_Pr->SiS_TVMode & TVSetPAL) {7045           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);7046           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);7047        } else {7048           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);7049           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);7050        }7051     }7052 7053  }7054 7055  tempcx = SiS_Pr->SiS_HT;7056  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;7057  tempcx--;7058  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;7059  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);7060  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));7061 7062  tempcx = SiS_Pr->SiS_HT >> 1;7063  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;7064  tempcx += 7;7065  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;7066  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));7067 7068  tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);7069  tempbx += tempcx;7070  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);7071  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));7072 7073  tempbx += 8;7074  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {7075     tempbx -= 4;7076     tempcx = tempbx;7077  }7078  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));7079 7080  j += 2;7081  tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));7082  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);7083  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));7084 7085  tempcx += 8;7086  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;7087  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));7088 7089  tempcx = SiS_Pr->SiS_HT >> 1;7090  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;7091  j += 2;7092  tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));7093  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));7094 7095  tempcx -= 11;7096  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {7097     tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;7098  }7099  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);7100 7101  tempbx = SiS_Pr->SiS_VDE;7102  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {7103     if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;7104     if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;7105     if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;7106  } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&7107             (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {7108     tempbx >>= 1;7109     if(SiS_Pr->ChipType >= SIS_315H) {7110        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {7111	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;7112	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {7113	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {7114	      if(crt2crtc == 4) tempbx++;7115	   }7116	}7117     }7118     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {7119        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {7120	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;7121	}7122	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {7123	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */7124        }7125     }7126  }7127  tempbx -= 2;7128  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);7129 7130  temp = (tempcx >> 8) & 0x0F;7131  temp |= ((tempbx >> 2) & 0xC0);7132  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {7133     temp |= 0x10;7134     if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;7135  }7136  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);7137 7138  if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {7139     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));7140  }7141 7142  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {7143     tempbx = SiS_Pr->SiS_VDE;7144     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&7145         (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {7146        tempbx >>= 1;7147     }7148     tempbx -= 3;7149     temp = ((tempbx >> 3) & 0x60) | 0x18;7150     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);7151     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);7152 7153     if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {7154	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));7155     }7156  }7157 7158  tempbx = 0;7159  if(!(modeflag & HalfDCLK)) {7160     if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {7161        tempax = 0;7162        tempbx |= 0x20;7163     }7164  }7165 7166  tempch = tempcl = 0x01;7167  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {7168     if(SiS_Pr->SiS_VGAHDE >= 960) {7169        if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {7170	   tempcl = 0x20;7171	   if(SiS_Pr->SiS_VGAHDE >= 1280) {7172              tempch = 20;7173              tempbx &= ~0x20;7174           } else {7175	      tempch = 25; /* OK */7176	   }7177        }7178     }7179  }7180 7181  if(!(tempbx & 0x20)) {7182     if(modeflag & HalfDCLK) tempcl <<= 1;7183     longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;7184     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;7185     tempax = longtemp / SiS_Pr->SiS_HDE;7186     if(longtemp % SiS_Pr->SiS_HDE) tempax++;7187     tempbx |= ((tempax >> 8) & 0x1F);7188     tempcx = tempax >> 13;7189  }7190 7191  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);7192  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);7193 7194  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {7195 7196     tempcx &= 0x07;7197     if(tempbx & 0x20) tempcx = 0;7198     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);7199 7200     if(SiS_Pr->SiS_TVMode & TVSetPAL) {7201        tempbx = 0x0382;7202        tempcx = 0x007e;7203     } else {7204        tempbx = 0x0369;7205        tempcx = 0x0061;7206     }7207     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);7208     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);7209     temp = (tempcx & 0x0300) >> 6;7210     temp |= ((tempbx >> 8) & 0x03);7211     if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {7212        temp |= 0x10;7213	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;7214	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;7215     }7216     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);7217 7218     temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);7219     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));7220 7221     SiS_SetTVSpecial(SiS_Pr, ModeNo);7222 7223     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {7224        temp = 0;7225        if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;7226        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);7227     }7228 7229  }7230 7231  if(SiS_Pr->SiS_TVMode & TVSetPALM) {7232     if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {7233        temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);7234        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));7235     }7236     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);7237  }7238 7239  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {7240     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {7241        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);7242     }7243  }7244 7245  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;7246 7247  /* From here: Part2 LCD setup */7248 7249  tempbx = SiS_Pr->SiS_HDE;7250  if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;7251  tempbx--;			         	/* RHACTE = HDE - 1 */7252  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);7253  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));7254 7255  temp = 0x01;7256  if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {7257     if(SiS_Pr->SiS_ModeType == ModeEGA) {7258        if(SiS_Pr->SiS_VGAHDE >= 1024) {7259           temp = 0x02;7260           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {7261              temp = 0x01;7262	   }7263        }7264     }7265  }7266  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);7267 7268  tempbx = SiS_Pr->SiS_VDE - 1;7269  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);7270  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));7271 7272  tempcx = SiS_Pr->SiS_VT - 1;7273  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);7274  temp = (tempcx >> 3) & 0xE0;7275  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {7276     /* Enable dithering; only do this for 32bpp mode */7277     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {7278        temp |= 0x10;7279     }7280  }7281  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);7282 7283  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);7284  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);7285 7286  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);7287  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);7288 7289#ifdef CONFIG_FB_SIS_3157290  if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,7291                          			&CRT2Index, &resindex)) {7292      switch(CRT2Index) {7293        case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;7294	default:7295        case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;7296      }7297 7298      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);7299      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);7300      for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {7301        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);7302      }7303      for(j = 0x1c; j <= 0x1d; i++, j++ ) {7304        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);7305      }7306      for(j = 0x1f; j <= 0x21; i++, j++ ) {7307        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);7308      }7309      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);7310      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);7311 7312      SiS_SetGroup2_Tail(SiS_Pr, ModeNo);7313 7314  } else {7315#endif7316 7317    /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */7318    /*             Clevo dual-link 1024x768 */7319    /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */7320    /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */7321 7322    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {7323       if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {7324          tempbx = SiS_Pr->SiS_VDE - 1;7325          tempcx = SiS_Pr->SiS_VT - 1;7326       } else {7327          tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);7328	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);7329       }7330    } else {7331       tempbx = SiS_Pr->PanelYRes;7332       tempcx = SiS_Pr->SiS_VT;7333       tempax = 1;7334       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {7335          tempax = SiS_Pr->PanelYRes;7336	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */7337          if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {7338             tempax = tempcx = 0;7339          } else {7340             tempax -= SiS_Pr->SiS_VDE;7341          }7342          tempax >>= 1;7343       }7344       tempcx -= tempax; /* lcdvdes */7345       tempbx -= tempax; /* lcdvdee */7346    }7347 7348    /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */7349 7350    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */7351    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */7352 7353    temp = (tempbx >> 5) & 0x38;7354    temp |= ((tempcx >> 8) & 0x07);7355    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);7356 7357    tempax = SiS_Pr->SiS_VDE;7358    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {7359       tempax = SiS_Pr->PanelYRes;7360    }7361    tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;7362    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {7363       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {7364	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;7365       }7366    }7367 7368    tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;7369    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {7370       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {7371          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */7372             tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;7373	     if(tempax % 4) { tempax >>= 2; tempax++; }7374	     else           { tempax >>= 2;           }7375             tempbx -= (tempax - 1);7376	  } else {7377	     tempbx -= 10;7378	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;7379	  }7380       }7381    }7382    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {7383       tempbx++;7384       if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {7385          if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {7386	     tempbx = 770;7387	     tempcx = 3;7388	  }7389       }7390    }7391 7392    /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */7393 7394    if(SiS_Pr->UseCustomMode) {7395       tempbx = SiS_Pr->CVSyncStart;7396    }7397 7398    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */7399 7400    temp = (tempbx >> 4) & 0xF0;7401    tempbx += (tempcx + 1);7402    temp |= (tempbx & 0x0F);7403 7404    if(SiS_Pr->UseCustomMode) {7405       temp &= 0xf0;7406       temp |= (SiS_Pr->CVSyncEnd & 0x0f);7407    }7408 7409    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);7410 7411#ifdef CONFIG_FB_SIS_3007412    SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);7413#endif7414 7415    bridgeoffset = 7;7416    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;7417    if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */7418    if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;7419    else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */7420    /* Higher bridgeoffset shifts to the LEFT */7421 7422    temp = 0;7423    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {7424       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {7425	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);7426	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;7427       }7428    }7429    temp += bridgeoffset;7430    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */7431    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));7432 7433    tempcx = SiS_Pr->SiS_HT;7434    tempax = tempbx = SiS_Pr->SiS_HDE;7435    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {7436       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {7437          tempax = SiS_Pr->PanelXRes;7438          tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);7439       }7440    }7441    if(SiS_IsDualLink(SiS_Pr)) {7442       tempcx >>= 1;7443       tempbx >>= 1;7444       tempax >>= 1;7445    }7446 7447    tempbx += bridgeoffset;7448 7449    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */7450    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));7451 7452    tempcx = (tempcx - tempax) >> 2;7453 7454    tempbx += tempcx;7455    push2 = tempbx;7456 7457    if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {7458       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {7459          if(SiS_Pr->SiS_LCDInfo & LCDPass11) {7460             if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;7461	  }7462       }7463    }7464 7465    if(SiS_Pr->UseCustomMode) {7466       tempbx = SiS_Pr->CHSyncStart;7467       if(modeflag & HalfDCLK) tempbx <<= 1;7468       if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;7469       tempbx += bridgeoffset;7470    }7471 7472    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */7473    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));7474 7475    tempbx = push2;7476 7477    tempcx <<= 1;7478    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {7479       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;7480    }7481    tempbx += tempcx;7482 7483    if(SiS_Pr->UseCustomMode) {7484       tempbx = SiS_Pr->CHSyncEnd;7485       if(modeflag & HalfDCLK) tempbx <<= 1;7486       if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;7487       tempbx += bridgeoffset;7488    }7489 7490    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */7491 7492    SiS_SetGroup2_Tail(SiS_Pr, ModeNo);7493 7494#ifdef CONFIG_FB_SIS_3007495    SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);7496#endif7497#ifdef CONFIG_FB_SIS_3157498  } /* CRT2-LCD from table */7499#endif7500}7501 7502/*********************************************/7503/*         SET PART 3 REGISTER GROUP         */7504/*********************************************/7505 7506static void7507SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)7508{7509  unsigned short i;7510  const unsigned char *tempdi;7511 7512  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;7513 7514#ifndef SIS_CP7515  SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);7516#else7517  SIS_CP_INIT301_CP7518#endif7519 7520  if(SiS_Pr->SiS_TVMode & TVSetPAL) {7521     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);7522     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);7523  } else {7524     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);7525     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);7526  }7527 7528  if(SiS_Pr->SiS_TVMode & TVSetPALM) {7529     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);7530     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);7531     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);7532  }7533 7534  tempdi = NULL;7535  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {7536     tempdi = SiS_Pr->SiS_HiTVGroup3Data;7537     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {7538        tempdi = SiS_Pr->SiS_HiTVGroup3Simu;7539     }7540  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {7541     if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {7542        tempdi = SiS_HiTVGroup3_1;7543        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;7544     }7545  }7546  if(tempdi) {7547     for(i=0; i<=0x3E; i++) {7548        SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);7549     }7550     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {7551	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {7552	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);7553	}7554     }7555  }7556 7557#ifdef SIS_CP7558  SIS_CP_INIT301_CP27559#endif7560}7561 7562/*********************************************/7563/*         SET PART 4 REGISTER GROUP         */7564/*********************************************/7565 7566#ifdef CONFIG_FB_SIS_3157567#if 07568static void7569SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)7570{7571   unsigned short temp, temp1, temp2;7572 7573   temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);7574   temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);7575   temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);7576   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);7577   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));7578   temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;7579   temp = (unsigned short)((int)(temp) + shift);7580   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));7581   temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);7582   temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);7583   temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);7584   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);7585   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));7586}7587#endif7588 7589static void7590SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)7591{7592   unsigned short temp, temp1;7593   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;7594 7595   if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;7596   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;7597 7598   if(SiS_Pr->ChipType >= XGI_20) return;7599 7600   if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {7601      if(!(ROMAddr[0x61] & 0x04)) return;7602   }7603 7604   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);7605   temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);7606   if(!(temp & 0x01)) {7607      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);7608      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);7609      if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {7610         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);7611      }7612      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);7613      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;7614      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;7615      else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;7616      else					   temp = 0x0402;7617      if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {7618         temp1 = 0;7619	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;7620	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);7621	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;7622	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));7623	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));7624	 if(ModeNo > 0x13) {7625            SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);7626         }7627      } else {7628         temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;7629	 if(temp1 == 0x01) temp |= 0x01;7630	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */7631	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));7632	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));7633	 if(ModeNo > 0x13) {7634            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);7635         }7636      }7637 7638#if 07639      if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */7640         if(SiS_Pr->SiS_TVMode & TVAspect43) {7641            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {7642	       if(resinfo == SIS_RI_1024x768) {7643	          SiS_ShiftXPos(SiS_Pr, 97);7644	       } else {7645	          SiS_ShiftXPos(SiS_Pr, 111);7646	       }7647	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {7648	       SiS_ShiftXPos(SiS_Pr, 136);7649	    }7650         }7651      }7652#endif7653 7654   }7655 7656}7657#endif7658 7659static void7660SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,7661                 unsigned short RefreshRateTableIndex)7662{7663  unsigned short vclkindex, temp, reg1, reg2;7664 7665  if(SiS_Pr->UseCustomMode) {7666     reg1 = SiS_Pr->CSR2B;7667     reg2 = SiS_Pr->CSR2C;7668  } else {7669     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);7670     reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;7671     reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;7672  }7673 7674  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {7675     if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {7676        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);7677 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);7678	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);7679     } else {7680        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);7681        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);7682     }7683  } else {7684     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);7685     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);7686     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);7687  }7688  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);7689  temp = 0x08;7690  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;7691  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);7692}7693 7694static void7695SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)7696{7697  if(SiS_Pr->ChipType >= SIS_315H) {7698     if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {7699	if((SiS_CRT2IsLCD(SiS_Pr)) ||7700	   (SiS_IsVAMode(SiS_Pr))) {7701	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {7702	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);7703	   } else {7704	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);7705	   }7706	}7707     }7708  }7709  if(SiS_Pr->SiS_VBType & VB_SISEMI) {7710     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);7711#ifdef SET_EMI7712     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);7713#endif7714     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);7715  }7716}7717 7718static void7719SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,7720		unsigned short RefreshRateTableIndex)7721{7722  unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;7723  unsigned int   tempebx, tempeax, templong;7724 7725  if(ModeNo <= 0x13) {7726     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;7727     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;7728  } else if(SiS_Pr->UseCustomMode) {7729     modeflag = SiS_Pr->CModeFlag;7730     resinfo = 0;7731  } else {7732     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;7733     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;7734  }7735 7736  if(SiS_Pr->ChipType >= SIS_315H) {7737     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {7738	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {7739	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);7740	}7741     }7742  }7743 7744  if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {7745     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {7746	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);7747     }7748  }7749 7750  if(SiS_Pr->ChipType >= SIS_315H) {7751     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {7752	SiS_SetDualLinkEtc(SiS_Pr);7753	return;7754     }7755  }7756 7757  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);7758 7759  tempbx = SiS_Pr->SiS_RVBHCMAX;7760  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);7761 7762  temp = (tempbx >> 1) & 0x80;7763 7764  tempcx = SiS_Pr->SiS_VGAHT - 1;7765  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);7766 7767  temp |= ((tempcx >> 5) & 0x78);7768 7769  tempcx = SiS_Pr->SiS_VGAVT - 1;7770  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;7771  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);7772 7773  temp |= ((tempcx >> 8) & 0x07);7774  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);7775 7776  tempbx = SiS_Pr->SiS_VGAHDE;7777  if(modeflag & HalfDCLK)    tempbx >>= 1;7778  if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;7779 7780  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {7781     temp = 0;7782     if(tempbx > 800)        temp = 0x60;7783  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {7784     temp = 0;7785     if(tempbx > 1024)       temp = 0xC0;7786     else if(tempbx >= 960)  temp = 0xA0;7787  } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {7788     temp = 0;7789     if(tempbx >= 1280)      temp = 0x40;7790     else if(tempbx >= 1024) temp = 0x20;7791  } else {7792     temp = 0x80;7793     if(tempbx >= 1024)      temp = 0xA0;7794  }7795 7796  temp |= SiS_Pr->Init_P4_0E;7797 7798  if(SiS_Pr->SiS_VBType & VB_SIS301) {7799     if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {7800        temp &= 0xf0;7801        temp |= 0x0A;7802     }7803  }7804 7805  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);7806 7807  tempeax = SiS_Pr->SiS_VGAVDE;7808  tempebx = SiS_Pr->SiS_VDE;7809  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {7810     if(!(temp & 0xE0)) tempebx >>=1;7811  }7812 7813  tempcx = SiS_Pr->SiS_RVBHRS;7814  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);7815  tempcx >>= 8;7816  tempcx |= 0x40;7817 7818  if(tempeax <= tempebx) {7819     tempcx ^= 0x40;7820  } else {7821     tempeax -= tempebx;7822  }7823 7824  tempeax *= (256 * 1024);7825  templong = tempeax % tempebx;7826  tempeax /= tempebx;7827  if(templong) tempeax++;7828 7829  temp = (unsigned short)(tempeax & 0x000000FF);7830  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);7831  temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);7832  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);7833  temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */7834  temp |= (tempcx & 0x4F);7835  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);7836 7837  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {7838 7839     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);7840 7841     /* Calc Linebuffer max address and set/clear decimode */7842     tempbx = 0;7843     if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;7844     tempax = SiS_Pr->SiS_VGAHDE;7845     if(modeflag & HalfDCLK)    tempax >>= 1;7846     if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;7847     if(tempax > 800) {7848        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {7849	   tempax -= 800;7850	} else {7851	   tempbx = 0x08;7852	   if(tempax == 960)	   tempax *= 25; /* Correct */7853           else if(tempax == 1024) tempax *= 25;7854           else			   tempax *= 20;7855	   temp = tempax % 32;7856	   tempax /= 32;7857	   if(temp) tempax++;7858	   tempax++;7859	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {7860	      if(resinfo == SIS_RI_1024x768 ||7861	         resinfo == SIS_RI_1024x576 ||7862		 resinfo == SIS_RI_1280x1024 ||7863		 resinfo == SIS_RI_1280x720) {7864	         /* Otherwise white line or garbage at right edge */7865	         tempax = (tempax & 0xff00) | 0x20;7866	      }7867	   }7868	}7869     }7870     tempax--;7871     temp = ((tempax >> 4) & 0x30) | tempbx;7872     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);7873     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);7874 7875     temp = 0x0036; tempbx = 0xD0;7876     if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {7877	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */7878     }7879     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {7880        if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {7881	   temp |= 0x01;7882	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {7883	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {7884  	         temp &= ~0x01;7885	      }7886	   }7887	}7888     }7889     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);7890 7891     tempbx = SiS_Pr->SiS_HT >> 1;7892     if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;7893     tempbx -= 2;7894     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);7895     temp = (tempbx >> 5) & 0x38;7896     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);7897 7898     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {7899	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {7900           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);7901	   /* LCD-too-dark-error-source, see FinalizeLCD() */7902	}7903     }7904 7905     SiS_SetDualLinkEtc(SiS_Pr);7906 7907  }  /* 301B */7908 7909  SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);7910}7911 7912/*********************************************/7913/*         SET PART 5 REGISTER GROUP         */7914/*********************************************/7915 7916static void7917SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)7918{7919 7920  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;7921 7922  if(SiS_Pr->SiS_ModeType == ModeVGA) {7923     if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {7924        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);7925        SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);7926     }7927  }7928}7929 7930/*********************************************/7931/*     MODIFY CRT1 GROUP FOR SLAVE MODE      */7932/*********************************************/7933 7934static bool7935SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,7936		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,7937		   unsigned short *DisplayType)7938 {7939  unsigned short modeflag = 0;7940  bool checkhd = true;7941 7942  /* Pass 1:1 not supported here */7943 7944  if(ModeNo <= 0x13) {7945     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;7946     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;7947  } else {7948     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;7949     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;7950  }7951 7952  (*ResIndex) &= 0x3F;7953 7954  if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {7955 7956     (*DisplayType) = 80;7957     if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {7958      	(*DisplayType) = 82;7959	if(SiS_Pr->SiS_ModeType > ModeVGA) {7960	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;7961	}7962     }7963     if((*DisplayType) != 84) {7964        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;7965     }7966 7967  } else {7968 7969     (*DisplayType = 0);7970     switch(SiS_Pr->SiS_LCDResInfo) {7971     case Panel_320x240_1: (*DisplayType) = 50;7972			   checkhd = false;7973			   break;7974     case Panel_320x240_2: (*DisplayType) = 14;7975			   break;7976     case Panel_320x240_3: (*DisplayType) = 18;7977			   break;7978     case Panel_640x480:   (*DisplayType) = 10;7979			   break;7980     case Panel_1024x600:  (*DisplayType) = 26;7981			   break;7982     default: return true;7983     }7984 7985     if(checkhd) {7986        if(modeflag & HalfDCLK) (*DisplayType)++;7987     }7988 7989     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {7990        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;7991     }7992 7993  }7994 7995  return true;7996}7997 7998static void7999SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,8000                unsigned short RefreshRateTableIndex)8001{8002  unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;8003  const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;8004  static const unsigned short CRIdx[] = {8005	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,8006	0x07, 0x10, 0x11, 0x15, 0x168007  };8008 8009  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||8010     (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||8011     (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||8012     (SiS_Pr->SiS_CustomT == CUT_PANEL856) )8013     return;8014 8015  if(SiS_Pr->SiS_IF_DEF_LVDS) {8016     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {8017        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;8018     }8019  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {8020     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;8021  } else return;8022 8023  if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;8024 8025  if(SiS_Pr->ChipType < SIS_315H) {8026     if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;8027  }8028 8029  if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,8030                          &ResIndex, &DisplayType))) {8031     return;8032  }8033 8034  switch(DisplayType) {8035    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */8036    case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */8037    case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */8038    case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */8039    case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */8040    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;8041    case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;8042#if 0 /* Works better with calculated numbers */8043    case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;8044    case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;8045    case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;8046    case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;8047#endif8048    case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;8049    case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;8050    case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;8051    case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;8052    case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;8053  }8054 8055  if(LVDSCRT1Ptr) {8056 8057     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);8058 8059     for(i = 0; i <= 10; i++) {8060        tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];8061        SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);8062     }8063 8064     for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {8065        tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];8066        SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);8067     }8068 8069     tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;8070     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);8071 8072     if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;8073     else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;8074 8075     tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;8076     if(modeflag & DoubleScanMode) tempah |= 0x80;8077     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);8078 8079  } else {8080 8081     SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);8082 8083  }8084}8085 8086/*********************************************/8087/*              SET CRT2 ECLK                */8088/*********************************************/8089 8090static void8091SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,8092           unsigned short RefreshRateTableIndex)8093{8094  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;8095  unsigned short clkbase, vclkindex = 0;8096  unsigned char  sr2b, sr2c;8097 8098  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {8099     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);8100     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {8101	RefreshRateTableIndex--;8102     }8103     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,8104                                    RefreshRateTableIndex);8105     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;8106  } else {8107     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,8108                                    RefreshRateTableIndex);8109  }8110 8111  sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;8112  sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;8113 8114  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {8115     if(SiS_Pr->SiS_UseROM) {8116	if(ROMAddr[0x220] & 0x01) {8117	   sr2b = ROMAddr[0x227];8118	   sr2c = ROMAddr[0x228];8119	}8120     }8121  }8122 8123  clkbase = 0x02B;8124  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {8125     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {8126	clkbase += 3;8127     }8128  }8129 8130  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);8131  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);8132  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);8133  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);8134  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);8135  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);8136  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);8137  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);8138  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);8139}8140 8141/*********************************************/8142/*           SET UP CHRONTEL CHIPS           */8143/*********************************************/8144 8145static void8146SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,8147               unsigned short RefreshRateTableIndex)8148{8149   unsigned short TVType, resindex;8150   const struct SiS_CHTVRegData *CHTVRegData = NULL;8151 8152   if(ModeNo <= 0x13)8153      resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;8154   else8155      resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;8156 8157   resindex &= 0x3F;8158 8159   TVType = 0;8160   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;8161   if(SiS_Pr->SiS_TVMode & TVSetPAL) {8162      TVType += 2;8163      if(SiS_Pr->SiS_ModeType > ModeVGA) {8164	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;8165      }8166      if(SiS_Pr->SiS_TVMode & TVSetPALM) {8167	 TVType = 4;8168	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;8169      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {8170	 TVType = 6;8171	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;8172      }8173   }8174 8175   switch(TVType) {8176      case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;8177      case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;8178      case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;8179      case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;8180      case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;8181      case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;8182      case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;8183      case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;8184      case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;8185      default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;8186   }8187 8188 8189   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {8190 8191#ifdef CONFIG_FB_SIS_3008192 8193      /* Chrontel 7005 - I assume that it does not come with a 315 series chip */8194 8195      /* We don't support modes >800x600 */8196      if (resindex > 5) return;8197 8198      if(SiS_Pr->SiS_TVMode & TVSetPAL) {8199	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/8200	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/8201      } else {8202	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/8203	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/8204      }8205 8206      SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */8207      SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */8208      SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */8209      SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */8210      SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */8211 8212      /* Set minimum flicker filter for Luma channel (SR1-0=00),8213                minimum text enhancement (S3-2=10),8214   	        maximum flicker filter for Chroma channel (S5-4=10)8215	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)8216       */8217      SiS_SetCH700x(SiS_Pr,0x01,0x28);8218 8219      /* Set video bandwidth8220            High bandwidth Luma composite video filter(S0=1)8221            low bandwidth Luma S-video filter (S2-1=00)8222	    disable peak filter in S-video channel (S3=0)8223	    high bandwidth Chroma Filter (S5-4=11)8224	    =00110001=0x318225      */8226      SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */8227 8228      /* Register 0x3D does not exist in non-macrovision register map8229            (Maybe this is a macrovision register?)8230       */8231#ifndef SIS_CP8232      SiS_SetCH70xx(SiS_Pr,0x3d,0x00);8233#endif8234 8235      /* Register 0x10 only contains 1 writable bit (S0) for sensing,8236             all other bits a read-only. Macrovision?8237       */8238      SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);8239 8240      /* Register 0x11 only contains 3 writable bits (S0-S2) for8241             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )8242       */8243      SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);8244 8245      /* Clear DSEN8246       */8247      SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);8248 8249      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */8250         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {8251            if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */8252      	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */8253               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */8254            } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */8255               SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */8256               SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);8257               SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);8258               SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);8259               SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);8260               SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);8261               SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);8262               SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);8263               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */8264               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */8265            }8266         } else {8267            if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */8268               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */8269               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);8270            } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */8271#if 08272               SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */8273               SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */8274               SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */8275               SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);8276               SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);8277               SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);8278               SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);8279               SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);8280               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */8281               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */8282#endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */8283	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */8284               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);8285            }8286         }8287      } else {						/* ---- PAL ---- */8288	/* We don't play around with FSCI in PAL mode */8289	SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);	/* loop filter off */8290	SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);	/* ACIV on */8291      }8292 8293#endif  /* 300 */8294 8295   } else {8296 8297      /* Chrontel 7019 - assumed that it does not come with a 300 series chip */8298 8299#ifdef CONFIG_FB_SIS_3158300 8301      unsigned short temp;8302 8303      /* We don't support modes >1024x768 */8304      if (resindex > 6) return;8305 8306      temp = CHTVRegData[resindex].Reg[0];8307      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;8308      SiS_SetCH701x(SiS_Pr,0x00,temp);8309 8310      SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);8311      SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);8312      SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);8313      SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);8314      SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);8315      SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);8316 8317      temp = CHTVRegData[resindex].Reg[7];8318      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;8319      SiS_SetCH701x(SiS_Pr,0x07,temp);8320 8321      SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);8322      SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);8323      SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);8324      SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);8325      SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);8326      SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);8327      SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);8328      SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);8329 8330      temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;8331      /* D1 should be set for PAL, PAL-N and NTSC-J,8332         but I won't do that for PAL unless somebody8333	 tells me to do so. Since the BIOS uses8334	 non-default CIV values and blacklevels,8335	 this might be compensated anyway.8336       */8337      if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;8338      SiS_SetCH701x(SiS_Pr,0x21,temp);8339 8340#endif	/* 315 */8341 8342   }8343 8344#ifdef SIS_CP8345   SIS_CP_INIT301_CP38346#endif8347 8348}8349 8350#ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */8351 8352void8353SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)8354{8355   unsigned short temp;8356 8357   /* Enable Chrontel 7019 LCD panel backlight */8358   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {8359      if(SiS_Pr->ChipType == SIS_740) {8360	 SiS_SetCH701x(SiS_Pr,0x66,0x65);8361      } else {8362	 temp = SiS_GetCH701x(SiS_Pr,0x66);8363	 temp |= 0x20;8364	 SiS_SetCH701x(SiS_Pr,0x66,temp);8365      }8366   }8367}8368 8369void8370SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)8371{8372   unsigned short temp;8373 8374   /* Disable Chrontel 7019 LCD panel backlight */8375   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {8376      temp = SiS_GetCH701x(SiS_Pr,0x66);8377      temp &= 0xDF;8378      SiS_SetCH701x(SiS_Pr,0x66,temp);8379   }8380}8381 8382static void8383SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)8384{8385  static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };8386  static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };8387  static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };8388  static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };8389  static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };8390  static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };8391  static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };8392  const unsigned char *tableptr = NULL;8393  int i;8394 8395  /* Set up Power up/down timing */8396 8397  if(SiS_Pr->ChipType == SIS_740) {8398     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {8399	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;8400	else    			          tableptr = table1024_740;8401     } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||8402	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||8403	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {8404	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;8405        else					  tableptr = table1400_740;8406     } else return;8407  } else {8408     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {8409	tableptr = table1024_650;8410     } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||8411	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||8412	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {8413	tableptr = table1400_650;8414     } else return;8415  }8416 8417  for(i=0; i<5; i++) {8418     SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);8419  }8420}8421 8422static void8423SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)8424{8425  const unsigned char *tableptr = NULL;8426  unsigned short tempbh;8427  int i;8428  static const unsigned char regtable[] = {8429		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,8430		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x668431  };8432  static const unsigned char table1024_740[] = {8433		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,8434		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x448435  };8436  static const unsigned char table1280_740[] = {8437		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,8438		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x448439  };8440  static const unsigned char table1400_740[] = {8441		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,8442		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x448443  };8444  static const unsigned char table1600_740[] = {8445		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,8446		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x448447  };8448  static const unsigned char table1024_650[] = {8449		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,8450		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x028451  };8452  static const unsigned char table1280_650[] = {8453		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,8454		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x028455  };8456  static const unsigned char table1400_650[] = {8457		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,8458		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x028459  };8460  static const unsigned char table1600_650[] = {8461		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,8462		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a8463  };8464 8465  if(SiS_Pr->ChipType == SIS_740) {8466     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;8467     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;8468     else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;8469     else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;8470     else return;8471  } else {8472     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;8473     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;8474     else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;8475     else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;8476     else return;8477  }8478 8479  tempbh = SiS_GetCH701x(SiS_Pr,0x74);8480  if((tempbh == 0xf6) || (tempbh == 0xc7)) {8481     tempbh = SiS_GetCH701x(SiS_Pr,0x73);8482     if(tempbh == 0xc8) {8483        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;8484     } else if(tempbh == 0xdb) {8485        if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;8486	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;8487     } else if(tempbh == 0xde) {8488        if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;8489     }8490  }8491 8492  if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;8493  else     			  tempbh = 0x0c;8494 8495  for(i = 0; i < tempbh; i++) {8496     SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);8497  }8498  SiS_ChrontelPowerSequencing(SiS_Pr);8499  tempbh = SiS_GetCH701x(SiS_Pr,0x1e);8500  tempbh |= 0xc0;8501  SiS_SetCH701x(SiS_Pr,0x1e,tempbh);8502 8503  if(SiS_Pr->ChipType == SIS_740) {8504     tempbh = SiS_GetCH701x(SiS_Pr,0x1c);8505     tempbh &= 0xfb;8506     SiS_SetCH701x(SiS_Pr,0x1c,tempbh);8507     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);8508     tempbh = SiS_GetCH701x(SiS_Pr,0x64);8509     tempbh |= 0x40;8510     SiS_SetCH701x(SiS_Pr,0x64,tempbh);8511     tempbh = SiS_GetCH701x(SiS_Pr,0x03);8512     tempbh &= 0x3f;8513     SiS_SetCH701x(SiS_Pr,0x03,tempbh);8514  }8515}8516 8517static void8518SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)8519{8520  unsigned char temp, temp1;8521 8522  temp1 = SiS_GetCH701x(SiS_Pr,0x49);8523  SiS_SetCH701x(SiS_Pr,0x49,0x3e);8524  temp = SiS_GetCH701x(SiS_Pr,0x47);8525  temp &= 0x7f;	/* Use external VSYNC */8526  SiS_SetCH701x(SiS_Pr,0x47,temp);8527  SiS_LongDelay(SiS_Pr, 3);8528  temp = SiS_GetCH701x(SiS_Pr,0x47);8529  temp |= 0x80;	/* Use internal VSYNC */8530  SiS_SetCH701x(SiS_Pr,0x47,temp);8531  SiS_SetCH701x(SiS_Pr,0x49,temp1);8532}8533 8534static void8535SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)8536{8537  unsigned short temp;8538 8539  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {8540     if(SiS_Pr->ChipType == SIS_740) {8541        temp = SiS_GetCH701x(SiS_Pr,0x1c);8542        temp |= 0x04;	/* Invert XCLK phase */8543        SiS_SetCH701x(SiS_Pr,0x1c,temp);8544     }8545     if(SiS_IsYPbPr(SiS_Pr)) {8546        temp = SiS_GetCH701x(SiS_Pr,0x01);8547	temp &= 0x3f;8548	temp |= 0x80;	/* Enable YPrPb (HDTV) */8549	SiS_SetCH701x(SiS_Pr,0x01,temp);8550     }8551     if(SiS_IsChScart(SiS_Pr)) {8552        temp = SiS_GetCH701x(SiS_Pr,0x01);8553	temp &= 0x3f;8554	temp |= 0xc0;	/* Enable SCART + CVBS */8555	SiS_SetCH701x(SiS_Pr,0x01,temp);8556     }8557     if(SiS_Pr->ChipType == SIS_740) {8558        SiS_ChrontelResetVSync(SiS_Pr);8559        SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */8560     } else {8561        SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */8562        temp = SiS_GetCH701x(SiS_Pr,0x49);8563        if(SiS_IsYPbPr(SiS_Pr)) {8564           temp = SiS_GetCH701x(SiS_Pr,0x73);8565	   temp |= 0x60;8566	   SiS_SetCH701x(SiS_Pr,0x73,temp);8567        }8568        temp = SiS_GetCH701x(SiS_Pr,0x47);8569        temp &= 0x7f;8570        SiS_SetCH701x(SiS_Pr,0x47,temp);8571        SiS_LongDelay(SiS_Pr, 2);8572        temp = SiS_GetCH701x(SiS_Pr,0x47);8573        temp |= 0x80;8574        SiS_SetCH701x(SiS_Pr,0x47,temp);8575     }8576  }8577}8578 8579static void8580SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)8581{8582  unsigned short temp;8583 8584  /* Complete power down of LVDS */8585  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {8586     if(SiS_Pr->ChipType == SIS_740) {8587        SiS_LongDelay(SiS_Pr, 1);8588	SiS_GenericDelay(SiS_Pr, 5887);8589	SiS_SetCH701x(SiS_Pr,0x76,0xac);8590	SiS_SetCH701x(SiS_Pr,0x66,0x00);8591     } else {8592        SiS_LongDelay(SiS_Pr, 2);8593	temp = SiS_GetCH701x(SiS_Pr,0x76);8594	temp &= 0xfc;8595	SiS_SetCH701x(SiS_Pr,0x76,temp);8596	SiS_SetCH701x(SiS_Pr,0x66,0x00);8597     }8598  }8599}8600 8601static void8602SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)8603{8604     unsigned short temp;8605 8606     if(SiS_Pr->ChipType == SIS_740) {8607 8608        temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */8609        temp &= 0x01;8610        if(!temp) {8611 8612           if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {8613	      temp = SiS_GetCH701x(SiS_Pr,0x49);8614	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);8615	   }8616 8617	   /* Reset Chrontel 7019 datapath */8618           SiS_SetCH701x(SiS_Pr,0x48,0x10);8619           SiS_LongDelay(SiS_Pr, 1);8620           SiS_SetCH701x(SiS_Pr,0x48,0x18);8621 8622	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {8623	      SiS_ChrontelResetVSync(SiS_Pr);8624	      SiS_SetCH701x(SiS_Pr,0x49,temp);8625	   }8626 8627        } else {8628 8629	   /* Clear/set/clear GPIO */8630           temp = SiS_GetCH701x(SiS_Pr,0x5c);8631	   temp &= 0xef;8632	   SiS_SetCH701x(SiS_Pr,0x5c,temp);8633	   temp = SiS_GetCH701x(SiS_Pr,0x5c);8634	   temp |= 0x10;8635	   SiS_SetCH701x(SiS_Pr,0x5c,temp);8636	   temp = SiS_GetCH701x(SiS_Pr,0x5c);8637	   temp &= 0xef;8638	   SiS_SetCH701x(SiS_Pr,0x5c,temp);8639	   temp = SiS_GetCH701x(SiS_Pr,0x61);8640	   if(!temp) {8641	      SiS_SetCH701xForLCD(SiS_Pr);8642	   }8643        }8644 8645     } else { /* 650 */8646        /* Reset Chrontel 7019 datapath */8647        SiS_SetCH701x(SiS_Pr,0x48,0x10);8648        SiS_LongDelay(SiS_Pr, 1);8649        SiS_SetCH701x(SiS_Pr,0x48,0x18);8650     }8651}8652 8653static void8654SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)8655{8656     unsigned short temp;8657 8658     if(SiS_Pr->ChipType == SIS_740) {8659 8660        if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {8661           SiS_ChrontelResetVSync(SiS_Pr);8662        }8663 8664     } else {8665 8666        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */8667        temp = SiS_GetCH701x(SiS_Pr,0x49);8668        temp &= 1;8669        if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */8670	   temp = SiS_GetCH701x(SiS_Pr,0x47);8671	   temp &= 0x70;8672	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */8673	   SiS_LongDelay(SiS_Pr, 3);8674	   temp = SiS_GetCH701x(SiS_Pr,0x47);8675	   temp |= 0x80;8676	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */8677        }8678 8679     }8680}8681 8682static void8683SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)8684{8685     unsigned short temp,temp1;8686 8687     if(SiS_Pr->ChipType == SIS_740) {8688 8689        temp = SiS_GetCH701x(SiS_Pr,0x61);8690        if(temp < 1) {8691           temp++;8692	   SiS_SetCH701x(SiS_Pr,0x61,temp);8693        }8694        SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */8695        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */8696        SiS_LongDelay(SiS_Pr, 1);8697        SiS_GenericDelay(SiS_Pr, 5887);8698 8699     } else {  /* 650 */8700 8701        temp1 = 0;8702        temp = SiS_GetCH701x(SiS_Pr,0x61);8703        if(temp < 2) {8704           temp++;8705	   SiS_SetCH701x(SiS_Pr,0x61,temp);8706	   temp1 = 1;8707        }8708        SiS_SetCH701x(SiS_Pr,0x76,0xac);8709        temp = SiS_GetCH701x(SiS_Pr,0x66);8710        temp |= 0x5f;8711        SiS_SetCH701x(SiS_Pr,0x66,temp);8712        if(ModeNo > 0x13) {8713           if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {8714	      SiS_GenericDelay(SiS_Pr, 1023);8715	   } else {8716	      SiS_GenericDelay(SiS_Pr, 767);8717	   }8718        } else {8719           if(!temp1)8720	      SiS_GenericDelay(SiS_Pr, 767);8721        }8722        temp = SiS_GetCH701x(SiS_Pr,0x76);8723        temp |= 0x03;8724        SiS_SetCH701x(SiS_Pr,0x76,temp);8725        temp = SiS_GetCH701x(SiS_Pr,0x66);8726        temp &= 0x7f;8727        SiS_SetCH701x(SiS_Pr,0x66,temp);8728        SiS_LongDelay(SiS_Pr, 1);8729 8730     }8731}8732 8733static void8734SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)8735{8736     unsigned short temp;8737 8738     SiS_LongDelay(SiS_Pr, 1);8739 8740     do {8741       temp = SiS_GetCH701x(SiS_Pr,0x66);8742       temp &= 0x04;  /* PLL stable? -> bail out */8743       if(temp == 0x04) break;8744 8745       if(SiS_Pr->ChipType == SIS_740) {8746          /* Power down LVDS output, PLL normal operation */8747          SiS_SetCH701x(SiS_Pr,0x76,0xac);8748       }8749 8750       SiS_SetCH701xForLCD(SiS_Pr);8751 8752       temp = SiS_GetCH701x(SiS_Pr,0x76);8753       temp &= 0xfb;  /* Reset PLL */8754       SiS_SetCH701x(SiS_Pr,0x76,temp);8755       SiS_LongDelay(SiS_Pr, 2);8756       temp = SiS_GetCH701x(SiS_Pr,0x76);8757       temp |= 0x04;  /* PLL normal operation */8758       SiS_SetCH701x(SiS_Pr,0x76,temp);8759       if(SiS_Pr->ChipType == SIS_740) {8760          SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */8761       } else {8762          SiS_SetCH701x(SiS_Pr,0x78,0x60);8763       }8764       SiS_LongDelay(SiS_Pr, 2);8765    } while(0);8766 8767    SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */8768}8769 8770static void8771SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)8772{8773     unsigned short temp;8774 8775     temp = SiS_GetCH701x(SiS_Pr,0x03);8776     temp |= 0x80;	/* Set datapath 1 to TV   */8777     temp &= 0xbf;	/* Set datapath 2 to LVDS */8778     SiS_SetCH701x(SiS_Pr,0x03,temp);8779 8780     if(SiS_Pr->ChipType == SIS_740) {8781 8782        temp = SiS_GetCH701x(SiS_Pr,0x1c);8783        temp &= 0xfb;	/* Normal XCLK phase */8784        SiS_SetCH701x(SiS_Pr,0x1c,temp);8785 8786        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);8787 8788        temp = SiS_GetCH701x(SiS_Pr,0x64);8789        temp |= 0x40;	/* ? Bit not defined */8790        SiS_SetCH701x(SiS_Pr,0x64,temp);8791 8792        temp = SiS_GetCH701x(SiS_Pr,0x03);8793        temp &= 0x3f;	/* D1 input to both LVDS and TV */8794        SiS_SetCH701x(SiS_Pr,0x03,temp);8795 8796	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {8797	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */8798	   SiS_LongDelay(SiS_Pr, 1);8799	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */8800	   SiS_ChrontelResetDB(SiS_Pr);8801	   SiS_ChrontelDoSomething2(SiS_Pr);8802	   SiS_ChrontelDoSomething3(SiS_Pr, 0);8803	} else {8804           temp = SiS_GetCH701x(SiS_Pr,0x66);8805           if(temp != 0x45) {8806              SiS_ChrontelResetDB(SiS_Pr);8807              SiS_ChrontelDoSomething2(SiS_Pr);8808              SiS_ChrontelDoSomething3(SiS_Pr, 0);8809           }8810	}8811 8812     } else { /* 650 */8813 8814        SiS_ChrontelResetDB(SiS_Pr);8815        SiS_ChrontelDoSomething2(SiS_Pr);8816        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);8817        SiS_ChrontelDoSomething3(SiS_Pr,temp);8818        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */8819 8820     }8821 8822}8823#endif  /* 315 series  */8824 8825/*********************************************/8826/*      MAIN: SET CRT2 REGISTER GROUP        */8827/*********************************************/8828 8829bool8830SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)8831{8832#ifdef CONFIG_FB_SIS_3008833   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;8834#endif8835   unsigned short ModeIdIndex, RefreshRateTableIndex;8836 8837   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;8838 8839   if(!SiS_Pr->UseCustomMode) {8840      SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);8841   } else {8842      ModeIdIndex = 0;8843   }8844 8845   /* Used for shifting CR33 */8846   SiS_Pr->SiS_SelectCRT2Rate = 4;8847 8848   SiS_UnLockCRT2(SiS_Pr);8849 8850   RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);8851 8852   SiS_SaveCRT2Info(SiS_Pr,ModeNo);8853 8854   if(SiS_Pr->SiS_SetFlag & LowModeTests) {8855      SiS_DisableBridge(SiS_Pr);8856      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {8857         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);8858      }8859      SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);8860   }8861 8862   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {8863      SiS_LockCRT2(SiS_Pr);8864      SiS_DisplayOn(SiS_Pr);8865      return true;8866   }8867 8868   SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8869 8870   /* Set up Panel Link for LVDS and LCDA */8871   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;8872   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||8873       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||8874       ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {8875      SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8876   }8877 8878   if(SiS_Pr->SiS_SetFlag & LowModeTests) {8879      SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8880   }8881 8882   if(SiS_Pr->SiS_VBType & VB_SISVB) {8883 8884      if(SiS_Pr->SiS_SetFlag & LowModeTests) {8885 8886	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8887#ifdef CONFIG_FB_SIS_3158888	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8889#endif8890	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);8891	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8892#ifdef CONFIG_FB_SIS_3158893	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);8894#endif8895	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);8896 8897	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);8898 8899	 /* For 301BDH (Panel link initialization): */8900	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {8901 8902	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {8903	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {8904		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8905	       }8906            }8907	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8908	 }8909      }8910 8911   } else {8912 8913      SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);8914 8915      SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);8916 8917      SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);8918 8919      if(SiS_Pr->SiS_SetFlag & LowModeTests) {8920	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {8921	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {8922	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {8923#ifdef CONFIG_FB_SIS_3158924		  SiS_SetCH701xForLCD(SiS_Pr);8925#endif8926	       }8927	    }8928	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {8929	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);8930	    }8931	 }8932      }8933 8934   }8935 8936#ifdef CONFIG_FB_SIS_3008937   if(SiS_Pr->ChipType < SIS_315H) {8938      if(SiS_Pr->SiS_SetFlag & LowModeTests) {8939	 if(SiS_Pr->SiS_UseOEM) {8940	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {8941	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {8942		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8943	       }8944	    } else {8945	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8946	    }8947	 }8948	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {8949	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||8950	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {8951	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);8952	    }8953	    SiS_DisplayOn(SiS_Pr);8954         }8955      }8956   }8957#endif8958 8959#ifdef CONFIG_FB_SIS_3158960   if(SiS_Pr->ChipType >= SIS_315H) {8961      if(SiS_Pr->SiS_SetFlag & LowModeTests) {8962	 if(SiS_Pr->ChipType < SIS_661) {8963	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);8964	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8965	 } else {8966	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);8967	 }8968	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);8969      }8970   }8971#endif8972 8973   if(SiS_Pr->SiS_SetFlag & LowModeTests) {8974      SiS_EnableBridge(SiS_Pr);8975   }8976 8977   SiS_DisplayOn(SiS_Pr);8978 8979   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {8980      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {8981	 /* Disable LCD panel when using TV */8982	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);8983      } else {8984	 /* Disable TV when using LCD */8985	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);8986      }8987   }8988 8989   if(SiS_Pr->SiS_SetFlag & LowModeTests) {8990      SiS_LockCRT2(SiS_Pr);8991   }8992 8993   return true;8994}8995 8996 8997/*********************************************/8998/*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */8999/*********************************************/9000 9001void9002SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)9003{9004  /* Switch on LCD backlight on SiS30xLV */9005  SiS_DDC2Delay(SiS_Pr,0xff00);9006  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {9007     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);9008     SiS_WaitVBRetrace(SiS_Pr);9009  }9010  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {9011     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);9012  }9013}9014 9015void9016SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)9017{9018  /* Switch off LCD backlight on SiS30xLV */9019  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);9020  SiS_DDC2Delay(SiS_Pr,0xff00);9021}9022 9023/*********************************************/9024/*          DDC RELATED FUNCTIONS            */9025/*********************************************/9026 9027static void9028SiS_SetupDDCN(struct SiS_Private *SiS_Pr)9029{9030  SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;9031  SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;9032  if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {9033     SiS_Pr->SiS_DDC_NData &= 0x0f;9034     SiS_Pr->SiS_DDC_NClk  &= 0x0f;9035  }9036}9037 9038#ifdef CONFIG_FB_SIS_3009039static unsigned char *9040SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)9041{9042  int i, j, num;9043  unsigned short tempah,temp;9044  unsigned char *mydataptr;9045 9046  for(i=0; i<20; i++) {				/* Do 20 attempts to write */9047     mydataptr = dataptr;9048     num = *mydataptr++;9049     if(!num) return mydataptr;9050     if(i) {9051        SiS_SetStop(SiS_Pr);9052	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);9053     }9054     if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */9055     tempah = SiS_Pr->SiS_DDC_DeviceAddr;9056     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */9057     if(temp) continue;				/*    (ERROR: no ack) */9058     tempah = *mydataptr++;9059     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */9060     if(temp) continue;				/*    (ERROR: no ack) */9061     for(j=0; j<num; j++) {9062        tempah = *mydataptr++;9063        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */9064	if(temp) break;9065     }9066     if(temp) continue;9067     if(SiS_SetStop(SiS_Pr)) continue;9068     return mydataptr;9069  }9070  return NULL;9071}9072 9073static bool9074SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)9075{9076  SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */9077  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */9078  SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */9079  SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */9080  SiS_SetupDDCN(SiS_Pr);9081 9082  SiS_SetSwitchDDC2(SiS_Pr);9083 9084  while(*dataptr) {9085     dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);9086     if(!dataptr) return false;9087  }9088  return true;9089}9090#endif9091 9092/* The Chrontel 700x is connected to the 630/730 via9093 * the 630/730's DDC/I2C port.9094 *9095 * On 630(S)T chipset, the index changed from 0x11 to9096 * 0x0a, possibly for working around the DDC problems9097 */9098 9099static bool9100SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)9101{9102  unsigned short temp, i;9103 9104  for(i=0; i<20; i++) {				/* Do 20 attempts to write */9105     if(i) {9106	SiS_SetStop(SiS_Pr);9107	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);9108     }9109     if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */9110     temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */9111     if(temp) continue;							/*    (ERROR: no ack) */9112     temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */9113     if(temp) continue;							/*    (ERROR: no ack) */9114     temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */9115     if(temp) continue;							/*    (ERROR: no ack) */9116     if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */9117     SiS_Pr->SiS_ChrontelInit = 1;9118     return true;9119  }9120  return false;9121}9122 9123/* Write to Chrontel 700x */9124void9125SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)9126{9127  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */9128 9129  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);9130 9131  if(!(SiS_Pr->SiS_ChrontelInit)) {9132     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */9133     SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */9134     SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */9135     SiS_SetupDDCN(SiS_Pr);9136  }9137 9138  if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&9139      (!(SiS_Pr->SiS_ChrontelInit)) ) {9140     SiS_Pr->SiS_DDC_Index = 0x0a;9141     SiS_Pr->SiS_DDC_Data  = 0x80;9142     SiS_Pr->SiS_DDC_Clk   = 0x40;9143     SiS_SetupDDCN(SiS_Pr);9144 9145     SiS_SetChReg(SiS_Pr, reg, val, 0x80);9146  }9147}9148 9149/* Write to Chrontel 701x */9150/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */9151void9152SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)9153{9154  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */9155  SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */9156  SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */9157  SiS_SetupDDCN(SiS_Pr);9158  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */9159  SiS_SetChReg(SiS_Pr, reg, val, 0);9160}9161 9162static9163void9164SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)9165{9166  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)9167     SiS_SetCH700x(SiS_Pr, reg, val);9168  else9169     SiS_SetCH701x(SiS_Pr, reg, val);9170}9171 9172static unsigned short9173SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)9174{9175  unsigned short tempah, temp, i;9176 9177  for(i=0; i<20; i++) {				/* Do 20 attempts to read */9178     if(i) {9179	SiS_SetStop(SiS_Pr);9180	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);9181     }9182     if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */9183     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */9184     if(temp) continue;							/*        (ERROR: no ack) */9185     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */9186     if(temp) continue;							/*        (ERROR: no ack) */9187     if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */9188     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */9189     if(temp) continue;							/*        (ERROR: no ack) */9190     tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */9191     if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */9192     SiS_Pr->SiS_ChrontelInit = 1;9193     return tempah;9194  }9195  return 0xFFFF;9196}9197 9198/* Read from Chrontel 700x */9199/* Parameter is [Register no (S7-S0)] */9200unsigned short9201SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)9202{9203  unsigned short result;9204 9205  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */9206 9207  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);9208 9209  if(!(SiS_Pr->SiS_ChrontelInit)) {9210     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */9211     SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */9212     SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */9213     SiS_SetupDDCN(SiS_Pr);9214  }9215 9216  SiS_Pr->SiS_DDC_ReadAddr = tempbx;9217 9218  if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&9219      (!SiS_Pr->SiS_ChrontelInit) ) {9220 9221     SiS_Pr->SiS_DDC_Index = 0x0a;9222     SiS_Pr->SiS_DDC_Data  = 0x80;9223     SiS_Pr->SiS_DDC_Clk   = 0x40;9224     SiS_SetupDDCN(SiS_Pr);9225 9226     result = SiS_GetChReg(SiS_Pr,0x80);9227  }9228  return result;9229}9230 9231/* Read from Chrontel 701x */9232/* Parameter is [Register no (S7-S0)] */9233unsigned short9234SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)9235{9236  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */9237  SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */9238  SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */9239  SiS_SetupDDCN(SiS_Pr);9240  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */9241 9242  SiS_Pr->SiS_DDC_ReadAddr = tempbx;9243 9244  return SiS_GetChReg(SiS_Pr,0);9245}9246 9247/* Read from Chrontel 70xx */9248/* Parameter is [Register no (S7-S0)] */9249static9250unsigned short9251SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)9252{9253  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)9254     return SiS_GetCH700x(SiS_Pr, tempbx);9255  else9256     return SiS_GetCH701x(SiS_Pr, tempbx);9257}9258 9259void9260SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,9261		unsigned char myor, unsigned short myand)9262{9263  unsigned short tempbl;9264 9265  tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;9266  SiS_SetCH70xx(SiS_Pr, reg, tempbl);9267}9268 9269/* Our own DDC functions */9270static9271unsigned short9272SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,9273                unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,9274		unsigned int VBFlags2)9275{9276     unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };9277     unsigned char flag, cr32;9278     unsigned short        temp = 0, myadaptnum = adaptnum;9279 9280     if(adaptnum != 0) {9281	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;9282	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;9283     }9284 9285     /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */9286 9287     SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */9288 9289     SiS_Pr->SiS_DDC_SecAddr = 0;9290     SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];9291     SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;9292     SiS_Pr->SiS_DDC_Index = 0x11;9293     flag = 0xff;9294 9295     cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);9296 9297#if 09298     if(VBFlags2 & VB2_SISBRIDGE) {9299	if(myadaptnum == 0) {9300	   if(!(cr32 & 0x20)) {9301	      myadaptnum = 2;9302	      if(!(cr32 & 0x10)) {9303	         myadaptnum = 1;9304		 if(!(cr32 & 0x08)) {9305		    myadaptnum = 0;9306		 }9307	      }9308	   }9309        }9310     }9311#endif9312 9313     if(VGAEngine == SIS_300_VGA) {		/* 300 series */9314 9315        if(myadaptnum != 0) {9316	   flag = 0;9317	   if(VBFlags2 & VB2_SISBRIDGE) {9318	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;9319              SiS_Pr->SiS_DDC_Index = 0x0f;9320	   }9321        }9322 9323	if(!(VBFlags2 & VB2_301)) {9324	   if((cr32 & 0x80) && (checkcr32)) {9325              if(myadaptnum >= 1) {9326	         if(!(cr32 & 0x08)) {9327		     myadaptnum = 1;9328		     if(!(cr32 & 0x10)) return 0xFFFF;9329                 }9330	      }9331	   }9332	}9333 9334	temp = 4 - (myadaptnum * 2);9335	if(flag) temp = 0;9336 9337     } else {						/* 315/330 series */9338 9339	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */9340 9341	if(VBFlags2 & VB2_SISBRIDGE) {9342	   if(myadaptnum == 2) {9343	      myadaptnum = 1;9344	   }9345	}9346 9347        if(myadaptnum == 1) {9348	   flag = 0;9349	   if(VBFlags2 & VB2_SISBRIDGE) {9350	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;9351              SiS_Pr->SiS_DDC_Index = 0x0f;9352	   }9353        }9354 9355        if((cr32 & 0x80) && (checkcr32)) {9356           if(myadaptnum >= 1) {9357	      if(!(cr32 & 0x08)) {9358	         myadaptnum = 1;9359		 if(!(cr32 & 0x10)) return 0xFFFF;9360	      }9361	   }9362        }9363 9364        temp = myadaptnum;9365        if(myadaptnum == 1) {9366           temp = 0;9367	   if(VBFlags2 & VB2_LVDS) flag = 0xff;9368        }9369 9370	if(flag) temp = 0;9371    }9372 9373    SiS_Pr->SiS_DDC_Data = 0x02 << temp;9374    SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;9375 9376    SiS_SetupDDCN(SiS_Pr);9377 9378    return 0;9379}9380 9381static unsigned short9382SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)9383{9384   if(SiS_SetStart(SiS_Pr)) return 0xFFFF;9385   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {9386      return 0xFFFF;9387   }9388   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {9389      return 0xFFFF;9390   }9391   return 0;9392}9393 9394static unsigned short9395SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)9396{9397   if(SiS_SetStart(SiS_Pr)) return 0xFFFF;9398   if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {9399      return 0xFFFF;9400   }9401   return 0;9402}9403 9404static unsigned short9405SiS_PrepareDDC(struct SiS_Private *SiS_Pr)9406{9407   if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);9408   if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));9409   return 0;9410}9411 9412static void9413SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)9414{9415   SiS_SetSCLKLow(SiS_Pr);9416   if(yesno) {9417      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9418		      SiS_Pr->SiS_DDC_Index,9419		      SiS_Pr->SiS_DDC_NData,9420		      SiS_Pr->SiS_DDC_Data);9421   } else {9422      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9423		      SiS_Pr->SiS_DDC_Index,9424		      SiS_Pr->SiS_DDC_NData,9425		      0);9426   }9427   SiS_SetSCLKHigh(SiS_Pr);9428}9429 9430static unsigned short9431SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)9432{9433    unsigned char mask, value;9434    unsigned short  temp, ret=0;9435    bool failed = false;9436 9437    SiS_SetSwitchDDC2(SiS_Pr);9438    if(SiS_PrepareDDC(SiS_Pr)) {9439         SiS_SetStop(SiS_Pr);9440         return 0xFFFF;9441    }9442    mask = 0xf0;9443    value = 0x20;9444    if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {9445       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);9446       SiS_SendACK(SiS_Pr, 0);9447       if(temp == 0) {9448           mask = 0xff;9449	   value = 0xff;9450       } else {9451           failed = true;9452	   ret = 0xFFFF;9453       }9454    }9455    if(!failed) {9456       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);9457       SiS_SendACK(SiS_Pr, 1);9458       temp &= mask;9459       if(temp == value) ret = 0;9460       else {9461          ret = 0xFFFF;9462          if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {9463             if(temp == 0x30) ret = 0;9464          }9465       }9466    }9467    SiS_SetStop(SiS_Pr);9468    return ret;9469}9470 9471static9472unsigned short9473SiS_ProbeDDC(struct SiS_Private *SiS_Pr)9474{9475   unsigned short flag;9476 9477   flag = 0x180;9478   SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;9479   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;9480   SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;9481   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;9482   SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;9483   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;9484   if(!(flag & 0x1a)) flag = 0;9485   return flag;9486}9487 9488static9489unsigned short9490SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)9491{9492   unsigned short flag, length, i;9493   unsigned char chksum,gotcha;9494 9495   if(DDCdatatype > 4) return 0xFFFF;9496 9497   flag = 0;9498   SiS_SetSwitchDDC2(SiS_Pr);9499   if(!(SiS_PrepareDDC(SiS_Pr))) {9500      length = 127;9501      if(DDCdatatype != 1) length = 255;9502      chksum = 0;9503      gotcha = 0;9504      for(i=0; i<length; i++) {9505	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);9506	 chksum += buffer[i];9507	 gotcha |= buffer[i];9508	 SiS_SendACK(SiS_Pr, 0);9509      }9510      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);9511      chksum += buffer[i];9512      SiS_SendACK(SiS_Pr, 1);9513      if(gotcha) flag = (unsigned short)chksum;9514      else flag = 0xFFFF;9515   } else {9516      flag = 0xFFFF;9517   }9518   SiS_SetStop(SiS_Pr);9519   return flag;9520}9521 9522/* Our private DDC functions9523 9524   It complies somewhat with the corresponding VESA function9525   in arguments and return values.9526 9527   Since this is probably called before the mode is changed,9528   we use our pre-detected pSiS-values instead of SiS_Pr as9529   regards chipset and video bridge type.9530 9531   Arguments:9532       adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)9533                 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.9534		 LCDA is CRT1, but DDC is read from CRT2 port.9535       DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)9536       buffer: ptr to 256 data bytes which will be filled with read data.9537 9538   Returns 0xFFFF if error, otherwise9539       if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)9540       if DDCdatatype = 0:  Returns supported DDC modes9541 9542 */9543unsigned short9544SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,9545              unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,9546	      unsigned int VBFlags2)9547{9548   unsigned char  sr1f, cr17=1;9549   unsigned short result;9550 9551   if(adaptnum > 2)9552      return 0xFFFF;9553 9554   if(DDCdatatype > 4)9555      return 0xFFFF;9556 9557   if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))9558      return 0xFFFF;9559 9560   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)9561      return 0xFFFF;9562 9563   sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);9564   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);9565   if(VGAEngine == SIS_300_VGA) {9566      cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;9567      if(!cr17) {9568         SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);9569         SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);9570         SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);9571      }9572   }9573   if((sr1f) || (!cr17)) {9574      SiS_WaitRetrace1(SiS_Pr);9575      SiS_WaitRetrace1(SiS_Pr);9576      SiS_WaitRetrace1(SiS_Pr);9577      SiS_WaitRetrace1(SiS_Pr);9578   }9579 9580   if(DDCdatatype == 0) {9581      result = SiS_ProbeDDC(SiS_Pr);9582   } else {9583      result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);9584      if((!result) && (DDCdatatype == 1)) {9585         if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&9586	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&9587	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&9588	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&9589	    (buffer[0x12] == 1)) {9590	    if(!SiS_Pr->DDCPortMixup) {9591	       if(adaptnum == 1) {9592	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;9593	       } else {9594	          if(buffer[0x14] & 0x80)    result = 0xFFFE;9595	       }9596	    }9597	 }9598      }9599   }9600   SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);9601   if(VGAEngine == SIS_300_VGA) {9602      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);9603   }9604   return result;9605}9606 9607/* Generic I2C functions for Chrontel & DDC --------- */9608 9609static void9610SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)9611{9612  SiS_SetSCLKHigh(SiS_Pr);9613  SiS_WaitRetrace1(SiS_Pr);9614 9615  SiS_SetSCLKLow(SiS_Pr);9616  SiS_WaitRetrace1(SiS_Pr);9617}9618 9619unsigned short9620SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)9621{9622   SiS_WaitRetrace1(SiS_Pr);9623   return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);9624}9625 9626/* Set I2C start condition */9627/* This is done by a SD high-to-low transition while SC is high */9628static unsigned short9629SiS_SetStart(struct SiS_Private *SiS_Pr)9630{9631  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */9632  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9633		  SiS_Pr->SiS_DDC_Index,9634		  SiS_Pr->SiS_DDC_NData,9635		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */9636  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */9637  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9638		  SiS_Pr->SiS_DDC_Index,9639		  SiS_Pr->SiS_DDC_NData,9640		  0x00);					/* SD->low = start condition */9641  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */9642  return 0;9643}9644 9645/* Set I2C stop condition */9646/* This is done by a SD low-to-high transition while SC is high */9647static unsigned short9648SiS_SetStop(struct SiS_Private *SiS_Pr)9649{9650  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */9651  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9652		  SiS_Pr->SiS_DDC_Index,9653		  SiS_Pr->SiS_DDC_NData,9654		  0x00);					/* SD->low   */9655  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */9656  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9657		  SiS_Pr->SiS_DDC_Index,9658		  SiS_Pr->SiS_DDC_NData,9659		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */9660  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */9661  return 0;9662}9663 9664/* Write 8 bits of data */9665static unsigned short9666SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)9667{9668  unsigned short i,flag,temp;9669 9670  flag = 0x80;9671  for(i = 0; i < 8; i++) {9672    SiS_SetSCLKLow(SiS_Pr);					/* SC->low */9673    if(tempax & flag) {9674      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9675		      SiS_Pr->SiS_DDC_Index,9676		      SiS_Pr->SiS_DDC_NData,9677		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */9678    } else {9679      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9680		      SiS_Pr->SiS_DDC_Index,9681		      SiS_Pr->SiS_DDC_NData,9682		      0x00);					/* Write bit (0) to SD */9683    }9684    SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */9685    flag >>= 1;9686  }9687  temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */9688  return temp;9689}9690 9691static unsigned short9692SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)9693{9694  unsigned short i, temp, getdata;9695 9696  getdata = 0;9697  for(i = 0; i < 8; i++) {9698    getdata <<= 1;9699    SiS_SetSCLKLow(SiS_Pr);9700    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9701		    SiS_Pr->SiS_DDC_Index,9702		    SiS_Pr->SiS_DDC_NData,9703		    SiS_Pr->SiS_DDC_Data);9704    SiS_SetSCLKHigh(SiS_Pr);9705    temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);9706    if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;9707  }9708  return getdata;9709}9710 9711static unsigned short9712SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)9713{9714  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9715		  SiS_Pr->SiS_DDC_Index,9716		  SiS_Pr->SiS_DDC_NClk,9717		  0x00);					/* SetSCLKLow()  */9718  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);9719  return 0;9720}9721 9722static unsigned short9723SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)9724{9725  unsigned short temp, watchdog=1000;9726 9727  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9728		  SiS_Pr->SiS_DDC_Index,9729		  SiS_Pr->SiS_DDC_NClk,9730		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */9731  do {9732    temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);9733  } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);9734  if (!watchdog) {9735  	return 0xFFFF;9736  }9737  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);9738  return 0;9739}9740 9741/* Check I2C acknowledge */9742/* Returns 0 if ack ok, non-0 if ack not ok */9743static unsigned short9744SiS_CheckACK(struct SiS_Private *SiS_Pr)9745{9746  unsigned short tempah;9747 9748  SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */9749  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,9750		  SiS_Pr->SiS_DDC_Index,9751		  SiS_Pr->SiS_DDC_NData,9752		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */9753  SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */9754  tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */9755  SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */9756  if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */9757  return 0;9758}9759 9760/* End of I2C functions ----------------------- */9761 9762 9763/* =============== SiS 315/330 O.E.M. ================= */9764 9765#ifdef CONFIG_FB_SIS_3159766 9767static unsigned short9768GetRAMDACromptr(struct SiS_Private *SiS_Pr)9769{9770  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;9771  unsigned short romptr;9772 9773  if(SiS_Pr->ChipType < SIS_330) {9774     romptr = SISGETROMW(0x128);9775     if(SiS_Pr->SiS_VBType & VB_SIS30xB)9776        romptr = SISGETROMW(0x12a);9777  } else {9778     romptr = SISGETROMW(0x1a8);9779     if(SiS_Pr->SiS_VBType & VB_SIS30xB)9780        romptr = SISGETROMW(0x1aa);9781  }9782  return romptr;9783}9784 9785static unsigned short9786GetLCDromptr(struct SiS_Private *SiS_Pr)9787{9788  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;9789  unsigned short romptr;9790 9791  if(SiS_Pr->ChipType < SIS_330) {9792     romptr = SISGETROMW(0x120);9793     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)9794        romptr = SISGETROMW(0x122);9795  } else {9796     romptr = SISGETROMW(0x1a0);9797     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)9798        romptr = SISGETROMW(0x1a2);9799  }9800  return romptr;9801}9802 9803static unsigned short9804GetTVromptr(struct SiS_Private *SiS_Pr)9805{9806  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;9807  unsigned short romptr;9808 9809  if(SiS_Pr->ChipType < SIS_330) {9810     romptr = SISGETROMW(0x114);9811     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)9812        romptr = SISGETROMW(0x11a);9813  } else {9814     romptr = SISGETROMW(0x194);9815     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)9816        romptr = SISGETROMW(0x19a);9817  }9818  return romptr;9819}9820 9821static unsigned short9822GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)9823{9824  unsigned short index;9825 9826  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {9827     if(!(SiS_IsNotM650orLater(SiS_Pr))) {9828        if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {9829	   index >>= 4;9830	   index *= 3;9831	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;9832           else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;9833           return index;9834	}9835     }9836  }9837 9838  index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;9839  if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;9840  if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */9841     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;9842     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;9843  } else {9844     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;9845  }9846  index--;9847  index *= 3;9848  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;9849  else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;9850  return index;9851}9852 9853static unsigned short9854GetLCDPtrIndex(struct SiS_Private *SiS_Pr)9855{9856  unsigned short index;9857 9858  index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;9859  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;9860  else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;9861  return index;9862}9863 9864static unsigned short9865GetTVPtrIndex(struct SiS_Private *SiS_Pr)9866{9867  unsigned short index;9868 9869  index = 0;9870  if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;9871  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;9872 9873  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;9874 9875  index <<= 1;9876 9877  if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&9878     (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {9879     index++;9880  }9881 9882  return index;9883}9884 9885static unsigned int9886GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)9887{9888   unsigned short index = 0, temp = 0;9889 9890   if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;9891   if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;9892   if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;9893   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;9894   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {9895      index = 4;9896      if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;9897      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;9898   }9899 9900   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {9901      if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||9902         (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {9903	 index += addme;9904	 temp++;9905      }9906      temp += 0x0100;9907   }9908   return (unsigned int)(index | (temp << 16));9909}9910 9911static unsigned int9912GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)9913{9914   return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));9915}9916 9917#if 09918static unsigned int9919GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)9920{9921   return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));9922}9923#endif9924 9925static int9926GetOEMTVPtr661(struct SiS_Private *SiS_Pr)9927{9928   int index = 0;9929 9930   if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;9931   if(SiS_Pr->SiS_ROMNew) {9932      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;9933      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;9934      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;9935      if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;9936   } else {9937      if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;9938      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;9939      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;9940      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;9941   }9942 9943   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;9944 9945   return index;9946}9947 9948static void9949SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)9950{9951  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;9952  unsigned short delay=0,index,myindex,temp,romptr=0;9953  bool dochiptest = true;9954 9955  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {9956     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);9957  } else {9958     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);9959  }9960 9961  /* Find delay (from ROM, internal tables, PCI subsystem) */9962 9963  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */9964 9965     if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {9966        romptr = GetRAMDACromptr(SiS_Pr);9967     }9968     if(romptr) delay = ROMAddr[romptr];9969     else {9970        delay = 0x04;9971        if(SiS_Pr->SiS_VBType & VB_SIS30xB) {9972	   if(IS_SIS650) {9973	      delay = 0x0a;9974	   } else if(IS_SIS740) {9975	      delay = 0x00;9976	   } else {9977	      delay = 0x0c;9978	   }9979	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {9980           delay = 0x00;9981	}9982     }9983 9984  } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */9985 9986     bool gotitfrompci = false;9987 9988     /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */9989 9990     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {9991	if(SiS_Pr->PDC != -1) {9992           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));9993	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));9994	   return;9995	}9996     } else {9997	if(SiS_Pr->PDCA != -1) {9998	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));9999	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));10000	   return;10001	}10002     }10003 10004     /* Custom Panel? */10005 10006     if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {10007        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {10008	   delay = 0x00;10009	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {10010	      delay = 0x20;10011	   }10012	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);10013	} else {10014	   delay = 0x0c;10015	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {10016	      delay = 0x03;10017	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {10018	         delay = 0x00;10019	      }10020	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {10021	      if(IS_SIS740) delay = 0x01;10022	      else          delay = 0x03;10023	   }10024	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);10025	}10026        return;10027     }10028 10029     /* This is a piece of typical SiS crap: They code the OEM LCD10030      * delay into the code, at no defined place in the BIOS.10031      * We now have to start doing a PCI subsystem check here.10032      */10033 10034     switch(SiS_Pr->SiS_CustomT) {10035     case CUT_COMPAQ1280:10036     case CUT_COMPAQ12802:10037	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {10038	   gotitfrompci = true;10039	   dochiptest = false;10040	   delay = 0x03;10041	}10042	break;10043     case CUT_CLEVO1400:10044     case CUT_CLEVO14002:10045	gotitfrompci = true;10046	dochiptest = false;10047	delay = 0x02;10048	break;10049     case CUT_CLEVO1024:10050     case CUT_CLEVO10242:10051        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {10052	   gotitfrompci = true;10053	   dochiptest = false;10054	   delay = 0x33;10055	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);10056	   delay &= 0x0f;10057	}10058	break;10059     }10060 10061     /* Could we find it through the PCI ID? If no, use ROM or table */10062 10063     if(!gotitfrompci) {10064 10065        index = GetLCDPtrIndexBIOS(SiS_Pr);10066        myindex = GetLCDPtrIndex(SiS_Pr);10067 10068        if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {10069 10070           if(SiS_IsNotM650orLater(SiS_Pr)) {10071 10072              if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {10073	         /* Always use the second pointer on 650; some BIOSes */10074                 /* still carry old 301 data at the first location    */10075	         /* romptr = SISGETROMW(0x120);                       */10076	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */10077	         romptr = SISGETROMW(0x122);10078	         if(!romptr) return;10079	         delay = ROMAddr[(romptr + index)];10080	      } else {10081                 delay = SiS310_LCDDelayCompensation_650301LV[myindex];10082	      }10083 10084          } else {10085 10086             delay = SiS310_LCDDelayCompensation_651301LV[myindex];10087	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))10088	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];10089 10090          }10091 10092        } else if(SiS_Pr->SiS_UseROM 			      &&10093		  (!(SiS_Pr->SiS_ROMNew))		      &&10094	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&10095		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&10096		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&10097		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&10098		  ((romptr = GetLCDromptr(SiS_Pr)))) {10099 10100	   /* Data for 1280x1024 wrong in 301B BIOS */10101	   /* Data for 1600x1200 wrong in 301C BIOS */10102	   delay = ROMAddr[(romptr + index)];10103 10104        } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {10105 10106	   if(IS_SIS740) delay = 0x03;10107	   else          delay = 0x00;10108 10109	} else {10110 10111           delay = SiS310_LCDDelayCompensation_301[myindex];10112	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {10113	      if(IS_SIS740) delay = 0x01;10114	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];10115	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];10116	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {10117	      if(IS_SIS740) delay = 0x01;  /* ? */10118	      else          delay = 0x03;10119	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */10120	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {10121	      if(IS_SIS740) delay = 0x01;10122	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];10123	   }10124 10125        }10126 10127     }  /* got it from PCI */10128 10129     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {10130	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));10131	dochiptest = false;10132     }10133 10134  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */10135 10136     index = GetTVPtrIndex(SiS_Pr);10137 10138     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {10139 10140        if(SiS_IsNotM650orLater(SiS_Pr)) {10141 10142           if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {10143	      /* Always use the second pointer on 650; some BIOSes */10144              /* still carry old 301 data at the first location    */10145              /* romptr = SISGETROMW(0x114);			   */10146	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */10147	      romptr = SISGETROMW(0x11a);10148	      if(!romptr) return;10149	      delay = ROMAddr[romptr + index];10150 10151	   } else {10152 10153	      delay = SiS310_TVDelayCompensation_301B[index];10154 10155	   }10156 10157        } else {10158 10159           switch(SiS_Pr->SiS_CustomT) {10160	   case CUT_COMPAQ1280:10161	   case CUT_COMPAQ12802:10162	   case CUT_CLEVO1400:10163	   case CUT_CLEVO14002:10164	      delay = 0x02;10165	      dochiptest = false;10166	      break;10167	   case CUT_CLEVO1024:10168	   case CUT_CLEVO10242:10169	      delay = 0x03;10170	      dochiptest = false;10171   	      break;10172	   default:10173              delay = SiS310_TVDelayCompensation_651301LV[index];10174	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {10175	         delay = SiS310_TVDelayCompensation_651302LV[index];10176	      }10177	   }10178        }10179 10180     } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {10181 10182        romptr = GetTVromptr(SiS_Pr);10183	if(!romptr) return;10184	delay = ROMAddr[romptr + index];10185 10186     } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {10187 10188        delay = SiS310_TVDelayCompensation_LVDS[index];10189 10190     } else {10191 10192	delay = SiS310_TVDelayCompensation_301[index];10193        if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {10194	   if(IS_SIS740) {10195	      delay = SiS310_TVDelayCompensation_740301B[index];10196	      /* LV: use 301 data? BIOS bug? */10197	   } else {10198              delay = SiS310_TVDelayCompensation_301B[index];10199	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;10200	   }10201	}10202 10203     }10204 10205     if(SiS_LCDAEnabled(SiS_Pr)) {10206	delay &= 0x0f;10207	dochiptest = false;10208     }10209 10210  } else return;10211 10212  /* Write delay */10213 10214  if(SiS_Pr->SiS_VBType & VB_SISVB) {10215 10216     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {10217 10218        temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;10219        if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */10220	   delay &= 0x0f;10221	   delay |= 0xb0;10222        } else if(temp == 6) {10223           delay &= 0x0f;10224	   delay |= 0xc0;10225        } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */10226	   delay = 0x35;10227        }10228        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);10229 10230     } else {10231 10232        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);10233 10234     }10235 10236  } else {  /* LVDS */10237 10238     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {10239        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);10240     } else {10241        if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {10242           delay <<= 4;10243           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);10244        } else {10245           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);10246        }10247     }10248 10249  }10250 10251}10252 10253static void10254SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)10255{10256  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;10257  unsigned short index,temp,temp1,romptr=0;10258 10259  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;10260 10261  if(ModeNo<=0x13)10262     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;10263  else10264     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;10265 10266  temp = GetTVPtrIndex(SiS_Pr);10267  temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */10268  temp1 = temp;10269 10270  if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {10271     if(SiS_Pr->ChipType >= SIS_661) {10272        temp1 = GetOEMTVPtr661(SiS_Pr);10273        temp1 >>= 1;10274        romptr = SISGETROMW(0x260);10275        if(SiS_Pr->ChipType >= SIS_760) {10276	   romptr = SISGETROMW(0x360);10277	}10278     } else if(SiS_Pr->ChipType >= SIS_330) {10279        romptr = SISGETROMW(0x192);10280     } else {10281        romptr = SISGETROMW(0x112);10282     }10283  }10284 10285  if(romptr) {10286     temp1 <<= 1;10287     temp = ROMAddr[romptr + temp1 + index];10288  } else {10289     temp = SiS310_TVAntiFlick1[temp][index];10290  }10291  temp <<= 4;10292 10293  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */10294}10295 10296static void10297SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)10298{10299  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;10300  unsigned short index,temp,temp1,romptr=0;10301 10302  temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */10303 10304  if(ModeNo <= 0x13)10305     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;10306  else10307     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;10308 10309  if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {10310     if(SiS_Pr->ChipType >= SIS_661) {10311        romptr = SISGETROMW(0x26c);10312        if(SiS_Pr->ChipType >= SIS_760) {10313	   romptr = SISGETROMW(0x36c);10314	}10315	temp1 = GetOEMTVPtr661(SiS_Pr);10316        temp1 >>= 1;10317     } else if(SiS_Pr->ChipType >= SIS_330) {10318        romptr = SISGETROMW(0x1a4);10319     } else {10320        romptr = SISGETROMW(0x124);10321     }10322  }10323 10324  if(romptr) {10325     temp1 <<= 1;10326     temp = ROMAddr[romptr + temp1 + index];10327  } else {10328     temp = SiS310_TVEdge1[temp][index];10329  }10330  temp <<= 5;10331  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */10332}10333 10334static void10335SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)10336{10337  unsigned short index, temp, i, j;10338 10339  if(ModeNo <= 0x13) {10340     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;10341  } else {10342     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;10343  }10344 10345  temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */10346 10347  if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */10348  else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */10349  else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */10350  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */10351 10352  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {10353     for(i=0x35, j=0; i<=0x38; i++, j++) {10354        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);10355     }10356     for(i=0x48; i<=0x4A; i++, j++) {10357        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);10358     }10359  } else {10360     for(i=0x35, j=0; i<=0x38; i++, j++) {10361        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);10362     }10363  }10364}10365 10366static void10367SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)10368{10369  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;10370  unsigned short index,temp,i,j,resinfo,romptr=0;10371  unsigned int  lindex;10372 10373  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;10374 10375  /* NTSC-J data not in BIOS, and already set in SetGroup2 */10376  if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;10377 10378  if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {10379     lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;10380     lindex <<= 2;10381     for(j=0, i=0x31; i<=0x34; i++, j++) {10382        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);10383     }10384     return;10385  }10386 10387  /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */10388  if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;10389 10390  if(ModeNo<=0x13) {10391     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;10392  } else {10393     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;10394  }10395 10396  temp = GetTVPtrIndex(SiS_Pr);10397  /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,10398   * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text10399   */10400  if(SiS_Pr->SiS_UseROM) {10401     romptr = SISGETROMW(0x116);10402     if(SiS_Pr->ChipType >= SIS_330) {10403        romptr = SISGETROMW(0x196);10404     }10405     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {10406        romptr = SISGETROMW(0x11c);10407	if(SiS_Pr->ChipType >= SIS_330) {10408	   romptr = SISGETROMW(0x19c);10409	}10410	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {10411	   romptr = SISGETROMW(0x116);10412	   if(SiS_Pr->ChipType >= SIS_330) {10413              romptr = SISGETROMW(0x196);10414           }10415	}10416     }10417  }10418  if(romptr) {10419     romptr += (temp << 2);10420     for(j=0, i=0x31; i<=0x34; i++, j++) {10421        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);10422     }10423  } else {10424     index = temp % 2;10425     temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */10426     for(j=0, i=0x31; i<=0x34; i++, j++) {10427        if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))10428	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);10429        else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))10430           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);10431        else10432           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);10433     }10434  }10435 10436  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {10437     if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {10438        if((resinfo == SIS_RI_640x480) ||10439	   (resinfo == SIS_RI_800x600)) {10440	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);10441	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);10442	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);10443	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);10444	} else if(resinfo == SIS_RI_1024x768) {10445	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);10446	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);10447	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);10448	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);10449	}10450     }10451  }10452}10453 10454static void10455SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,10456                unsigned short ModeIdIndex, unsigned short RTI)10457{10458   unsigned short delay = 0, romptr = 0, index, lcdpdcindex;10459   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;10460 10461   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))10462      return;10463 10464   /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */10465   /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */10466 10467   if(SiS_Pr->SiS_ROMNew) {10468      if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||10469         ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&10470	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {10471         index = 25;10472         if(SiS_Pr->UseCustomMode) {10473	    index = SiS_Pr->CSRClock;10474         } else if(ModeNo > 0x13) {10475            index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);10476            index = SiS_Pr->SiS_VCLKData[index].CLOCK;10477         }10478	 if(index < 25) index = 25;10479         index = ((index / 25) - 1) << 1;10480         if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {10481	    index++;10482	 }10483	 romptr = SISGETROMW(0x104);10484         delay = ROMAddr[romptr + index];10485         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {10486            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));10487            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));10488         } else {10489            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));10490	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));10491         }10492         return;10493      }10494   }10495 10496   /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */10497 10498   if(SiS_Pr->UseCustomMode) delay = 0x04;10499   else if(ModeNo <= 0x13)   delay = 0x04;10500   else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);10501   delay |= (delay << 8);10502 10503   if(SiS_Pr->ChipType >= XGI_20) {10504 10505      delay = 0x0606;10506      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {10507 10508	 delay = 0x0404;10509         if(SiS_Pr->SiS_XGIROM) {10510	     index = GetTVPtrIndex(SiS_Pr);10511	     if((romptr = SISGETROMW(0x35e))) {10512	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;10513		delay |= (delay << 8);10514	     }10515	 }10516 10517	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {10518	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {10519	       delay -= 0x0404;10520	    }10521	 }10522      }10523 10524   } else if(SiS_Pr->ChipType >= SIS_340) {10525 10526      delay = 0x0606;10527      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {10528         delay = 0x0404;10529      }10530      /* TODO (eventually) */10531 10532   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {10533 10534      /* 3. TV */10535 10536      index = GetOEMTVPtr661(SiS_Pr);10537      if(SiS_Pr->SiS_ROMNew) {10538         romptr = SISGETROMW(0x106);10539	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;10540         delay = ROMAddr[romptr + index];10541      } else {10542         delay = 0x04;10543	 if(index > 3) delay = 0;10544      }10545 10546   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {10547 10548      /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */10549 10550      if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&10551          ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {10552 10553	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;10554 10555	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */10556	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */10557	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */10558 10559      } else {10560 10561         /* TMDS: Set our own, since BIOS has no idea */10562	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */10563         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {10564	    switch(SiS_Pr->SiS_LCDResInfo) {10565	    case Panel_1024x768:  delay = 0x0008; break;10566	    case Panel_1280x720:  delay = 0x0004; break;10567	    case Panel_1280x768:10568	    case Panel_1280x768_2:delay = 0x0004; break;10569	    case Panel_1280x800:10570	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */10571	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */10572	    case Panel_1280x1024: delay = 0x1e04; break;10573	    case Panel_1400x1050: delay = 0x0004; break;10574	    case Panel_1600x1200: delay = 0x0400; break;10575	    case Panel_1680x1050: delay = 0x0e04; break;10576	    default:10577               if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {10578	          delay = 0x0008;10579	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {10580	          delay = 0x1e04;10581               } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {10582	          delay = 0x0004;10583	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {10584	          delay = 0x0400;10585               } else10586	          delay = 0x0e04;10587	       break;10588	    }10589         }10590 10591	 /* Override by detected or user-set values */10592	 /* (but only if, for some reason, we can't read value from BIOS) */10593         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {10594            delay = SiS_Pr->PDC & 0x1f;10595         }10596         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {10597            delay = (SiS_Pr->PDCA & 0x1f) << 8;10598         }10599 10600      }10601 10602   }10603 10604   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {10605      delay >>= 8;10606      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));10607      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));10608   } else {10609      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));10610      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));10611   }10612}10613 10614static void10615SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)10616{10617   unsigned short infoflag;10618   unsigned char  temp;10619 10620   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {10621 10622      if(ModeNo <= 0x13) {10623         infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);10624      } else if(SiS_Pr->UseCustomMode) {10625         infoflag = SiS_Pr->CInfoFlag;10626      } else {10627         infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;10628      }10629 10630      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {10631         infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */10632      }10633 10634      infoflag &= 0xc0;10635 10636      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {10637         temp = (infoflag >> 6) | 0x0c;10638         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {10639	    temp ^= 0x04;10640	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;10641	 }10642         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);10643      } else {10644         temp = 0x30;10645         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;10646         temp |= infoflag;10647         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);10648         temp = 0;10649         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {10650	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;10651	 }10652         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);10653      }10654 10655   }10656}10657 10658static void10659SetPanelParms661(struct SiS_Private *SiS_Pr)10660{10661   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;10662   unsigned short romptr, temp1, temp2;10663 10664   if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {10665      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);10666   }10667 10668   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {10669      if(SiS_Pr->LVDSHL != -1) {10670         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);10671      }10672   }10673 10674   if(SiS_Pr->SiS_ROMNew) {10675 10676      if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {10677         if(SiS_Pr->SiS_VBType & VB_SISLVDS) {10678            temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;10679	    temp2 = 0xfc;10680	    if(SiS_Pr->LVDSHL != -1) {10681	      temp1 &= 0xfc;10682	      temp2 = 0xf3;10683	    }10684	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);10685         }10686	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {10687            temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;10688            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);10689	 }10690      }10691 10692   }10693}10694 10695static void10696SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)10697{10698   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {10699      SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);10700      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {10701         SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);10702         SetPanelParms661(SiS_Pr);10703      }10704   } else {10705      SetDelayComp(SiS_Pr,ModeNo);10706   }10707 10708   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {10709      SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);10710      SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);10711      SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);10712      if(SiS_Pr->SiS_VBType & VB_SIS301) {10713         SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);10714      }10715   }10716}10717 10718static void10719SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,10720			unsigned short ModeIdIndex, unsigned short RRTI)10721{10722   if(SiS_Pr->SiS_VBType & VB_SISVB) {10723 10724      SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);10725 10726      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {10727         SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);10728         SetPanelParms661(SiS_Pr);10729      }10730 10731      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {10732         SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);10733         SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);10734         SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);10735         if(SiS_Pr->SiS_VBType & VB_SIS301) {10736            SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);10737         }10738      }10739   }10740}10741 10742/* FinalizeLCD10743 * This finalizes some CRT2 registers for the very panel used.10744 * If we have a backup if these registers, we use it; otherwise10745 * we set the register according to most BIOSes. However, this10746 * function looks quite different in every BIOS, so you better10747 * pray that we have a backup...10748 */10749static void10750SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)10751{10752  unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;10753  unsigned short resinfo,modeflag;10754 10755  if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;10756  if(SiS_Pr->SiS_ROMNew) return;10757 10758  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {10759     if(SiS_Pr->LVDSHL != -1) {10760        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);10761     }10762  }10763 10764  if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;10765  if(SiS_Pr->UseCustomMode) return;10766 10767  switch(SiS_Pr->SiS_CustomT) {10768  case CUT_COMPAQ1280:10769  case CUT_COMPAQ12802:10770  case CUT_CLEVO1400:10771  case CUT_CLEVO14002:10772     return;10773  }10774 10775  if(ModeNo <= 0x13) {10776     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;10777     modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;10778  } else {10779     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;10780     modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;10781  }10782 10783  if(IS_SIS650) {10784     if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {10785        if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {10786	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);10787	} else {10788           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);10789	}10790     }10791  }10792 10793  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {10794     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {10795        /* Maybe all panels? */10796        if(SiS_Pr->LVDSHL == -1) {10797           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);10798	}10799	return;10800     }10801  }10802 10803  if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {10804     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {10805        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {10806	   if(SiS_Pr->LVDSHL == -1) {10807	      /* Maybe all panels? */10808              SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);10809	   }10810	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {10811	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;10812	      if(tempch == 3) {10813	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);10814	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);10815	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);10816	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);10817	      }10818	   }10819	   return;10820	}10821     }10822  }10823 10824  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {10825     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {10826	if(SiS_Pr->SiS_VBType & VB_SISEMI) {10827	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);10828#ifdef SET_EMI10829	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);10830#endif10831	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);10832	}10833     } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {10834        if(SiS_Pr->LVDSHL == -1) {10835           /* Maybe ACER only? */10836           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);10837	}10838     }10839     tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;10840     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {10841	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {10842	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);10843	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {10844	   if(tempch == 0x03) {10845	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);10846	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);10847	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);10848	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);10849	   }10850	   if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {10851	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);10852	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);10853	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);10854	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);10855	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);10856	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);10857	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);10858	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);10859	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);10860	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);10861	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */10862	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);10863	      if(ModeNo <= 0x13) {10864	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);10865		 if((resinfo == 0) || (resinfo == 2)) return;10866		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);10867		 if((resinfo == 1) || (resinfo == 3)) return;10868	      }10869	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);10870	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {10871	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */10872#if 010873	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */10874		 tempbx--;10875		 temp = tempbx & 0xff;10876		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);10877		 temp = (tempbx >> 8) & 0x03;10878		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);10879#endif10880	      }10881	   } else if(ModeNo <= 0x13) {10882	      if(ModeNo <= 1) {10883		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);10884		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);10885		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);10886		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);10887	      }10888	      if(!(modeflag & HalfDCLK)) {10889		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);10890		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);10891		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);10892		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);10893		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);10894		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);10895		 if(ModeNo == 0x12) {10896		    switch(tempch) {10897		       case 0:10898			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);10899			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);10900			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);10901			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);10902			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);10903			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);10904			  break;10905		       case 2:10906			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);10907			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);10908			  break;10909		       case 3:10910			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);10911			  break;10912		    }10913		 }10914	      }10915	   }10916	}10917     } else {10918        tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);10919	tempcl &= 0x0f;10920	tempbh &= 0x70;10921	tempbh >>= 4;10922	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);10923	tempbx = (tempbh << 8) | tempbl;10924	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {10925	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {10926	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {10927	      	 tempbx = 770;10928	      } else {10929	         if(tempbx > 770) tempbx = 770;10930		 if(SiS_Pr->SiS_VGAVDE < 600) {10931		    tempax = 768 - SiS_Pr->SiS_VGAVDE;10932		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */10933		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */10934		    tempbx -= tempax;10935		 }10936	      }10937	   } else return;10938	}10939	temp = tempbx & 0xff;10940	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);10941	temp = ((tempbx & 0xff00) >> 4) | tempcl;10942	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);10943     }10944  }10945}10946 10947#endif10948 10949/*  =================  SiS 300 O.E.M. ================== */10950 10951#ifdef CONFIG_FB_SIS_30010952 10953static void10954SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,10955		unsigned short RefTabIndex)10956{10957  unsigned short crt2crtc=0, modeflag, myindex=0;10958  unsigned char  temp;10959  int i;10960 10961  if(ModeNo <= 0x13) {10962     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;10963     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;10964  } else {10965     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;10966     crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;10967  }10968 10969  crt2crtc &= 0x3f;10970 10971  if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {10972     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);10973  }10974 10975  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {10976     if(modeflag & HalfDCLK) myindex = 1;10977 10978     if(SiS_Pr->SiS_SetFlag & LowModeTests) {10979        for(i=0; i<7; i++) {10980           if(barco_p1[myindex][crt2crtc][i][0]) {10981	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,10982	                      barco_p1[myindex][crt2crtc][i][0],10983	   	   	      barco_p1[myindex][crt2crtc][i][2],10984			      barco_p1[myindex][crt2crtc][i][1]);10985	   }10986        }10987     }10988     temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);10989     if(temp & 0x80) {10990        temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);10991        temp++;10992        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);10993     }10994  }10995}10996 10997static unsigned short10998GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)10999{11000  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;11001  unsigned short tempbx=0,romptr=0;11002  static const unsigned char customtable300[] = {11003	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,11004	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff11005  };11006  static const unsigned char customtable630[] = {11007	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,11008	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff11009  };11010 11011  if(SiS_Pr->ChipType == SIS_300) {11012 11013    tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;11014    if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;11015    tempbx -= 2;11016    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;11017    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {11018       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;11019    }11020    if(SiS_Pr->SiS_UseROM) {11021       if(ROMAddr[0x235] & 0x80) {11022          tempbx = SiS_Pr->SiS_LCDTypeInfo;11023          if(Flag) {11024	     romptr = SISGETROMW(0x255);11025	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];11026	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];11027             if(tempbx == 0xFF) return 0xFFFF;11028          }11029	  tempbx <<= 1;11030	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;11031       }11032    }11033 11034  } else {11035 11036    if(Flag) {11037       if(SiS_Pr->SiS_UseROM) {11038          romptr = SISGETROMW(0x255);11039	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];11040	  else 	     tempbx = 0xff;11041       } else {11042          tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];11043       }11044       if(tempbx == 0xFF) return 0xFFFF;11045       tempbx <<= 2;11046       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;11047       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;11048       return tempbx;11049    }11050    tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;11051    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;11052    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;11053 11054  }11055 11056  return tempbx;11057}11058 11059static void11060SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)11061{11062  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;11063  unsigned short index,temp,romptr=0;11064 11065  if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;11066 11067  if(SiS_Pr->SiS_UseROM) {11068     if(!(ROMAddr[0x237] & 0x01)) return;11069     if(!(ROMAddr[0x237] & 0x02)) return;11070     romptr = SISGETROMW(0x24b);11071  }11072 11073  /* The Panel Compensation Delay should be set according to tables11074   * here. Unfortunately, various BIOS versions don't care about11075   * a uniform way using eg. ROM byte 0x220, but use different11076   * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().11077   * Thus we don't set this if the user selected a custom pdc or if11078   * we otherwise detected a valid pdc.11079   */11080  if(SiS_Pr->PDC != -1) return;11081 11082  temp = GetOEMLCDPtr(SiS_Pr, 0);11083 11084  if(SiS_Pr->UseCustomMode)11085     index = 0;11086  else11087     index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;11088 11089  if(SiS_Pr->ChipType != SIS_300) {11090     if(romptr) {11091	romptr += (temp * 2);11092	romptr = SISGETROMW(romptr);11093	romptr += index;11094	temp = ROMAddr[romptr];11095     } else {11096	if(SiS_Pr->SiS_VBType & VB_SISVB) {11097    	   temp = SiS300_OEMLCDDelay2[temp][index];11098	} else {11099           temp = SiS300_OEMLCDDelay3[temp][index];11100        }11101     }11102  } else {11103     if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {11104	if(romptr) {11105	   romptr += (temp * 2);11106	   romptr = SISGETROMW(romptr);11107	   romptr += index;11108	   temp = ROMAddr[romptr];11109	} else {11110	   temp = SiS300_OEMLCDDelay5[temp][index];11111	}11112     } else {11113        if(SiS_Pr->SiS_UseROM) {11114	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);11115	   if(romptr) {11116	      romptr += (temp * 2);11117	      romptr = SISGETROMW(romptr);11118	      romptr += index;11119	      temp = ROMAddr[romptr];11120	   } else {11121	      temp = SiS300_OEMLCDDelay4[temp][index];11122	   }11123	} else {11124	   temp = SiS300_OEMLCDDelay4[temp][index];11125	}11126     }11127  }11128  temp &= 0x3c;11129  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */11130}11131 11132static void11133SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)11134{11135#if 0  /* Unfinished; Data table missing */11136  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;11137  unsigned short index,temp;11138 11139  if((SiS_Pr->SiS_UseROM) {11140     if(!(ROMAddr[0x237] & 0x01)) return;11141     if(!(ROMAddr[0x237] & 0x04)) return;11142     /* No rom pointer in BIOS header! */11143  }11144 11145  temp = GetOEMLCDPtr(SiS_Pr, 1);11146  if(temp == 0xFFFF) return;11147 11148  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;11149  for(i=0x14, j=0; i<=0x17; i++, j++) {11150      SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);11151  }11152  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));11153 11154  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;11155  SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);11156  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);11157  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));11158  for(i=0x1b, j=3; i<=0x1d; i++, j++) {11159      SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);11160  }11161#endif11162}11163 11164static unsigned short11165GetOEMTVPtr(struct SiS_Private *SiS_Pr)11166{11167  unsigned short index;11168 11169  index = 0;11170  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;11171  if(SiS_Pr->SiS_VBType & VB_SISVB) {11172     if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;11173     else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;11174     else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;11175  } else {11176     if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;11177     if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;11178  }11179  return index;11180}11181 11182static void11183SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)11184{11185  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;11186  unsigned short index,temp,romptr=0;11187 11188  if(SiS_Pr->SiS_UseROM) {11189     if(!(ROMAddr[0x238] & 0x01)) return;11190     if(!(ROMAddr[0x238] & 0x02)) return;11191     romptr = SISGETROMW(0x241);11192  }11193 11194  temp = GetOEMTVPtr(SiS_Pr);11195 11196  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;11197 11198  if(romptr) {11199     romptr += (temp * 2);11200     romptr = SISGETROMW(romptr);11201     romptr += index;11202     temp = ROMAddr[romptr];11203  } else {11204     if(SiS_Pr->SiS_VBType & VB_SISVB) {11205        temp = SiS300_OEMTVDelay301[temp][index];11206     } else {11207        temp = SiS300_OEMTVDelayLVDS[temp][index];11208     }11209  }11210  temp &= 0x3c;11211  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);11212}11213 11214static void11215SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)11216{11217  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;11218  unsigned short index,temp,romptr=0;11219 11220  if(SiS_Pr->SiS_UseROM) {11221     if(!(ROMAddr[0x238] & 0x01)) return;11222     if(!(ROMAddr[0x238] & 0x04)) return;11223     romptr = SISGETROMW(0x243);11224  }11225 11226  temp = GetOEMTVPtr(SiS_Pr);11227 11228  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;11229 11230  if(romptr) {11231     romptr += (temp * 2);11232     romptr = SISGETROMW(romptr);11233     romptr += index;11234     temp = ROMAddr[romptr];11235  } else {11236     temp = SiS300_OEMTVFlicker[temp][index];11237  }11238  temp &= 0x70;11239  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);11240}11241 11242static void11243SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)11244{11245  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;11246  unsigned short index,i,j,temp,romptr=0;11247 11248  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;11249 11250  if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;11251 11252  if(SiS_Pr->SiS_UseROM) {11253     if(!(ROMAddr[0x238] & 0x01)) return;11254     if(!(ROMAddr[0x238] & 0x08)) return;11255     romptr = SISGETROMW(0x245);11256  }11257 11258  temp = GetOEMTVPtr(SiS_Pr);11259 11260  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;11261 11262  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {11263     for(i=0x31, j=0; i<=0x34; i++, j++) {11264        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);11265     }11266  } else {11267     if(romptr) {11268        romptr += (temp * 2);11269	romptr = SISGETROMW(romptr);11270	romptr += (index * 4);11271        for(i=0x31, j=0; i<=0x34; i++, j++) {11272	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);11273	}11274     } else {11275        for(i=0x31, j=0; i<=0x34; i++, j++) {11276           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);11277	}11278     }11279  }11280}11281 11282static void11283SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)11284{11285  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;11286  unsigned short index,temp,i,j,romptr=0;11287 11288  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;11289 11290  if(SiS_Pr->SiS_UseROM) {11291     if(!(ROMAddr[0x238] & 0x01)) return;11292     if(!(ROMAddr[0x238] & 0x10)) return;11293     romptr = SISGETROMW(0x247);11294  }11295 11296  temp = GetOEMTVPtr(SiS_Pr);11297 11298  if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;11299  else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;11300  /* NTSCJ uses NTSC filters */11301 11302  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;11303 11304  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {11305      for(i=0x35, j=0; i<=0x38; i++, j++) {11306       	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);11307      }11308      for(i=0x48; i<=0x4A; i++, j++) {11309     	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);11310      }11311  } else {11312      if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {11313         romptr += (temp * 2);11314	 romptr = SISGETROMW(romptr);11315	 romptr += (index * 4);11316	 for(i=0x35, j=0; i<=0x38; i++, j++) {11317       	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);11318         }11319      } else {11320         for(i=0x35, j=0; i<=0x38; i++, j++) {11321       	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);11322         }11323      }11324  }11325}11326 11327static unsigned short11328SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)11329{11330   unsigned short ModeIdIndex;11331   unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;11332 11333   if(*ModeNo <= 5) *ModeNo |= 1;11334 11335   for(ModeIdIndex=0; ; ModeIdIndex++) {11336      if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;11337      if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;11338   }11339 11340   if(*ModeNo != 0x07) {11341      if(*ModeNo > 0x03) return ModeIdIndex;11342      if(VGAINFO & 0x80) return ModeIdIndex;11343      ModeIdIndex++;11344   }11345 11346   if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */11347	                               /* else 350 lines */11348   return ModeIdIndex;11349}11350 11351static void11352SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,11353		  unsigned short RefTableIndex)11354{11355  unsigned short OEMModeIdIndex = 0;11356 11357  if(!SiS_Pr->UseCustomMode) {11358     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);11359     if(!(OEMModeIdIndex)) return;11360  }11361 11362  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {11363     SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);11364     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {11365        SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);11366     }11367  }11368  if(SiS_Pr->UseCustomMode) return;11369  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {11370     SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);11371     if(SiS_Pr->SiS_VBType & VB_SISVB) {11372        SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);11373    	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);11374       	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);11375     }11376  }11377}11378#endif11379 11380