cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

init301.c (359653B)


      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, Z7
      8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
      9 *
     10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
     11 *
     12 * If distributed as part of the Linux kernel, the following license terms
     13 * apply:
     14 *
     15 * * This program is free software; you can redistribute it and/or modify
     16 * * it under the terms of the GNU General Public License as published by
     17 * * the Free Software Foundation; either version 2 of the named License,
     18 * * or any later version.
     19 * *
     20 * * This program is distributed in the hope that it will be useful,
     21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
     22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     23 * * GNU General Public License for more details.
     24 * *
     25 * * You should have received a copy of the GNU General Public License
     26 * * along with this program; if not, write to the Free Software
     27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
     28 *
     29 * Otherwise, the following license terms apply:
     30 *
     31 * * Redistribution and use in source and binary forms, with or without
     32 * * modification, are permitted provided that the following conditions
     33 * * are met:
     34 * * 1) Redistributions of source code must retain the above copyright
     35 * *    notice, this list of conditions and the following disclaimer.
     36 * * 2) Redistributions in binary form must reproduce the above copyright
     37 * *    notice, this list of conditions and the following disclaimer in the
     38 * *    documentation and/or other materials provided with the distribution.
     39 * * 3) The name of the author may not be used to endorse or promote products
     40 * *    derived from this software without specific prior written permission.
     41 * *
     42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     52 *
     53 * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
     54 *
     55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
     56 * Used by permission.
     57 *
     58 */
     59
     60#if 1
     61#define SET_EMI		/* 302LV/ELV: Set EMI values */
     62#endif
     63
     64#if 1
     65#define SET_PWD		/* 301/302LV: Set PWD */
     66#endif
     67
     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_300
     75#include "oem300.h"
     76#endif
     77
     78#ifdef CONFIG_FB_SIS_315
     79#include "oem310.h"
     80#endif
     81
     82#define SiS_I2CDELAY      1000
     83#define SiS_I2CDELAYSHORT  150
     84
     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,0x00
     95  },
     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,0x00
    105  },
    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,0x00
    116#endif
    117#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,0x00
    126#endif
    127  }
    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, 0x01
    161};
    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, 0x01
    172};
    173
    174/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */
    175
    176static 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,0x7E
    182};
    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,0x7E
    190};
    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,0xFF
    209};
    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,0xFF
    228};
    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,0xFF
    237};
    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#ifdef CONFIG_FB_SIS_315
    249/* 661 et al LCD data structure (2.03.00) */
    250static const unsigned char SiS_LCDStruct661[] = {
    251    /* 1024x768 */
    252/*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
    253    0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
    254    0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
    255    /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
    256    /*					      VESA    non-VESA  noscale */
    257    /* 1280x1024 */
    258    0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
    259    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
    260    /* 1400x1050 */
    261    0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
    262    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
    263    /* 1600x1200 */
    264    0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
    265    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
    266    /* 1280x768 (_2) */
    267    0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
    268    0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
    269    /* 1280x720 */
    270    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
    271    0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
    272    /* 1280x800 (_2) */
    273    0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
    274    0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
    275    /* 1680x1050 */
    276    0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
    277    0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
    278    /* 1280x800_3 */
    279    0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
    280    0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
    281    /* 800x600 */
    282    0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
    283    0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
    284    /* 1280x854 */
    285    0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
    286    0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
    287};
    288#endif
    289
    290#ifdef CONFIG_FB_SIS_300
    291static unsigned char SiS300_TrumpionData[14][80] = {
    292  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    293    0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
    294    0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
    295    0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
    296    0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
    297  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
    298    0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
    299    0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
    300    0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
    301    0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
    302  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
    303    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    304    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    305    0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    306    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
    307  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
    308    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    309    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    310    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    311    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
    312  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    313    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
    314    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
    315    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
    316    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
    317  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
    318    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
    319    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
    320    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
    321    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
    322  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
    323    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
    324    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
    325    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
    326    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
    327  /* variant 2 */
    328  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    329    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
    330    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
    331    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
    332    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
    333  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    334    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
    335    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
    336    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
    337    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
    338  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
    339    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    340    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    341    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    342    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
    343  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
    344    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    345    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    346    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    347    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
    348  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    349    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
    350    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
    351    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
    352    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
    353  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
    354    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
    355    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
    356    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
    357    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
    358  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
    359    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
    360    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
    361    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
    362    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
    363};
    364#endif
    365
    366#ifdef CONFIG_FB_SIS_315
    367static void	SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
    368static void	SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
    369static void	SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
    370static void	SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
    371#endif /* 315 */
    372
    373#ifdef CONFIG_FB_SIS_300
    374static  bool	SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
    375#endif
    376
    377static unsigned short	SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
    378				int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
    379				bool checkcr32, unsigned int VBFlags2);
    380static unsigned short	SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
    381static unsigned short	SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
    382				unsigned char *buffer);
    383static void		SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
    384static unsigned short	SiS_SetStart(struct SiS_Private *SiS_Pr);
    385static unsigned short	SiS_SetStop(struct SiS_Private *SiS_Pr);
    386static unsigned short	SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
    387static unsigned short	SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
    388static unsigned short	SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
    389static unsigned short	SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
    390static unsigned short	SiS_CheckACK(struct SiS_Private *SiS_Pr);
    391static unsigned short	SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
    392static unsigned short	SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
    393static unsigned short	SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
    394static void		SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
    395static unsigned short	SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
    396
    397#ifdef CONFIG_FB_SIS_300
    398static void		SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
    399				unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
    400static void		SetOEMLCDData2(struct SiS_Private *SiS_Pr,
    401				unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
    402#endif
    403#ifdef CONFIG_FB_SIS_315
    404static void		SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
    405				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
    406static void		SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
    407				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
    408static void		SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
    409#endif
    410
    411static unsigned short	SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
    412static void		SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
    413
    414/*********************************************/
    415/*         HELPER: Lock/Unlock CRT2          */
    416/*********************************************/
    417
    418void
    419SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
    420{
    421   if(SiS_Pr->ChipType == XGI_20)
    422      return;
    423   else if(SiS_Pr->ChipType >= SIS_315H)
    424      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
    425   else
    426      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
    427}
    428
    429static
    430void
    431SiS_LockCRT2(struct SiS_Private *SiS_Pr)
    432{
    433   if(SiS_Pr->ChipType == XGI_20)
    434      return;
    435   else if(SiS_Pr->ChipType >= SIS_315H)
    436      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
    437   else
    438      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
    439}
    440
    441/*********************************************/
    442/*            HELPER: Write SR11             */
    443/*********************************************/
    444
    445static void
    446SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
    447{
    448   if(SiS_Pr->ChipType >= SIS_661) {
    449      DataAND &= 0x0f;
    450      DataOR  &= 0x0f;
    451   }
    452   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
    453}
    454
    455/*********************************************/
    456/*    HELPER: Get Pointer to LCD structure   */
    457/*********************************************/
    458
    459#ifdef CONFIG_FB_SIS_315
    460static unsigned char *
    461GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
    462{
    463   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
    464   unsigned char  *myptr = NULL;
    465   unsigned short romindex = 0, reg = 0, idx = 0;
    466
    467   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
    468    * due to the variaty of panels the BIOS doesn't know about.
    469    * Exception: If the BIOS has better knowledge (such as in case
    470    * of machines with a 301C and a panel that does not support DDC)
    471    * use the BIOS data as well.
    472    */
    473
    474   if((SiS_Pr->SiS_ROMNew) &&
    475      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
    476
    477      if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
    478      else                           reg = 0x7d;
    479
    480      idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;
    481
    482      if(idx < (8*26)) {
    483         myptr = (unsigned char *)&SiS_LCDStruct661[idx];
    484      }
    485      romindex = SISGETROMW(0x100);
    486      if(romindex) {
    487         romindex += idx;
    488         myptr = &ROMAddr[romindex];
    489      }
    490   }
    491   return myptr;
    492}
    493
    494static unsigned short
    495GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
    496{
    497   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
    498   unsigned short romptr = 0;
    499
    500   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
    501    * due to the variaty of panels the BIOS doesn't know about.
    502    * Exception: If the BIOS has better knowledge (such as in case
    503    * of machines with a 301C and a panel that does not support DDC)
    504    * use the BIOS data as well.
    505    */
    506
    507   if((SiS_Pr->SiS_ROMNew) &&
    508      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
    509      romptr = SISGETROMW(0x102);
    510      romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
    511   }
    512
    513   return romptr;
    514}
    515#endif
    516
    517/*********************************************/
    518/*           Adjust Rate for CRT2            */
    519/*********************************************/
    520
    521static bool
    522SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
    523		unsigned short RRTI, unsigned short *i)
    524{
    525   unsigned short checkmask=0, modeid, infoflag;
    526
    527   modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;
    528
    529   if(SiS_Pr->SiS_VBType & VB_SISVB) {
    530
    531      if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
    532
    533	 checkmask |= SupportRAMDAC2;
    534	 if(SiS_Pr->ChipType >= SIS_315H) {
    535	    checkmask |= SupportRAMDAC2_135;
    536	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
    537	       checkmask |= SupportRAMDAC2_162;
    538	       if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
    539		  checkmask |= SupportRAMDAC2_202;
    540	       }
    541	    }
    542	 }
    543
    544      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
    545
    546	 checkmask |= SupportLCD;
    547	 if(SiS_Pr->ChipType >= SIS_315H) {
    548	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
    549	       if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
    550	          if(modeid == 0x2e) checkmask |= Support64048060Hz;
    551	       }
    552	    }
    553	 }
    554
    555      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
    556
    557	 checkmask |= SupportHiVision;
    558
    559      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
    560
    561	 checkmask |= SupportTV;
    562	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
    563	    checkmask |= SupportTV1024;
    564	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
    565	       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
    566	          checkmask |= SupportYPbPr750p;
    567	       }
    568	    }
    569	 }
    570
    571      }
    572
    573   } else {	/* LVDS */
    574
    575      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
    576	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
    577	    checkmask |= SupportCHTV;
    578	 }
    579      }
    580
    581      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
    582	 checkmask |= SupportLCD;
    583      }
    584
    585   }
    586
    587   /* Look backwards in table for matching CRT2 mode */
    588   for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
    589      infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
    590      if(infoflag & checkmask) return true;
    591      if((*i) == 0) break;
    592   }
    593
    594   /* Look through the whole mode-section of the table from the beginning
    595    * for a matching CRT2 mode if no mode was found yet.
    596    */
    597   for((*i) = 0; ; (*i)++) {
    598      if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
    599      infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
    600      if(infoflag & checkmask) return true;
    601   }
    602   return false;
    603}
    604
    605/*********************************************/
    606/*              Get rate index               */
    607/*********************************************/
    608
    609unsigned short
    610SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
    611{
    612   unsigned short RRTI,i,backup_i;
    613   unsigned short modeflag,index,temp,backupindex;
    614   static const unsigned short LCDRefreshIndex[] = {
    615		0x00, 0x00, 0x01, 0x01,
    616		0x01, 0x01, 0x01, 0x01,
    617		0x01, 0x01, 0x01, 0x01,
    618		0x01, 0x01, 0x01, 0x01,
    619		0x00, 0x00, 0x00, 0x00
    620   };
    621
    622   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
    623   if(ModeNo == 0xfe) return 0;
    624
    625   if(ModeNo <= 0x13) {
    626      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
    627   } else {
    628      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
    629   }
    630
    631   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
    632      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
    633	 if(modeflag & HalfDCLK) return 0;
    634      }
    635   }
    636
    637   if(ModeNo < 0x14) return 0xFFFF;
    638
    639   index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
    640   backupindex = index;
    641
    642   if(index > 0) index--;
    643
    644   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
    645      if(SiS_Pr->SiS_VBType & VB_SISVB) {
    646	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
    647	    if(SiS_Pr->SiS_VBType & VB_NoLCD)		 index = 0;
    648	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
    649	 }
    650	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
    651	    if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
    652	       temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
    653	       if(index > temp) index = temp;
    654	    }
    655	 }
    656      } else {
    657	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
    658	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
    659	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
    660	 }
    661      }
    662   }
    663
    664   RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
    665   ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;
    666
    667   if(SiS_Pr->ChipType >= SIS_315H) {
    668      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
    669	 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
    670	     (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
    671	    if(backupindex <= 1) RRTI++;
    672	 }
    673      }
    674   }
    675
    676   i = 0;
    677   do {
    678      if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
    679      temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
    680      temp &= ModeTypeMask;
    681      if(temp < SiS_Pr->SiS_ModeType) break;
    682      i++;
    683      index--;
    684   } while(index != 0xFFFF);
    685
    686   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
    687      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
    688	 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
    689	 if(temp & InterlaceMode) i++;
    690      }
    691   }
    692
    693   i--;
    694
    695   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
    696      backup_i = i;
    697      if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
    698	 i = backup_i;
    699      }
    700   }
    701
    702   return (RRTI + i);
    703}
    704
    705/*********************************************/
    706/*            STORE CRT2 INFO in CR34        */
    707/*********************************************/
    708
    709static void
    710SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
    711{
    712   unsigned short temp1, temp2;
    713
    714   /* Store CRT1 ModeNo in CR34 */
    715   SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
    716   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
    717   temp2 = ~(SetInSlaveMode >> 8);
    718   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
    719}
    720
    721/*********************************************/
    722/*    HELPER: GET SOME DATA FROM BIOS ROM    */
    723/*********************************************/
    724
    725#ifdef CONFIG_FB_SIS_300
    726static bool
    727SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
    728{
    729   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
    730   unsigned short temp,temp1;
    731
    732   if(SiS_Pr->SiS_UseROM) {
    733      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
    734	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
    735	 temp1 = SISGETROMW(0x23b);
    736	 if(temp1 & temp) return true;
    737      }
    738   }
    739   return false;
    740}
    741
    742static bool
    743SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
    744{
    745   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
    746   unsigned short temp,temp1;
    747
    748   if(SiS_Pr->SiS_UseROM) {
    749      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
    750	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
    751	 temp1 = SISGETROMW(0x23d);
    752	 if(temp1 & temp) return true;
    753      }
    754   }
    755   return false;
    756}
    757#endif
    758
    759/*********************************************/
    760/*          HELPER: DELAY FUNCTIONS          */
    761/*********************************************/
    762
    763void
    764SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
    765{
    766   while (delaytime-- > 0)
    767      SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
    768}
    769
    770#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
    771static void
    772SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
    773{
    774   SiS_DDC2Delay(SiS_Pr, delay * 36);
    775}
    776#endif
    777
    778#ifdef CONFIG_FB_SIS_315
    779static void
    780SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
    781{
    782   while(delay--) {
    783      SiS_GenericDelay(SiS_Pr, 6623);
    784   }
    785}
    786#endif
    787
    788#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
    789static void
    790SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
    791{
    792   while(delay--) {
    793      SiS_GenericDelay(SiS_Pr, 66);
    794   }
    795}
    796#endif
    797
    798static void
    799SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
    800{
    801#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
    802   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
    803   unsigned short PanelID, DelayIndex, Delay=0;
    804#endif
    805
    806   if(SiS_Pr->ChipType < SIS_315H) {
    807
    808#ifdef CONFIG_FB_SIS_300
    809
    810      PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
    811      if(SiS_Pr->SiS_VBType & VB_SISVB) {
    812	 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
    813	 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
    814      }
    815      DelayIndex = PanelID >> 4;
    816      if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
    817	 Delay = 3;
    818      } else {
    819	 if(DelayTime >= 2) DelayTime -= 2;
    820	 if(!(DelayTime & 0x01)) {
    821	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
    822	 } else {
    823	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
    824	 }
    825	 if(SiS_Pr->SiS_UseROM) {
    826	    if(ROMAddr[0x220] & 0x40) {
    827	       if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
    828	       else 	    	       Delay = (unsigned short)ROMAddr[0x226];
    829	    }
    830	 }
    831      }
    832      SiS_ShortDelay(SiS_Pr, Delay);
    833
    834#endif  /* CONFIG_FB_SIS_300 */
    835
    836   } else {
    837
    838#ifdef CONFIG_FB_SIS_315
    839
    840      if((SiS_Pr->ChipType >= SIS_661)    ||
    841	 (SiS_Pr->ChipType <= SIS_315PRO) ||
    842	 (SiS_Pr->ChipType == SIS_330)    ||
    843	 (SiS_Pr->SiS_ROMNew)) {
    844
    845	 if(!(DelayTime & 0x01)) {
    846	    SiS_DDC2Delay(SiS_Pr, 0x1000);
    847	 } else {
    848	    SiS_DDC2Delay(SiS_Pr, 0x4000);
    849	 }
    850
    851      } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS; Special */
    852
    853	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
    854	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
    855	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
    856	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
    857	    }
    858	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
    859	       DelayIndex = PanelID & 0x0f;
    860	    } else {
    861	       DelayIndex = PanelID >> 4;
    862	    }
    863	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
    864	       Delay = 3;
    865	    } else {
    866	       if(DelayTime >= 2) DelayTime -= 2;
    867	       if(!(DelayTime & 0x01)) {
    868		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
    869		} else {
    870		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
    871	       }
    872	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
    873		  if(ROMAddr[0x13c] & 0x40) {
    874		     if(!(DelayTime & 0x01)) {
    875			Delay = (unsigned short)ROMAddr[0x17e];
    876		     } else {
    877			Delay = (unsigned short)ROMAddr[0x17f];
    878		     }
    879		  }
    880	       }
    881	    }
    882	    SiS_ShortDelay(SiS_Pr, Delay);
    883	 }
    884
    885      } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */
    886
    887	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
    888	 if(!(DelayTime & 0x01)) {
    889	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
    890	 } else {
    891	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
    892	 }
    893	 Delay <<= 8;
    894	 SiS_DDC2Delay(SiS_Pr, Delay);
    895
    896      }
    897
    898#endif /* CONFIG_FB_SIS_315 */
    899
    900   }
    901}
    902
    903#ifdef CONFIG_FB_SIS_315
    904static void
    905SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
    906{
    907   int i;
    908   for(i = 0; i < DelayLoop; i++) {
    909      SiS_PanelDelay(SiS_Pr, DelayTime);
    910   }
    911}
    912#endif
    913
    914/*********************************************/
    915/*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
    916/*********************************************/
    917
    918void
    919SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
    920{
    921   unsigned short watchdog;
    922
    923   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
    924   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
    925
    926   watchdog = 65535;
    927   while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
    928   watchdog = 65535;
    929   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
    930}
    931
    932#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
    933static void
    934SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
    935{
    936   unsigned short watchdog;
    937
    938   watchdog = 65535;
    939   while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
    940   watchdog = 65535;
    941   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
    942}
    943#endif
    944
    945static void
    946SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
    947{
    948   if(SiS_Pr->ChipType < SIS_315H) {
    949#ifdef CONFIG_FB_SIS_300
    950      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
    951	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
    952      }
    953      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
    954	 SiS_WaitRetrace1(SiS_Pr);
    955      } else {
    956	 SiS_WaitRetrace2(SiS_Pr, 0x25);
    957      }
    958#endif
    959   } else {
    960#ifdef CONFIG_FB_SIS_315
    961      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
    962	 SiS_WaitRetrace1(SiS_Pr);
    963      } else {
    964	 SiS_WaitRetrace2(SiS_Pr, 0x30);
    965      }
    966#endif
    967   }
    968}
    969
    970static void
    971SiS_VBWait(struct SiS_Private *SiS_Pr)
    972{
    973   unsigned short tempal,temp,i,j;
    974
    975   temp = 0;
    976   for(i = 0; i < 3; i++) {
    977     for(j = 0; j < 100; j++) {
    978        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
    979        if(temp & 0x01) {
    980	   if((tempal & 0x08))  continue;
    981	   else break;
    982        } else {
    983	   if(!(tempal & 0x08)) continue;
    984	   else break;
    985        }
    986     }
    987     temp ^= 0x01;
    988   }
    989}
    990
    991static void
    992SiS_VBLongWait(struct SiS_Private *SiS_Pr)
    993{
    994   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
    995      SiS_VBWait(SiS_Pr);
    996   } else {
    997      SiS_WaitRetrace1(SiS_Pr);
    998   }
    999}
   1000
   1001/*********************************************/
   1002/*               HELPER: MISC                */
   1003/*********************************************/
   1004
   1005#ifdef CONFIG_FB_SIS_300
   1006static bool
   1007SiS_Is301B(struct SiS_Private *SiS_Pr)
   1008{
   1009   if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
   1010   return false;
   1011}
   1012#endif
   1013
   1014static bool
   1015SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
   1016{
   1017   if(SiS_Pr->ChipType == SIS_730) {
   1018      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
   1019   }
   1020   if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
   1021   return false;
   1022}
   1023
   1024bool
   1025SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
   1026{
   1027#ifdef CONFIG_FB_SIS_315
   1028   if(SiS_Pr->ChipType >= SIS_315H) {
   1029      if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
   1030	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
   1031      }
   1032   }
   1033#endif
   1034   return false;
   1035}
   1036
   1037bool
   1038SiS_IsVAMode(struct SiS_Private *SiS_Pr)
   1039{
   1040#ifdef CONFIG_FB_SIS_315
   1041   unsigned short flag;
   1042
   1043   if(SiS_Pr->ChipType >= SIS_315H) {
   1044      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
   1045      if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
   1046   }
   1047#endif
   1048   return false;
   1049}
   1050
   1051#ifdef CONFIG_FB_SIS_315
   1052static bool
   1053SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
   1054{
   1055   if(SiS_IsVAMode(SiS_Pr))  return true;
   1056   if(SiS_CRT2IsLCD(SiS_Pr)) return true;
   1057   return false;
   1058}
   1059#endif
   1060
   1061static bool
   1062SiS_IsDualLink(struct SiS_Private *SiS_Pr)
   1063{
   1064#ifdef CONFIG_FB_SIS_315
   1065   if(SiS_Pr->ChipType >= SIS_315H) {
   1066      if((SiS_CRT2IsLCD(SiS_Pr)) ||
   1067         (SiS_IsVAMode(SiS_Pr))) {
   1068	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
   1069      }
   1070   }
   1071#endif
   1072   return false;
   1073}
   1074
   1075#ifdef CONFIG_FB_SIS_315
   1076static bool
   1077SiS_TVEnabled(struct SiS_Private *SiS_Pr)
   1078{
   1079   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
   1080   if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
   1081      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
   1082   }
   1083   return false;
   1084}
   1085#endif
   1086
   1087#ifdef CONFIG_FB_SIS_315
   1088static bool
   1089SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
   1090{
   1091   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
   1092   return false;
   1093}
   1094#endif
   1095
   1096#ifdef CONFIG_FB_SIS_315
   1097static bool
   1098SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
   1099{
   1100   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
   1101      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
   1102   }
   1103   return false;
   1104}
   1105#endif
   1106
   1107#ifdef CONFIG_FB_SIS_315
   1108static bool
   1109SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
   1110{
   1111   unsigned short flag;
   1112
   1113   if(SiS_Pr->ChipType == SIS_650) {
   1114      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
   1115      /* Check for revision != A0 only */
   1116      if((flag == 0xe0) || (flag == 0xc0) ||
   1117         (flag == 0xb0) || (flag == 0x90)) return false;
   1118   } else if(SiS_Pr->ChipType >= SIS_661) return false;
   1119   return true;
   1120}
   1121#endif
   1122
   1123#ifdef CONFIG_FB_SIS_315
   1124static bool
   1125SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
   1126{
   1127   if(SiS_Pr->ChipType >= SIS_315H) {
   1128      /* YPrPb = 0x08 */
   1129      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
   1130   }
   1131   return false;
   1132}
   1133#endif
   1134
   1135#ifdef CONFIG_FB_SIS_315
   1136static bool
   1137SiS_IsChScart(struct SiS_Private *SiS_Pr)
   1138{
   1139   if(SiS_Pr->ChipType >= SIS_315H) {
   1140      /* Scart = 0x04 */
   1141      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
   1142   }
   1143   return false;
   1144}
   1145#endif
   1146
   1147#ifdef CONFIG_FB_SIS_315
   1148static bool
   1149SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
   1150{
   1151   unsigned short flag;
   1152
   1153   if(SiS_Pr->ChipType >= SIS_315H) {
   1154      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   1155      if(flag & SetCRT2ToTV)        return true;
   1156      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
   1157      if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
   1158      if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
   1159   } else {
   1160      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   1161      if(flag & SetCRT2ToTV)        return true;
   1162   }
   1163   return false;
   1164}
   1165#endif
   1166
   1167#ifdef CONFIG_FB_SIS_315
   1168static bool
   1169SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
   1170{
   1171   unsigned short flag;
   1172
   1173   if(SiS_Pr->ChipType >= SIS_315H) {
   1174      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   1175      if(flag & SetCRT2ToLCD) return true;
   1176      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
   1177      if(flag & SetToLCDA)    return true;
   1178   } else {
   1179      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   1180      if(flag & SetCRT2ToLCD) return true;
   1181   }
   1182   return false;
   1183}
   1184#endif
   1185
   1186static bool
   1187SiS_HaveBridge(struct SiS_Private *SiS_Pr)
   1188{
   1189   unsigned short flag;
   1190
   1191   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   1192      return true;
   1193   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1194      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
   1195      if((flag == 1) || (flag == 2)) return true;
   1196   }
   1197   return false;
   1198}
   1199
   1200static bool
   1201SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
   1202{
   1203   unsigned short flag;
   1204
   1205   if(SiS_HaveBridge(SiS_Pr)) {
   1206      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
   1207      if(SiS_Pr->ChipType < SIS_315H) {
   1208	flag &= 0xa0;
   1209	if((flag == 0x80) || (flag == 0x20)) return true;
   1210      } else {
   1211	flag &= 0x50;
   1212	if((flag == 0x40) || (flag == 0x10)) return true;
   1213      }
   1214   }
   1215   return false;
   1216}
   1217
   1218static bool
   1219SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
   1220{
   1221   unsigned short flag1;
   1222
   1223   flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
   1224   if(flag1 & (SetInSlaveMode >> 8)) return true;
   1225   return false;
   1226}
   1227
   1228/*********************************************/
   1229/*       GET VIDEO BRIDGE CONFIG INFO        */
   1230/*********************************************/
   1231
   1232/* Setup general purpose IO for Chrontel communication */
   1233#ifdef CONFIG_FB_SIS_300
   1234void
   1235SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
   1236{
   1237   unsigned int   acpibase;
   1238   unsigned short temp;
   1239
   1240   if(!(SiS_Pr->SiS_ChSW)) return;
   1241
   1242   acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
   1243   acpibase &= 0xFFFF;
   1244   if(!acpibase) return;
   1245   temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */
   1246   temp &= 0xFEFF;
   1247   SiS_SetRegShort((acpibase + 0x3c), temp);
   1248   temp = SiS_GetRegShort((acpibase + 0x3c));
   1249   temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */
   1250   temp &= 0xFEFF;
   1251   if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
   1252   SiS_SetRegShort((acpibase + 0x3a), temp);
   1253   temp = SiS_GetRegShort((acpibase + 0x3a));
   1254}
   1255#endif
   1256
   1257void
   1258SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
   1259		unsigned short ModeIdIndex, int checkcrt2mode)
   1260{
   1261   unsigned short tempax, tempbx, temp;
   1262   unsigned short modeflag, resinfo = 0;
   1263
   1264   SiS_Pr->SiS_SetFlag = 0;
   1265
   1266   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
   1267
   1268   SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;
   1269
   1270   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
   1271      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   1272   }
   1273
   1274   tempbx = 0;
   1275
   1276   if(SiS_HaveBridge(SiS_Pr)) {
   1277
   1278	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   1279	tempbx |= temp;
   1280	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
   1281	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
   1282	tempbx |= tempax;
   1283
   1284#ifdef CONFIG_FB_SIS_315
   1285	if(SiS_Pr->ChipType >= SIS_315H) {
   1286	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
   1287	      if(ModeNo == 0x03) {
   1288		 /* Mode 0x03 is never in driver mode */
   1289		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
   1290	      }
   1291	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
   1292		 /* Reset LCDA setting if not driver mode */
   1293		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
   1294	      }
   1295	      if(IS_SIS650) {
   1296		 if(SiS_Pr->SiS_UseLCDA) {
   1297		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
   1298		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
   1299			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
   1300		       }
   1301		    }
   1302		 }
   1303	      }
   1304	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
   1305	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
   1306		 tempbx |= SetCRT2ToLCDA;
   1307	      }
   1308	   }
   1309
   1310	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
   1311	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
   1312	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
   1313		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
   1314		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
   1315		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
   1316		    tempbx |= SetCRT2ToYPbPr525750;
   1317		 }
   1318	      }
   1319	   }
   1320
   1321	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   1322	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
   1323	      if(temp & SetToLCDA) {
   1324		 tempbx |= SetCRT2ToLCDA;
   1325	      }
   1326	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   1327		 if(temp & EnableCHYPbPr) {
   1328		    tempbx |= SetCRT2ToCHYPbPr;
   1329		 }
   1330	      }
   1331	   }
   1332	}
   1333
   1334#endif  /* CONFIG_FB_SIS_315 */
   1335
   1336        if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
   1337	   tempbx &= ~(SetCRT2ToRAMDAC);
   1338	}
   1339
   1340	if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1341	   temp = SetCRT2ToSVIDEO   |
   1342		  SetCRT2ToAVIDEO   |
   1343		  SetCRT2ToSCART    |
   1344		  SetCRT2ToLCDA     |
   1345		  SetCRT2ToLCD      |
   1346		  SetCRT2ToRAMDAC   |
   1347		  SetCRT2ToHiVision |
   1348		  SetCRT2ToYPbPr525750;
   1349	} else {
   1350	   if(SiS_Pr->ChipType >= SIS_315H) {
   1351	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   1352		 temp = SetCRT2ToAVIDEO |
   1353		        SetCRT2ToSVIDEO |
   1354		        SetCRT2ToSCART  |
   1355		        SetCRT2ToLCDA   |
   1356		        SetCRT2ToLCD    |
   1357		        SetCRT2ToCHYPbPr;
   1358	      } else {
   1359		 temp = SetCRT2ToLCDA   |
   1360		        SetCRT2ToLCD;
   1361	      }
   1362	   } else {
   1363	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   1364		 temp = SetCRT2ToTV | SetCRT2ToLCD;
   1365	      } else {
   1366		 temp = SetCRT2ToLCD;
   1367	      }
   1368	   }
   1369	}
   1370
   1371	if(!(tempbx & temp)) {
   1372	   tempax = DisableCRT2Display;
   1373	   tempbx = 0;
   1374	}
   1375
   1376	if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1377
   1378	   unsigned short clearmask = ( DriverMode |
   1379				DisableCRT2Display |
   1380				LoadDACFlag 	   |
   1381				SetNotSimuMode 	   |
   1382				SetInSlaveMode 	   |
   1383				SetPALTV 	   |
   1384				SwitchCRT2	   |
   1385				SetSimuScanMode );
   1386
   1387	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
   1388	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
   1389	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
   1390	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
   1391	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
   1392	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
   1393
   1394	} else {
   1395
   1396	   if(SiS_Pr->ChipType >= SIS_315H) {
   1397	      if(tempbx & SetCRT2ToLCDA) {
   1398		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
   1399	      }
   1400	   }
   1401	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   1402	      if(tempbx & SetCRT2ToTV) {
   1403		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
   1404	      }
   1405	   }
   1406	   if(tempbx & SetCRT2ToLCD) {
   1407	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
   1408	   }
   1409	   if(SiS_Pr->ChipType >= SIS_315H) {
   1410	      if(tempbx & SetCRT2ToLCDA) {
   1411	         tempbx |= SetCRT2ToLCD;
   1412	      }
   1413	   }
   1414
   1415	}
   1416
   1417	if(tempax & DisableCRT2Display) {
   1418	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
   1419	      tempbx = SetSimuScanMode | DisableCRT2Display;
   1420	   }
   1421	}
   1422
   1423	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
   1424
   1425	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
   1426	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
   1427	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
   1428	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
   1429	      modeflag &= (~CRT2Mode);
   1430	   }
   1431	}
   1432
   1433	if(!(tempbx & SetSimuScanMode)) {
   1434	   if(tempbx & SwitchCRT2) {
   1435	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
   1436		 if(resinfo != SIS_RI_1600x1200) {
   1437		    tempbx |= SetSimuScanMode;
   1438		 }
   1439              }
   1440	   } else {
   1441	      if(SiS_BridgeIsEnabled(SiS_Pr)) {
   1442		 if(!(tempbx & DriverMode)) {
   1443		    if(SiS_BridgeInSlavemode(SiS_Pr)) {
   1444		       tempbx |= SetSimuScanMode;
   1445		    }
   1446		 }
   1447	      }
   1448	   }
   1449	}
   1450
   1451	if(!(tempbx & DisableCRT2Display)) {
   1452	   if(tempbx & DriverMode) {
   1453	      if(tempbx & SetSimuScanMode) {
   1454		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
   1455		    if(resinfo != SIS_RI_1600x1200) {
   1456		       tempbx |= SetInSlaveMode;
   1457		    }
   1458		 }
   1459	      }
   1460	   } else {
   1461	      tempbx |= SetInSlaveMode;
   1462	   }
   1463	}
   1464
   1465   }
   1466
   1467   SiS_Pr->SiS_VBInfo = tempbx;
   1468
   1469#ifdef CONFIG_FB_SIS_300
   1470   if(SiS_Pr->ChipType == SIS_630) {
   1471      SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
   1472   }
   1473#endif
   1474
   1475#if 0
   1476   printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
   1477      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
   1478#endif
   1479}
   1480
   1481/*********************************************/
   1482/*           DETERMINE YPbPr MODE            */
   1483/*********************************************/
   1484
   1485void
   1486SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
   1487{
   1488
   1489   unsigned char temp;
   1490
   1491   /* Note: This variable is only used on 30xLV systems.
   1492    * CR38 has a different meaning on LVDS/CH7019 systems.
   1493    * On 661 and later, these bits moved to CR35.
   1494    *
   1495    * On 301, 301B, only HiVision 1080i is supported.
   1496    * On 30xLV, 301C, only YPbPr 1080i is supported.
   1497    */
   1498
   1499   SiS_Pr->SiS_YPbPr = 0;
   1500   if(SiS_Pr->ChipType >= SIS_661) return;
   1501
   1502   if(SiS_Pr->SiS_VBType) {
   1503      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   1504	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
   1505      }
   1506   }
   1507
   1508   if(SiS_Pr->ChipType >= SIS_315H) {
   1509      if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
   1510	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
   1511	 if(temp & 0x08) {
   1512	    switch((temp >> 4)) {
   1513	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
   1514	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
   1515	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
   1516	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
   1517	    }
   1518	 }
   1519      }
   1520   }
   1521
   1522}
   1523
   1524/*********************************************/
   1525/*           DETERMINE TVMode flag           */
   1526/*********************************************/
   1527
   1528void
   1529SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   1530{
   1531   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   1532   unsigned short temp, temp1, resinfo = 0, romindex = 0;
   1533   unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
   1534
   1535   SiS_Pr->SiS_TVMode = 0;
   1536
   1537   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
   1538   if(SiS_Pr->UseCustomMode) return;
   1539
   1540   if(ModeNo > 0x13) {
   1541      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   1542   }
   1543
   1544   if(SiS_Pr->ChipType < SIS_661) {
   1545
   1546      if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;
   1547
   1548      if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1549	 temp = 0;
   1550	 if((SiS_Pr->ChipType == SIS_630) ||
   1551	    (SiS_Pr->ChipType == SIS_730)) {
   1552	    temp = 0x35;
   1553	    romindex = 0xfe;
   1554	 } else if(SiS_Pr->ChipType >= SIS_315H) {
   1555	    temp = 0x38;
   1556	    if(SiS_Pr->ChipType < XGI_20) {
   1557	       romindex = 0xf3;
   1558	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
   1559	    }
   1560	 }
   1561	 if(temp) {
   1562	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
   1563	       OutputSelect = ROMAddr[romindex];
   1564	       if(!(OutputSelect & EnablePALMN)) {
   1565		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
   1566	       }
   1567	    }
   1568	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
   1569	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   1570	       if(temp1 & EnablePALM) {		/* 0x40 */
   1571		  SiS_Pr->SiS_TVMode |= TVSetPALM;
   1572		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
   1573	       } else if(temp1 & EnablePALN) {	/* 0x80 */
   1574		  SiS_Pr->SiS_TVMode |= TVSetPALN;
   1575	       }
   1576	    } else {
   1577	       if(temp1 & EnableNTSCJ) {	/* 0x40 */
   1578		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
   1579	       }
   1580	    }
   1581	 }
   1582	 /* Translate HiVision/YPbPr to our new flags */
   1583	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   1584	    if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
   1585	    else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
   1586	    else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
   1587	    else				        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
   1588	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
   1589	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
   1590	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
   1591	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
   1592	       SiS_Pr->SiS_TVMode |= TVSetPAL;
   1593	    }
   1594	 }
   1595      } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   1596	 if(SiS_Pr->SiS_CHOverScan) {
   1597	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
   1598	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
   1599	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
   1600		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
   1601	       }
   1602	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   1603	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
   1604	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
   1605		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
   1606	       }
   1607	    }
   1608	    if(SiS_Pr->SiS_CHSOverScan) {
   1609	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
   1610	    }
   1611	 }
   1612	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   1613	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
   1614	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   1615	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
   1616	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
   1617	    } else {
   1618	       if(temp & EnableNTSCJ) {
   1619		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
   1620	       }
   1621	    }
   1622	 }
   1623      }
   1624
   1625   } else {  /* 661 and later */
   1626
   1627      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
   1628      if(temp1 & 0x01) {
   1629	 SiS_Pr->SiS_TVMode |= TVSetPAL;
   1630	 if(temp1 & 0x08) {
   1631	    SiS_Pr->SiS_TVMode |= TVSetPALN;
   1632	 } else if(temp1 & 0x04) {
   1633	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1634	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
   1635	    }
   1636	    SiS_Pr->SiS_TVMode |= TVSetPALM;
   1637	 }
   1638      } else {
   1639	 if(temp1 & 0x02) {
   1640	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
   1641	 }
   1642      }
   1643      if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   1644	 if(SiS_Pr->SiS_CHOverScan) {
   1645	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
   1646	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
   1647	    }
   1648	 }
   1649      }
   1650      if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1651	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   1652	    temp1 &= 0xe0;
   1653	    if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
   1654	    else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
   1655	    else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
   1656	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   1657	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
   1658	 }
   1659	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
   1660	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
   1661	       SiS_Pr->SiS_TVMode |= TVAspect169;
   1662	    } else {
   1663	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
   1664	       if(temp1 & 0x02) {
   1665		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
   1666		     SiS_Pr->SiS_TVMode |= TVAspect169;
   1667		  } else {
   1668		     SiS_Pr->SiS_TVMode |= TVAspect43LB;
   1669		  }
   1670	       } else {
   1671		  SiS_Pr->SiS_TVMode |= TVAspect43;
   1672	       }
   1673	    }
   1674	 }
   1675      }
   1676   }
   1677
   1678   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;
   1679
   1680   if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1681
   1682      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   1683	 SiS_Pr->SiS_TVMode |= TVSetPAL;
   1684	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
   1685      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   1686	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
   1687	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
   1688	 }
   1689      }
   1690
   1691      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   1692	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
   1693	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
   1694	 }
   1695      }
   1696
   1697      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
   1698	 if(resinfo == SIS_RI_1024x768) {
   1699	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
   1700	       SiS_Pr->SiS_TVMode |= TVSet525p1024;
   1701	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
   1702	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
   1703	    }
   1704	 }
   1705      }
   1706
   1707      SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
   1708      if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
   1709	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   1710	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
   1711      } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
   1712	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
   1713      } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
   1714	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
   1715	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
   1716	 }
   1717      }
   1718
   1719   }
   1720
   1721   SiS_Pr->SiS_VBInfo &= ~SetPALTV;
   1722}
   1723
   1724/*********************************************/
   1725/*               GET LCD INFO                */
   1726/*********************************************/
   1727
   1728static unsigned short
   1729SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
   1730{
   1731   unsigned short temp = SiS_Pr->SiS_LCDResInfo;
   1732   /* Translate my LCDResInfo to BIOS value */
   1733   switch(temp) {
   1734   case Panel_1280x768_2: temp = Panel_1280x768;    break;
   1735   case Panel_1280x800_2: temp = Panel_1280x800;    break;
   1736   case Panel_1280x854:   temp = Panel661_1280x854; break;
   1737   }
   1738   return temp;
   1739}
   1740
   1741static void
   1742SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
   1743{
   1744#ifdef CONFIG_FB_SIS_315
   1745   unsigned char  *ROMAddr;
   1746   unsigned short temp;
   1747
   1748   if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
   1749      if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
   1750	 SiS_Pr->SiS_NeedRomModeData = true;
   1751	 SiS_Pr->PanelHT  = temp;
   1752      }
   1753      if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
   1754	 SiS_Pr->SiS_NeedRomModeData = true;
   1755	 SiS_Pr->PanelVT  = temp;
   1756      }
   1757      SiS_Pr->PanelHRS = SISGETROMW(10);
   1758      SiS_Pr->PanelHRE = SISGETROMW(12);
   1759      SiS_Pr->PanelVRS = SISGETROMW(14);
   1760      SiS_Pr->PanelVRE = SISGETROMW(16);
   1761      SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
   1762      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
   1763	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
   1764      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
   1765	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
   1766      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
   1767	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
   1768
   1769   }
   1770#endif
   1771}
   1772
   1773static void
   1774SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
   1775			const unsigned char *nonscalingmodes)
   1776{
   1777   int i = 0;
   1778   while(nonscalingmodes[i] != 0xff) {
   1779      if(nonscalingmodes[i++] == resinfo) {
   1780	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
   1781	    (SiS_Pr->UsePanelScaler == -1)) {
   1782	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   1783	 }
   1784	 break;
   1785      }
   1786   }
   1787}
   1788
   1789void
   1790SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   1791{
   1792  unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
   1793  bool panelcanscale = false;
   1794#ifdef CONFIG_FB_SIS_300
   1795  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
   1796  static const unsigned char SiS300SeriesLCDRes[] =
   1797          { 0,  1,  2,  3,  7,  4,  5,  8,
   1798	    0,  0, 10,  0,  0,  0,  0, 15 };
   1799#endif
   1800#ifdef CONFIG_FB_SIS_315
   1801  unsigned char   *myptr = NULL;
   1802#endif
   1803
   1804  SiS_Pr->SiS_LCDResInfo  = 0;
   1805  SiS_Pr->SiS_LCDTypeInfo = 0;
   1806  SiS_Pr->SiS_LCDInfo     = 0;
   1807  SiS_Pr->PanelHRS        = 999; /* HSync start */
   1808  SiS_Pr->PanelHRE        = 999; /* HSync end */
   1809  SiS_Pr->PanelVRS        = 999; /* VSync start */
   1810  SiS_Pr->PanelVRE        = 999; /* VSync end */
   1811  SiS_Pr->SiS_NeedRomModeData = false;
   1812
   1813  /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
   1814  SiS_Pr->Alternate1600x1200 = false;
   1815
   1816  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
   1817
   1818  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
   1819
   1820  if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
   1821     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   1822     modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
   1823     modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
   1824  }
   1825
   1826  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
   1827
   1828  /* For broken BIOSes: Assume 1024x768 */
   1829  if(temp == 0) temp = 0x02;
   1830
   1831  if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
   1832     SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
   1833  } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
   1834     SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
   1835  } else {
   1836     SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
   1837  }
   1838  temp &= 0x0f;
   1839#ifdef CONFIG_FB_SIS_300
   1840  if(SiS_Pr->ChipType < SIS_315H) {
   1841     /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
   1842     if(SiS_Pr->SiS_VBType & VB_SIS301) {
   1843        if(temp < 0x0f) temp &= 0x07;
   1844     }
   1845     /* Translate 300 series LCDRes to 315 series for unified usage */
   1846     temp = SiS300SeriesLCDRes[temp];
   1847  }
   1848#endif
   1849
   1850  /* Translate to our internal types */
   1851#ifdef CONFIG_FB_SIS_315
   1852  if(SiS_Pr->ChipType == SIS_550) {
   1853     if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
   1854     else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
   1855     else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
   1856  } else if(SiS_Pr->ChipType >= SIS_661) {
   1857     if(temp == Panel661_1280x854)       temp = Panel_1280x854;
   1858  }
   1859#endif
   1860
   1861  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */
   1862     if(temp == Panel310_1280x768) {
   1863        temp = Panel_1280x768_2;
   1864     }
   1865     if(SiS_Pr->SiS_ROMNew) {
   1866	if(temp == Panel661_1280x800) {
   1867	   temp = Panel_1280x800_2;
   1868	}
   1869     }
   1870  }
   1871
   1872  SiS_Pr->SiS_LCDResInfo = temp;
   1873
   1874#ifdef CONFIG_FB_SIS_300
   1875  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   1876     if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
   1877	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
   1878     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
   1879	SiS_Pr->SiS_LCDResInfo = Panel_848x480;
   1880     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
   1881	SiS_Pr->SiS_LCDResInfo = Panel_856x480;
   1882     }
   1883  }
   1884#endif
   1885
   1886  if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1887     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
   1888	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
   1889  } else {
   1890     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
   1891	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
   1892  }
   1893
   1894  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
   1895  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
   1896  /* Need temp below! */
   1897
   1898  /* These must/can't scale no matter what */
   1899  switch(SiS_Pr->SiS_LCDResInfo) {
   1900  case Panel_320x240_1:
   1901  case Panel_320x240_2:
   1902  case Panel_320x240_3:
   1903  case Panel_1280x960:
   1904      SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
   1905      break;
   1906  case Panel_640x480:
   1907      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   1908  }
   1909
   1910  panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
   1911
   1912  if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
   1913  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   1914
   1915  /* Dual link, Pass 1:1 BIOS default, etc. */
   1916#ifdef CONFIG_FB_SIS_315
   1917  if(SiS_Pr->ChipType >= SIS_661) {
   1918     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   1919	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
   1920     }
   1921     if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
   1922	if(SiS_Pr->SiS_ROMNew) {
   1923	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
   1924	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
   1925	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
   1926	}
   1927     }
   1928  } else if(SiS_Pr->ChipType >= SIS_315H) {
   1929     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   1930	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
   1931     }
   1932     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
   1933	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
   1934	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
   1935	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
   1936	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
   1937	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
   1938	}
   1939     } else if(!(SiS_Pr->SiS_ROMNew)) {
   1940	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
   1941	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
   1942	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
   1943	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
   1944	   }
   1945	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
   1946	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
   1947	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
   1948	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
   1949	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
   1950	   }
   1951	}
   1952     }
   1953  }
   1954#endif
   1955
   1956  /* Pass 1:1 */
   1957  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
   1958     /* Always center screen on LVDS (if scaling is disabled) */
   1959     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   1960  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
   1961     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   1962	/* Always center screen on SiS LVDS (if scaling is disabled) */
   1963	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   1964     } else {
   1965	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
   1966	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
   1967	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   1968     }
   1969  }
   1970
   1971  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
   1972  SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
   1973
   1974  switch(SiS_Pr->SiS_LCDResInfo) {
   1975     case Panel_320x240_1:
   1976     case Panel_320x240_2:
   1977     case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
   1978			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
   1979			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
   1980			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
   1981			    break;
   1982     case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
   1983						      SiS_Pr->PanelVRE  =    3;
   1984			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
   1985			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
   1986			    break;
   1987     case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
   1988     			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
   1989			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
   1990			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
   1991			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
   1992			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
   1993			    break;
   1994     case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
   1995			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
   1996			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
   1997			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
   1998			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
   1999			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
   2000			    break;
   2001     case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
   2002			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
   2003			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
   2004			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
   2005			    if(SiS_Pr->ChipType < SIS_315H) {
   2006			       SiS_Pr->PanelHRS = 23;
   2007						      SiS_Pr->PanelVRE  =    5;
   2008			    }
   2009			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
   2010			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
   2011			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2012			    break;
   2013     case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
   2014			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
   2015			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
   2016			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
   2017			    if(SiS_Pr->ChipType < SIS_315H) {
   2018			       SiS_Pr->PanelHRS = 23;
   2019						      SiS_Pr->PanelVRE  =    5;
   2020			    }
   2021			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
   2022			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
   2023			    break;
   2024     case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
   2025			    break;
   2026     case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
   2027			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
   2028			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
   2029			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
   2030			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
   2031			    /* Data above for TMDS (projector); get from BIOS for LVDS */
   2032			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2033			    break;
   2034     case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
   2035			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   2036			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
   2037			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
   2038			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
   2039			    } else {
   2040			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
   2041			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
   2042			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
   2043			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
   2044			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
   2045			    }
   2046			    break;
   2047     case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
   2048			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
   2049			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
   2050			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
   2051			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
   2052			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2053			    break;
   2054     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
   2055			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
   2056			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
   2057			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
   2058			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
   2059			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2060			    break;
   2061     case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
   2062			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
   2063			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
   2064			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
   2065			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
   2066			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2067			    break;
   2068     case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
   2069			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
   2070			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
   2071			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
   2072			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
   2073			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2074			    break;
   2075     case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
   2076			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
   2077			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
   2078			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
   2079			    if(resinfo == SIS_RI_1280x1024) {
   2080			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
   2081			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
   2082			    }
   2083			    break;
   2084     case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
   2085			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
   2086			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
   2087			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
   2088			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
   2089			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
   2090			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2091			    break;
   2092     case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
   2093			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
   2094			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
   2095			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
   2096			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
   2097			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2098			    break;
   2099     case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
   2100			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
   2101			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
   2102			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
   2103			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
   2104			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
   2105			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   2106				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
   2107				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
   2108				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
   2109				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
   2110				  SiS_Pr->Alternate1600x1200 = true;
   2111			       }
   2112			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
   2113			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
   2114			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
   2115			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
   2116			    }
   2117			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2118			    break;
   2119     case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
   2120			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
   2121			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
   2122			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
   2123			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
   2124			    SiS_GetLCDInfoBIOS(SiS_Pr);
   2125			    break;
   2126     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
   2127			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
   2128			    break;
   2129     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
   2130			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
   2131			    break;
   2132     case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
   2133			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
   2134			    break;
   2135     case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
   2136			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
   2137			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
   2138			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
   2139			    if(SiS_Pr->CP_PreferredIndex != -1) {
   2140			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
   2141			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
   2142			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
   2143			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
   2144			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
   2145			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
   2146			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
   2147			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
   2148			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
   2149			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
   2150			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
   2151			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
   2152			       if(SiS_Pr->CP_PrefClock) {
   2153				  int idx;
   2154				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
   2155				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
   2156				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
   2157				  else				   idx = VCLK_CUSTOM_315;
   2158				  SiS_Pr->SiS_VCLKData[idx].CLOCK =
   2159				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
   2160				  SiS_Pr->SiS_VCLKData[idx].SR2B =
   2161				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
   2162				  SiS_Pr->SiS_VCLKData[idx].SR2C =
   2163				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
   2164			       }
   2165			    }
   2166			    break;
   2167     default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
   2168			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
   2169			    break;
   2170  }
   2171
   2172  /* Special cases */
   2173  if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
   2174      (SiS_Pr->SiS_IF_DEF_DSTN)              ||
   2175      (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
   2176      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
   2177      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
   2178      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
   2179     SiS_Pr->PanelHRS = 999;
   2180     SiS_Pr->PanelHRE = 999;
   2181  }
   2182
   2183  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
   2184      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
   2185      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
   2186      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
   2187     SiS_Pr->PanelVRS = 999;
   2188     SiS_Pr->PanelVRE = 999;
   2189  }
   2190
   2191  /* DontExpand overrule */
   2192  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
   2193
   2194     if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
   2195	/* No scaling for this mode on any panel (LCD=CRT2)*/
   2196	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2197     }
   2198
   2199     switch(SiS_Pr->SiS_LCDResInfo) {
   2200
   2201     case Panel_Custom:
   2202     case Panel_1152x864:
   2203     case Panel_1280x768:	/* TMDS only */
   2204	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2205	break;
   2206
   2207     case Panel_800x600: {
   2208	static const unsigned char nonscalingmodes[] = {
   2209	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
   2210	};
   2211	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2212	break;
   2213     }
   2214     case Panel_1024x768: {
   2215	static const unsigned char nonscalingmodes[] = {
   2216	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2217	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2218	   0xff
   2219	};
   2220	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2221	break;
   2222     }
   2223     case Panel_1280x720: {
   2224	static const unsigned char nonscalingmodes[] = {
   2225	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2226	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2227	   0xff
   2228	};
   2229	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2230	if(SiS_Pr->PanelHT == 1650) {
   2231	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2232	}
   2233	break;
   2234     }
   2235     case Panel_1280x768_2: {  /* LVDS only */
   2236	static const unsigned char nonscalingmodes[] = {
   2237	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2238	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2239	   SIS_RI_1152x768,0xff
   2240	};
   2241	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2242	switch(resinfo) {
   2243	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
   2244				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2245			       }
   2246			       break;
   2247	}
   2248	break;
   2249     }
   2250     case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
   2251	static const unsigned char nonscalingmodes[] = {
   2252	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2253	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2254	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
   2255	};
   2256	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2257	break;
   2258     }
   2259     case Panel_1280x800_2:  { 	/* SiS LVDS */
   2260	static const unsigned char nonscalingmodes[] = {
   2261	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2262	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2263	   SIS_RI_1152x768,0xff
   2264	};
   2265	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2266	switch(resinfo) {
   2267	case SIS_RI_1280x720:
   2268	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
   2269				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2270			       }
   2271			       break;
   2272	}
   2273	break;
   2274     }
   2275     case Panel_1280x854: {  	/* SiS LVDS */
   2276	static const unsigned char nonscalingmodes[] = {
   2277	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2278	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2279	   SIS_RI_1152x768,0xff
   2280	};
   2281	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2282	switch(resinfo) {
   2283	case SIS_RI_1280x720:
   2284	case SIS_RI_1280x768:
   2285	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
   2286				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2287			       }
   2288			       break;
   2289	}
   2290	break;
   2291     }
   2292     case Panel_1280x960: {
   2293	static const unsigned char nonscalingmodes[] = {
   2294	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2295	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2296	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
   2297	   SIS_RI_1280x854,0xff
   2298	};
   2299	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2300	break;
   2301     }
   2302     case Panel_1280x1024: {
   2303	static const unsigned char nonscalingmodes[] = {
   2304	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2305	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2306	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
   2307	   SIS_RI_1280x854,SIS_RI_1280x960,0xff
   2308	};
   2309	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2310	break;
   2311     }
   2312     case Panel_1400x1050: {
   2313	static const unsigned char nonscalingmodes[] = {
   2314	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2315	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2316	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
   2317	     SIS_RI_1280x960,0xff
   2318	};
   2319	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2320	switch(resinfo) {
   2321	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
   2322				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2323			       }
   2324			       break;
   2325	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   2326			       break;
   2327	}
   2328	break;
   2329     }
   2330     case Panel_1600x1200: {
   2331	static const unsigned char nonscalingmodes[] = {
   2332	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2333	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2334	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
   2335	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
   2336	};
   2337	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2338	break;
   2339     }
   2340     case Panel_1680x1050: {
   2341	static const unsigned char nonscalingmodes[] = {
   2342	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
   2343	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
   2344	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
   2345	     SIS_RI_1360x1024,0xff
   2346	};
   2347	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
   2348	break;
   2349     }
   2350     }
   2351  }
   2352
   2353#ifdef CONFIG_FB_SIS_300
   2354  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   2355     if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
   2356	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
   2357     }
   2358  }
   2359
   2360  if(SiS_Pr->ChipType < SIS_315H) {
   2361     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   2362	if(SiS_Pr->SiS_UseROM) {
   2363	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
   2364	      if(!(ROMAddr[0x235] & 0x02)) {
   2365		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
   2366	      }
   2367	   }
   2368	}
   2369     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   2370	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
   2371	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
   2372	}
   2373     }
   2374  }
   2375#endif
   2376
   2377  /* Special cases */
   2378
   2379  if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
   2380     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   2381  }
   2382
   2383  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
   2384     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   2385  }
   2386
   2387  switch(SiS_Pr->SiS_LCDResInfo) {
   2388  case Panel_640x480:
   2389     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   2390     break;
   2391  case Panel_1280x800:
   2392     /* Don't pass 1:1 by default (TMDS special) */
   2393     if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   2394     break;
   2395  case Panel_1280x960:
   2396     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   2397     break;
   2398  case Panel_Custom:
   2399     if((!SiS_Pr->CP_PrefClock) ||
   2400        (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
   2401        SiS_Pr->SiS_LCDInfo |= LCDPass11;
   2402     }
   2403     break;
   2404  }
   2405
   2406  if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
   2407     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
   2408  }
   2409
   2410  /* (In)validate LCDPass11 flag */
   2411  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
   2412     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   2413  }
   2414
   2415  /* LVDS DDA */
   2416  if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
   2417
   2418     if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
   2419	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
   2420	   if(ModeNo == 0x12) {
   2421	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
   2422		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
   2423	      }
   2424	   } else if(ModeNo > 0x13) {
   2425	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
   2426		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
   2427		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
   2428		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
   2429		    }
   2430		 }
   2431	      }
   2432	   }
   2433	}
   2434     }
   2435
   2436     if(modeflag & HalfDCLK) {
   2437	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
   2438	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
   2439	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   2440	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
   2441	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
   2442	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
   2443	} else if(ModeNo > 0x13) {
   2444	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   2445	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
   2446	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
   2447	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
   2448	   }
   2449	}
   2450     }
   2451
   2452  }
   2453
   2454  /* VESA timing */
   2455  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   2456     if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
   2457	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
   2458     }
   2459  } else {
   2460     SiS_Pr->SiS_SetFlag |= LCDVESATiming;
   2461  }
   2462
   2463#if 0
   2464  printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
   2465	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
   2466#endif
   2467}
   2468
   2469/*********************************************/
   2470/*                 GET VCLK                  */
   2471/*********************************************/
   2472
   2473unsigned short
   2474SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   2475		unsigned short RefreshRateTableIndex)
   2476{
   2477  unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
   2478  unsigned short resinfo, tempbx;
   2479  const unsigned char *CHTVVCLKPtr = NULL;
   2480
   2481  if(ModeNo <= 0x13) {
   2482     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   2483     CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   2484     VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
   2485     VCLKIndexGENCRT = VCLKIndexGEN;
   2486  } else {
   2487     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   2488     CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   2489     VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
   2490     VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
   2491		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
   2492  }
   2493
   2494  if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */
   2495
   2496     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
   2497
   2498	CRT2Index >>= 6;
   2499	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */
   2500
   2501	   if(SiS_Pr->ChipType < SIS_315H) {
   2502	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
   2503	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   2504		 VCLKIndex = VCLKIndexGEN;
   2505	      }
   2506	   } else {
   2507	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
   2508	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   2509		 switch(resinfo) {
   2510		 /* Correct those whose IndexGEN doesn't match VBVCLK array */
   2511		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
   2512		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
   2513		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
   2514		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
   2515		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
   2516		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
   2517		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
   2518		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
   2519		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
   2520		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
   2521		 default:              VCLKIndex = VCLKIndexGEN;
   2522		 }
   2523
   2524		 if(ModeNo <= 0x13) {
   2525		    if(SiS_Pr->ChipType <= SIS_315PRO) {
   2526		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
   2527		    } else {
   2528		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
   2529		    }
   2530		 }
   2531		 if(SiS_Pr->ChipType <= SIS_315PRO) {
   2532		    if(VCLKIndex == 0) VCLKIndex = 0x41;
   2533		    if(VCLKIndex == 1) VCLKIndex = 0x43;
   2534		    if(VCLKIndex == 4) VCLKIndex = 0x44;
   2535		 }
   2536	      }
   2537	   }
   2538
   2539	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */
   2540
   2541	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   2542	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;
   2543	      else                                  	   VCLKIndex = HiTVVCLK;
   2544	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
   2545	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
   2546	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
   2547	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
   2548	   else						   VCLKIndex = TVVCLK;
   2549
   2550	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
   2551	   else				   VCLKIndex += TVCLKBASE_315;
   2552
   2553	} else {							/* VGA2 */
   2554
   2555	   VCLKIndex = VCLKIndexGENCRT;
   2556	   if(SiS_Pr->ChipType < SIS_315H) {
   2557	      if(ModeNo > 0x13) {
   2558		 if( (SiS_Pr->ChipType == SIS_630) &&
   2559		     (SiS_Pr->ChipRevision >= 0x30)) {
   2560		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
   2561		 }
   2562		 /* Better VGA2 clock for 1280x1024@75 */
   2563		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
   2564	      }
   2565	   }
   2566	}
   2567
   2568     } else {   /* If not programming CRT2 */
   2569
   2570	VCLKIndex = VCLKIndexGENCRT;
   2571	if(SiS_Pr->ChipType < SIS_315H) {
   2572	   if(ModeNo > 0x13) {
   2573	      if( (SiS_Pr->ChipType != SIS_630) &&
   2574		  (SiS_Pr->ChipType != SIS_300) ) {
   2575		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
   2576	      }
   2577	   }
   2578	}
   2579     }
   2580
   2581  } else {       /*   LVDS  */
   2582
   2583     VCLKIndex = CRT2Index;
   2584
   2585     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
   2586
   2587	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
   2588
   2589	   VCLKIndex &= 0x1f;
   2590	   tempbx = 0;
   2591	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
   2592	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   2593	      tempbx += 2;
   2594	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
   2595		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
   2596	      }
   2597	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
   2598		 tempbx = 4;
   2599		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
   2600	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
   2601		 tempbx = 6;
   2602		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
   2603	      }
   2604	   }
   2605	   switch(tempbx) {
   2606	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
   2607	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
   2608	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
   2609	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
   2610	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
   2611	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
   2612	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
   2613	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
   2614	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
   2615	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
   2616	   }
   2617	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];
   2618
   2619	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   2620
   2621	   if(SiS_Pr->ChipType < SIS_315H) {
   2622	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
   2623	   } else {
   2624	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
   2625	   }
   2626
   2627#ifdef CONFIG_FB_SIS_300
   2628	   /* Special Timing: Barco iQ Pro R series */
   2629	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
   2630
   2631	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */
   2632	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
   2633	      if(SiS_Pr->ChipType < SIS_315H) {
   2634		 VCLKIndex = VCLK34_300;
   2635		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
   2636	      } else {
   2637		 VCLKIndex = VCLK34_315;
   2638		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
   2639	      }
   2640	   }
   2641#endif
   2642
   2643	} else {
   2644
   2645	   VCLKIndex = VCLKIndexGENCRT;
   2646	   if(SiS_Pr->ChipType < SIS_315H) {
   2647	      if(ModeNo > 0x13) {
   2648		 if( (SiS_Pr->ChipType == SIS_630) &&
   2649		     (SiS_Pr->ChipRevision >= 0x30) ) {
   2650		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
   2651		 }
   2652	      }
   2653	   }
   2654	}
   2655
   2656     } else {  /* if not programming CRT2 */
   2657
   2658	VCLKIndex = VCLKIndexGENCRT;
   2659	if(SiS_Pr->ChipType < SIS_315H) {
   2660	   if(ModeNo > 0x13) {
   2661	      if( (SiS_Pr->ChipType != SIS_630) &&
   2662		  (SiS_Pr->ChipType != SIS_300) ) {
   2663		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
   2664	      }
   2665#if 0
   2666	      if(SiS_Pr->ChipType == SIS_730) {
   2667		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
   2668		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
   2669	      }
   2670#endif
   2671	   }
   2672        }
   2673
   2674     }
   2675
   2676  }
   2677
   2678  return VCLKIndex;
   2679}
   2680
   2681/*********************************************/
   2682/*        SET CRT2 MODE TYPE REGISTERS       */
   2683/*********************************************/
   2684
   2685static void
   2686SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   2687{
   2688  unsigned short i, j, modeflag, tempah=0;
   2689  short tempcl;
   2690#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
   2691  unsigned short tempbl;
   2692#endif
   2693#ifdef CONFIG_FB_SIS_315
   2694  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   2695  unsigned short tempah2, tempbl2;
   2696#endif
   2697
   2698  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
   2699
   2700  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   2701
   2702     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
   2703     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
   2704
   2705  } else {
   2706
   2707     for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
   2708     if(SiS_Pr->ChipType >= SIS_315H) {
   2709        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
   2710     }
   2711
   2712     tempcl = SiS_Pr->SiS_ModeType;
   2713
   2714     if(SiS_Pr->ChipType < SIS_315H) {
   2715
   2716#ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */
   2717
   2718	/* For 301BDH: (with LCD via LVDS) */
   2719	if(SiS_Pr->SiS_VBType & VB_NoLCD) {
   2720	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
   2721	   tempbl &= 0xef;
   2722	   tempbl |= 0x02;
   2723	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
   2724	      tempbl |= 0x10;
   2725	      tempbl &= 0xfd;
   2726	   }
   2727	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
   2728	}
   2729
   2730	if(ModeNo > 0x13) {
   2731	   tempcl -= ModeVGA;
   2732	   if(tempcl >= 0) {
   2733	      tempah = ((0x10 >> tempcl) | 0x80);
   2734	   }
   2735	} else tempah = 0x80;
   2736
   2737	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
   2738
   2739#endif  /* CONFIG_FB_SIS_300 */
   2740
   2741     } else {
   2742
   2743#ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */
   2744
   2745	if(ModeNo > 0x13) {
   2746	   tempcl -= ModeVGA;
   2747	   if(tempcl >= 0) {
   2748	      tempah = (0x08 >> tempcl);
   2749	      if (tempah == 0) tempah = 1;
   2750	      tempah |= 0x40;
   2751	   }
   2752	} else tempah = 0x40;
   2753
   2754	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
   2755
   2756#endif  /* CONFIG_FB_SIS_315 */
   2757
   2758     }
   2759
   2760     if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
   2761
   2762     if(SiS_Pr->ChipType < SIS_315H) {
   2763	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
   2764     } else {
   2765#ifdef CONFIG_FB_SIS_315
   2766	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   2767	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
   2768	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
   2769	   if(IS_SIS740) {
   2770	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
   2771	   } else {
   2772	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
   2773	   }
   2774	}
   2775#endif
   2776     }
   2777
   2778     if(SiS_Pr->SiS_VBType & VB_SISVB) {
   2779
   2780	tempah = 0x01;
   2781	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   2782	   tempah |= 0x02;
   2783	}
   2784	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
   2785	   tempah ^= 0x05;
   2786	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
   2787	      tempah ^= 0x01;
   2788	   }
   2789	}
   2790
   2791	if(SiS_Pr->ChipType < SIS_315H) {
   2792
   2793	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
   2794
   2795	   tempah = (tempah << 5) & 0xFF;
   2796	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
   2797	   tempah = (tempah >> 5) & 0xFF;
   2798
   2799	} else {
   2800
   2801	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
   2802	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
   2803	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
   2804	   tempah &= ~0x08;
   2805
   2806	}
   2807
   2808	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
   2809	   tempah |= 0x10;
   2810	}
   2811
   2812	tempah |= 0x80;
   2813	if(SiS_Pr->SiS_VBType & VB_SIS301) {
   2814	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
   2815	}
   2816
   2817	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   2818	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
   2819	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   2820		 tempah |= 0x20;
   2821	      }
   2822	   }
   2823	}
   2824
   2825	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
   2826
   2827	tempah = 0x80;
   2828	if(SiS_Pr->SiS_VBType & VB_SIS301) {
   2829	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
   2830	}
   2831
   2832	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;
   2833
   2834	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   2835	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
   2836	      tempah |= 0x40;
   2837	   }
   2838	}
   2839
   2840	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
   2841
   2842     } else {  /* LVDS */
   2843
   2844	if(SiS_Pr->ChipType >= SIS_315H) {
   2845
   2846#ifdef CONFIG_FB_SIS_315
   2847	   /* LVDS can only be slave in 8bpp modes */
   2848	   tempah = 0x80;
   2849	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
   2850	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
   2851	         tempah |= 0x02;
   2852	      }
   2853	   }
   2854
   2855	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;
   2856
   2857	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;
   2858
   2859	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;
   2860
   2861	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
   2862#endif
   2863
   2864	} else {
   2865
   2866#ifdef CONFIG_FB_SIS_300
   2867	   tempah = 0;
   2868	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
   2869	      tempah |= 0x02;
   2870	   }
   2871	   tempah <<= 5;
   2872
   2873	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;
   2874
   2875	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
   2876#endif
   2877
   2878	}
   2879
   2880     }
   2881
   2882  }  /* LCDA */
   2883
   2884  if(SiS_Pr->SiS_VBType & VB_SISVB) {
   2885
   2886     if(SiS_Pr->ChipType >= SIS_315H) {
   2887
   2888#ifdef CONFIG_FB_SIS_315
   2889	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
   2890
   2891	/* The following is nearly unpreditable and varies from machine
   2892	 * to machine. Especially the 301DH seems to be a real trouble
   2893	 * maker. Some BIOSes simply set the registers (like in the
   2894	 * NoLCD-if-statements here), some set them according to the
   2895	 * LCDA stuff. It is very likely that some machines are not
   2896	 * treated correctly in the following, very case-orientated
   2897	 * code. What do I do then...?
   2898	 */
   2899
   2900	/* 740 variants match for 30xB, 301B-DH, 30xLV */
   2901
   2902	if(!(IS_SIS740)) {
   2903	   tempah = 0x04;						   /* For all bridges */
   2904	   tempbl = 0xfb;
   2905	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   2906	      tempah = 0x00;
   2907	      if(SiS_IsDualEdge(SiS_Pr)) {
   2908	         tempbl = 0xff;
   2909	      }
   2910	   }
   2911	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
   2912	}
   2913
   2914	/* The following two are responsible for eventually wrong colors
   2915	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
   2916	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
   2917	 * in a 650 box (Jake). What is the criteria?
   2918	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
   2919	 * treatment like the 651+301B-DH(b0) case. Seems more to be the
   2920	 * chipset than the bridge revision.
   2921	 */
   2922
   2923	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
   2924	   tempah = 0x30;
   2925	   tempbl = 0xc0;
   2926	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
   2927	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
   2928	      tempah = 0x00;
   2929	      tempbl = 0x00;
   2930	   }
   2931	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
   2932	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
   2933	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
   2934	   /* Fixes "TV-blue-bug" on 315+301 */
   2935	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */
   2936	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
   2937	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   2938	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */
   2939	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
   2940	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */
   2941	   tempah = 0x30; tempah2 = 0xc0;
   2942	   tempbl = 0xcf; tempbl2 = 0x3f;
   2943	   if(SiS_Pr->SiS_TVBlue == 0) {
   2944	         tempah = tempah2 = 0x00;
   2945	   } else if(SiS_Pr->SiS_TVBlue == -1) {
   2946	      /* Set on 651/M650, clear on 315/650 */
   2947	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
   2948	         tempah = tempah2 = 0x00;
   2949	      }
   2950	   }
   2951	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
   2952	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
   2953	} else {
   2954	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */
   2955	   tempbl = 0xcf; tempbl2 = 0x3f;
   2956	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   2957	      tempah = tempah2 = 0x00;
   2958	      if(SiS_IsDualEdge(SiS_Pr)) {
   2959		 tempbl = tempbl2 = 0xff;
   2960	      }
   2961	   }
   2962	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
   2963	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
   2964	}
   2965
   2966	if(IS_SIS740) {
   2967	   tempah = 0x80;
   2968	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
   2969	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
   2970	} else {
   2971	   tempah = 0x00;
   2972	   tempbl = 0x7f;
   2973	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   2974	      tempbl = 0xff;
   2975	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
   2976	   }
   2977	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
   2978	}
   2979
   2980#endif /* CONFIG_FB_SIS_315 */
   2981
   2982     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   2983
   2984#ifdef CONFIG_FB_SIS_300
   2985	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
   2986
   2987	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
   2988	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
   2989	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
   2990	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
   2991	} else {
   2992	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
   2993	}
   2994#endif
   2995
   2996     }
   2997
   2998     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   2999	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
   3000	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
   3001	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
   3002        }
   3003     }
   3004
   3005  } else {  /* LVDS */
   3006
   3007#ifdef CONFIG_FB_SIS_315
   3008     if(SiS_Pr->ChipType >= SIS_315H) {
   3009
   3010	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   3011
   3012	   tempah = 0x04;
   3013	   tempbl = 0xfb;
   3014	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   3015	      tempah = 0x00;
   3016	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
   3017	   }
   3018	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
   3019
   3020	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
   3021	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
   3022	   }
   3023
   3024	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
   3025
   3026	} else if(SiS_Pr->ChipType == SIS_550) {
   3027
   3028	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
   3029	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);
   3030
   3031	}
   3032
   3033     }
   3034#endif
   3035
   3036  }
   3037
   3038}
   3039
   3040/*********************************************/
   3041/*            GET RESOLUTION DATA            */
   3042/*********************************************/
   3043
   3044unsigned short
   3045SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   3046{
   3047   if(ModeNo <= 0x13)
   3048      return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
   3049   else
   3050      return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
   3051}
   3052
   3053static void
   3054SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   3055{
   3056   unsigned short xres, yres, modeflag=0, resindex;
   3057
   3058   if(SiS_Pr->UseCustomMode) {
   3059      xres = SiS_Pr->CHDisplay;
   3060      if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
   3061      SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
   3062      /* DoubleScanMode-check done in CheckCalcCustomMode()! */
   3063      SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
   3064      return;
   3065   }
   3066
   3067   resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
   3068
   3069   if(ModeNo <= 0x13) {
   3070      xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
   3071      yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
   3072   } else {
   3073      xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
   3074      yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
   3075      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   3076   }
   3077
   3078   if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
   3079
   3080      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
   3081	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
   3082	    if(yres == 350) yres = 400;
   3083	 }
   3084	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
   3085	    if(ModeNo == 0x12) yres = 400;
   3086	 }
   3087      }
   3088
   3089      if(modeflag & HalfDCLK)       xres <<= 1;
   3090      if(modeflag & DoubleScanMode) yres <<= 1;
   3091
   3092   }
   3093
   3094   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
   3095
   3096      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   3097	 switch(SiS_Pr->SiS_LCDResInfo) {
   3098	   case Panel_1024x768:
   3099	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
   3100		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
   3101		    if(yres == 350) yres = 357;
   3102		    if(yres == 400) yres = 420;
   3103		    if(yres == 480) yres = 525;
   3104		 }
   3105	      }
   3106	      break;
   3107	   case Panel_1280x1024:
   3108	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
   3109		 /* BIOS bug - does this regardless of scaling */
   3110		 if(yres == 400) yres = 405;
   3111	      }
   3112	      if(yres == 350) yres = 360;
   3113	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
   3114		 if(yres == 360) yres = 375;
   3115	      }
   3116	      break;
   3117	   case Panel_1600x1200:
   3118	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
   3119		 if(yres == 1024) yres = 1056;
   3120	      }
   3121	      break;
   3122	 }
   3123      }
   3124
   3125   } else {
   3126
   3127      if(SiS_Pr->SiS_VBType & VB_SISVB) {
   3128	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
   3129	    if(xres == 720) xres = 640;
   3130	 }
   3131      } else if(xres == 720) xres = 640;
   3132
   3133      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
   3134	 yres = 400;
   3135	 if(SiS_Pr->ChipType >= SIS_315H) {
   3136	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
   3137	 } else {
   3138	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
   3139	 }
   3140	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
   3141      }
   3142
   3143   }
   3144   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
   3145   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
   3146}
   3147
   3148/*********************************************/
   3149/*           GET CRT2 TIMING DATA            */
   3150/*********************************************/
   3151
   3152static void
   3153SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   3154	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
   3155	       unsigned short *ResIndex)
   3156{
   3157  unsigned short tempbx=0, tempal=0, resinfo=0;
   3158
   3159  if(ModeNo <= 0x13) {
   3160     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   3161  } else {
   3162     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   3163     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   3164  }
   3165
   3166  if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {
   3167
   3168     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
   3169
   3170	tempbx = SiS_Pr->SiS_LCDResInfo;
   3171	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
   3172
   3173	/* patch index */
   3174	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
   3175	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
   3176	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
   3177	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
   3178		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
   3179		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
   3180	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
   3181	}
   3182
   3183	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   3184	   /* Pass 1:1 only (center-screen handled outside) */
   3185	   /* This is never called for the panel's native resolution */
   3186	   /* since Pass1:1 will not be set in this case */
   3187	   tempbx = 100;
   3188	   if(ModeNo >= 0x13) {
   3189	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
   3190	   }
   3191	}
   3192
   3193#ifdef CONFIG_FB_SIS_315
   3194	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
   3195	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
   3196	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
   3197		 tempbx = 200;
   3198		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
   3199	      }
   3200	   }
   3201	}
   3202#endif
   3203
   3204     } else {						  	/* TV */
   3205
   3206	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   3207	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
   3208	   tempbx = 2;
   3209	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   3210	      tempbx = 13;
   3211	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
   3212	   }
   3213	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   3214	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;
   3215	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;
   3216	   else						tempbx = 5;
   3217	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
   3218	} else {
   3219	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;
   3220	   else						tempbx = 4;
   3221	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
   3222	}
   3223
   3224     }
   3225
   3226     tempal &= 0x3F;
   3227
   3228     if(ModeNo > 0x13) {
   3229        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
   3230	   switch(resinfo) {
   3231	   case SIS_RI_720x480:
   3232	      tempal = 6;
   3233	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))	tempal = 9;
   3234	      break;
   3235	   case SIS_RI_720x576:
   3236	   case SIS_RI_768x576:
   3237	   case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
   3238	      tempal = 6;
   3239	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   3240		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 8;
   3241	      }
   3242	      break;
   3243	   case SIS_RI_800x480:
   3244	      tempal = 4;
   3245	      break;
   3246	   case SIS_RI_512x384:
   3247	   case SIS_RI_1024x768:
   3248	      tempal = 7;
   3249	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   3250		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempal = 8;
   3251	      }
   3252	      break;
   3253	   case SIS_RI_1280x720:
   3254	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   3255		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 9;
   3256	      }
   3257	      break;
   3258	   }
   3259	}
   3260     }
   3261
   3262     *CRT2Index = tempbx;
   3263     *ResIndex = tempal;
   3264
   3265  } else {   /* LVDS, 301B-DH (if running on LCD) */
   3266
   3267     tempbx = 0;
   3268     if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
   3269
   3270	tempbx = 90;
   3271	if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   3272	   tempbx = 92;
   3273	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
   3274	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
   3275	   }
   3276	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
   3277	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
   3278	}
   3279	if(tempbx != 99) {
   3280	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
   3281	}
   3282
   3283     } else {
   3284
   3285	switch(SiS_Pr->SiS_LCDResInfo) {
   3286	case Panel_640x480:   tempbx = 12; break;
   3287	case Panel_320x240_1: tempbx = 10; break;
   3288	case Panel_320x240_2:
   3289	case Panel_320x240_3: tempbx = 14; break;
   3290	case Panel_800x600:   tempbx = 16; break;
   3291	case Panel_1024x600:  tempbx = 18; break;
   3292	case Panel_1152x768:
   3293	case Panel_1024x768:  tempbx = 20; break;
   3294	case Panel_1280x768:  tempbx = 22; break;
   3295	case Panel_1280x1024: tempbx = 24; break;
   3296	case Panel_1400x1050: tempbx = 26; break;
   3297	case Panel_1600x1200: tempbx = 28; break;
   3298#ifdef CONFIG_FB_SIS_300
   3299	case Panel_Barco1366: tempbx = 80; break;
   3300#endif
   3301	}
   3302
   3303	switch(SiS_Pr->SiS_LCDResInfo) {
   3304	case Panel_320x240_1:
   3305	case Panel_320x240_2:
   3306	case Panel_320x240_3:
   3307	case Panel_640x480:
   3308	   break;
   3309	default:
   3310	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
   3311	}
   3312
   3313	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
   3314
   3315#ifdef CONFIG_FB_SIS_300
   3316	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
   3317	   tempbx = 82;
   3318	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
   3319	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
   3320	   tempbx = 84;
   3321	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
   3322	}
   3323#endif
   3324
   3325     }
   3326
   3327     (*CRT2Index) = tempbx;
   3328     (*ResIndex) = tempal & 0x1F;
   3329  }
   3330}
   3331
   3332static void
   3333SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   3334		unsigned short RefreshRateTableIndex)
   3335{
   3336  unsigned short tempax=0, tempbx=0, index, dotclock;
   3337  unsigned short temp1=0, modeflag=0, tempcx=0;
   3338
   3339  SiS_Pr->SiS_RVBHCMAX  = 1;
   3340  SiS_Pr->SiS_RVBHCFACT = 1;
   3341
   3342  if(ModeNo <= 0x13) {
   3343
   3344     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   3345     index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
   3346
   3347     tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
   3348     tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
   3349     temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
   3350
   3351     dotclock = (modeflag & Charx8Dot) ? 8 : 9;
   3352
   3353  } else {
   3354
   3355     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   3356     index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
   3357
   3358     tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
   3359     tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
   3360     tempax &= 0x03FF;
   3361     tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
   3362     tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
   3363     tempcx &= 0x0100;
   3364     tempcx <<= 2;
   3365     tempbx |= tempcx;
   3366     temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
   3367
   3368     dotclock = 8;
   3369
   3370  }
   3371
   3372  if(temp1 & 0x01) tempbx |= 0x0100;
   3373  if(temp1 & 0x20) tempbx |= 0x0200;
   3374
   3375  tempax += 5;
   3376  tempax *= dotclock;
   3377  if(modeflag & HalfDCLK) tempax <<= 1;
   3378
   3379  tempbx++;
   3380
   3381  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
   3382  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
   3383}
   3384
   3385static void
   3386SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
   3387		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
   3388{
   3389   unsigned short ResIndex;
   3390
   3391   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   3392      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
   3393	 if(SiS_Pr->UseCustomMode) {
   3394	    ResIndex = SiS_Pr->CHTotal;
   3395	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
   3396	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
   3397	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
   3398	 } else {
   3399	    if(ModeNo < 0x13) {
   3400	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   3401	    } else {
   3402	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
   3403	    }
   3404	    if(ResIndex == 0x09) {
   3405	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
   3406	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
   3407	    }
   3408	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
   3409	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
   3410	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
   3411	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
   3412	 }
   3413      } else {
   3414	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
   3415	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
   3416      }
   3417   } else {
   3418      /* This handles custom modes and custom panels */
   3419      SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
   3420      SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
   3421      SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
   3422      SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
   3423      SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
   3424      SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
   3425   }
   3426}
   3427
   3428static void
   3429SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   3430                    unsigned short RefreshRateTableIndex)
   3431{
   3432   unsigned short CRT2Index, ResIndex, backup;
   3433   const struct SiS_LVDSData *LVDSData = NULL;
   3434
   3435   SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);
   3436
   3437   if(SiS_Pr->SiS_VBType & VB_SISVB) {
   3438      SiS_Pr->SiS_RVBHCMAX  = 1;
   3439      SiS_Pr->SiS_RVBHCFACT = 1;
   3440      SiS_Pr->SiS_NewFlickerMode = 0;
   3441      SiS_Pr->SiS_RVBHRS = 50;
   3442      SiS_Pr->SiS_RY1COE = 0;
   3443      SiS_Pr->SiS_RY2COE = 0;
   3444      SiS_Pr->SiS_RY3COE = 0;
   3445      SiS_Pr->SiS_RY4COE = 0;
   3446      SiS_Pr->SiS_RVBHRS2 = 0;
   3447   }
   3448
   3449   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   3450
   3451#ifdef CONFIG_FB_SIS_315
   3452      SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   3453      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
   3454#endif
   3455
   3456   } else {
   3457
   3458      /* 301BDH needs LVDS Data */
   3459      backup = SiS_Pr->SiS_IF_DEF_LVDS;
   3460      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
   3461	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
   3462      }
   3463
   3464      SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
   3465                     		            &CRT2Index, &ResIndex);
   3466
   3467      SiS_Pr->SiS_IF_DEF_LVDS = backup;
   3468
   3469      switch(CRT2Index) {
   3470	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
   3471	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
   3472	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
   3473	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
   3474	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
   3475	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
   3476#ifdef CONFIG_FB_SIS_300
   3477	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
   3478	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
   3479	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
   3480	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
   3481	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
   3482#endif
   3483	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
   3484	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
   3485	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
   3486	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
   3487	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
   3488	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
   3489	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
   3490	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
   3491	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;
   3492      }
   3493
   3494      if(LVDSData) {
   3495	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
   3496	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
   3497	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
   3498	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
   3499      } else {
   3500	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   3501      }
   3502
   3503      if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
   3504	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
   3505	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
   3506	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
   3507	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
   3508	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
   3509            SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
   3510#ifdef CONFIG_FB_SIS_300
   3511	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
   3512	       if(ResIndex < 0x08) {
   3513		  SiS_Pr->SiS_HDE = 1280;
   3514		  SiS_Pr->SiS_VDE = 1024;
   3515	       }
   3516	    }
   3517#endif
   3518         }
   3519      }
   3520   }
   3521}
   3522
   3523static void
   3524SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   3525		unsigned short RefreshRateTableIndex)
   3526{
   3527  unsigned char  *ROMAddr = NULL;
   3528  unsigned short tempax, tempbx, modeflag, romptr=0;
   3529  unsigned short resinfo, CRT2Index, ResIndex;
   3530  const struct SiS_LCDData *LCDPtr = NULL;
   3531  const struct SiS_TVData  *TVPtr  = NULL;
   3532#ifdef CONFIG_FB_SIS_315
   3533  short resinfo661;
   3534#endif
   3535
   3536  if(ModeNo <= 0x13) {
   3537     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   3538     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   3539  } else if(SiS_Pr->UseCustomMode) {
   3540     modeflag = SiS_Pr->CModeFlag;
   3541     resinfo = 0;
   3542  } else {
   3543     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   3544     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   3545#ifdef CONFIG_FB_SIS_315
   3546     resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
   3547     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
   3548	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
   3549	 (resinfo661 >= 0)                     &&
   3550	 (SiS_Pr->SiS_NeedRomModeData) ) {
   3551	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
   3552	   if((romptr = (SISGETROMW(21)))) {
   3553	      romptr += (resinfo661 * 10);
   3554	      ROMAddr = SiS_Pr->VirtualRomBase;
   3555	   }
   3556	}
   3557     }
   3558#endif
   3559  }
   3560
   3561  SiS_Pr->SiS_NewFlickerMode = 0;
   3562  SiS_Pr->SiS_RVBHRS = 50;
   3563  SiS_Pr->SiS_RY1COE = 0;
   3564  SiS_Pr->SiS_RY2COE = 0;
   3565  SiS_Pr->SiS_RY3COE = 0;
   3566  SiS_Pr->SiS_RY4COE = 0;
   3567  SiS_Pr->SiS_RVBHRS2 = 0;
   3568
   3569  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);
   3570
   3571  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
   3572
   3573     if(SiS_Pr->UseCustomMode) {
   3574
   3575	SiS_Pr->SiS_RVBHCMAX  = 1;
   3576	SiS_Pr->SiS_RVBHCFACT = 1;
   3577	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
   3578	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
   3579
   3580	tempax = SiS_Pr->CHTotal;
   3581	if(modeflag & HalfDCLK) tempax <<= 1;
   3582	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
   3583	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
   3584
   3585     } else {
   3586
   3587	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   3588
   3589     }
   3590
   3591  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   3592
   3593     SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
   3594		    &CRT2Index,&ResIndex);
   3595
   3596     switch(CRT2Index) {
   3597	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
   3598	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
   3599	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
   3600	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
   3601	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
   3602	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
   3603	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
   3604	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
   3605	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
   3606	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
   3607	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
   3608	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
   3609	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
   3610	default: TVPtr = SiS_Pr->SiS_StPALData;     break;
   3611     }
   3612
   3613     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
   3614     SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
   3615     SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
   3616     SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
   3617     SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
   3618     SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
   3619     SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
   3620     if(modeflag & HalfDCLK) {
   3621	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
   3622	if(SiS_Pr->SiS_RVBHRS2) {
   3623	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
   3624	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
   3625	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
   3626	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
   3627	}
   3628     } else {
   3629	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
   3630     }
   3631     SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;
   3632
   3633     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   3634
   3635	if((resinfo == SIS_RI_960x600)   ||
   3636	   (resinfo == SIS_RI_1024x768)  ||
   3637	   (resinfo == SIS_RI_1280x1024) ||
   3638	   (resinfo == SIS_RI_1280x720)) {
   3639	   SiS_Pr->SiS_NewFlickerMode = 0x40;
   3640	}
   3641
   3642	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
   3643
   3644	SiS_Pr->SiS_HT = ExtHiTVHT;
   3645	SiS_Pr->SiS_VT = ExtHiTVVT;
   3646	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   3647	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
   3648	      SiS_Pr->SiS_HT = StHiTVHT;
   3649	      SiS_Pr->SiS_VT = StHiTVVT;
   3650	   }
   3651	}
   3652
   3653     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   3654
   3655	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
   3656	   SiS_Pr->SiS_HT = 1650;
   3657	   SiS_Pr->SiS_VT = 750;
   3658	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
   3659	   SiS_Pr->SiS_HT = NTSCHT;
   3660	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
   3661	   SiS_Pr->SiS_VT = NTSCVT;
   3662	} else {
   3663	   SiS_Pr->SiS_HT = NTSCHT;
   3664	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
   3665	   SiS_Pr->SiS_VT = NTSCVT;
   3666	}
   3667
   3668     } else {
   3669
   3670	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
   3671	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
   3672	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
   3673	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
   3674
   3675	if(modeflag & HalfDCLK) {
   3676	   SiS_Pr->SiS_RY1COE = 0x00;
   3677	   SiS_Pr->SiS_RY2COE = 0xf4;
   3678	   SiS_Pr->SiS_RY3COE = 0x10;
   3679	   SiS_Pr->SiS_RY4COE = 0x38;
   3680	}
   3681
   3682	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
   3683	   SiS_Pr->SiS_HT = NTSCHT;
   3684	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
   3685	   SiS_Pr->SiS_VT = NTSCVT;
   3686	} else {
   3687	   SiS_Pr->SiS_HT = PALHT;
   3688	   SiS_Pr->SiS_VT = PALVT;
   3689	}
   3690
   3691     }
   3692
   3693  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   3694
   3695     SiS_Pr->SiS_RVBHCMAX  = 1;
   3696     SiS_Pr->SiS_RVBHCFACT = 1;
   3697
   3698     if(SiS_Pr->UseCustomMode) {
   3699
   3700	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
   3701	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;
   3702
   3703	tempax = SiS_Pr->CHTotal;
   3704	if(modeflag & HalfDCLK) tempax <<= 1;
   3705	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
   3706	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
   3707
   3708     } else {
   3709
   3710	bool gotit = false;
   3711
   3712	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
   3713
   3714	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
   3715	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
   3716	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
   3717	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
   3718	   gotit = true;
   3719
   3720	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
   3721
   3722#ifdef CONFIG_FB_SIS_315
   3723	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
   3724	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
   3725	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
   3726	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
   3727	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
   3728	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
   3729	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
   3730	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
   3731	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
   3732	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
   3733	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
   3734	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;
   3735	   }
   3736	   if(SiS_Pr->SiS_VGAHT) gotit = true;
   3737	   else {
   3738	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
   3739	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
   3740	      SiS_Pr->SiS_RVBHCMAX  = 1;
   3741	      SiS_Pr->SiS_RVBHCFACT = 1;
   3742	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
   3743	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
   3744	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
   3745	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
   3746	      SiS_Pr->SiS_RVBHRS2 = 0;
   3747	      gotit = true;
   3748	   }
   3749#endif
   3750
   3751	}
   3752
   3753	if(!gotit) {
   3754
   3755	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
   3756			  &CRT2Index,&ResIndex);
   3757
   3758	   switch(CRT2Index) {
   3759	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
   3760	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
   3761	      case Panel_1280x720      :
   3762	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
   3763	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
   3764	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
   3765	      case Panel_1280x800      :
   3766	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
   3767	      case Panel_1280x800_2    :
   3768	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
   3769	      case Panel_1280x854      :
   3770	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
   3771	      case Panel_1280x960      :
   3772	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
   3773	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
   3774	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
   3775	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
   3776	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
   3777	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
   3778	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
   3779	      case Panel_1680x1050     :
   3780	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
   3781	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
   3782#ifdef CONFIG_FB_SIS_315
   3783	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
   3784	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
   3785#endif
   3786	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
   3787	   }
   3788
   3789	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
   3790	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
   3791	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
   3792	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
   3793	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
   3794	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
   3795
   3796        }
   3797
   3798	tempax = SiS_Pr->PanelXRes;
   3799	tempbx = SiS_Pr->PanelYRes;
   3800
   3801	switch(SiS_Pr->SiS_LCDResInfo) {
   3802	case Panel_1024x768:
   3803	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
   3804	      if(SiS_Pr->ChipType < SIS_315H) {
   3805		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
   3806		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
   3807	      }
   3808	   } else {
   3809	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
   3810	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
   3811	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
   3812	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
   3813	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
   3814	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
   3815	   }
   3816	   break;
   3817	case Panel_1280x960:
   3818	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
   3819	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
   3820	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
   3821	   break;
   3822	case Panel_1280x1024:
   3823	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
   3824	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
   3825	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
   3826	   break;
   3827	case Panel_1600x1200:
   3828	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
   3829	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
   3830	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
   3831	   }
   3832	   break;
   3833	}
   3834
   3835	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   3836	   tempax = SiS_Pr->SiS_VGAHDE;
   3837	   tempbx = SiS_Pr->SiS_VGAVDE;
   3838	}
   3839
   3840	SiS_Pr->SiS_HDE = tempax;
   3841	SiS_Pr->SiS_VDE = tempbx;
   3842     }
   3843  }
   3844}
   3845
   3846static void
   3847SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   3848                unsigned short RefreshRateTableIndex)
   3849{
   3850
   3851   if(SiS_Pr->SiS_VBType & VB_SISVB) {
   3852
   3853      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   3854         SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   3855      } else {
   3856	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
   3857	    /* Need LVDS Data for LCD on 301B-DH */
   3858	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   3859	 } else {
   3860	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   3861	 }
   3862      }
   3863
   3864   } else {
   3865
   3866      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   3867
   3868   }
   3869}
   3870
   3871/*********************************************/
   3872/*         GET LVDS DES (SKEW) DATA          */
   3873/*********************************************/
   3874
   3875static const struct SiS_LVDSDes *
   3876SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
   3877{
   3878   const struct SiS_LVDSDes *PanelDesPtr = NULL;
   3879
   3880#ifdef CONFIG_FB_SIS_300
   3881   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   3882
   3883      if(SiS_Pr->ChipType < SIS_315H) {
   3884	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
   3885	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
   3886	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
   3887	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   3888		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
   3889	       }
   3890            } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
   3891	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
   3892	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   3893		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
   3894	       }
   3895	    }
   3896	 }
   3897      }
   3898   }
   3899#endif
   3900   return PanelDesPtr;
   3901}
   3902
   3903static void
   3904SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   3905                   unsigned short RefreshRateTableIndex)
   3906{
   3907  unsigned short modeflag, ResIndex;
   3908  const struct SiS_LVDSDes *PanelDesPtr = NULL;
   3909
   3910  SiS_Pr->SiS_LCDHDES = 0;
   3911  SiS_Pr->SiS_LCDVDES = 0;
   3912
   3913  /* Some special cases */
   3914  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   3915
   3916     /* Trumpion */
   3917     if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
   3918	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   3919	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
   3920	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   3921	   }
   3922	}
   3923	return;
   3924     }
   3925
   3926     /* 640x480 on LVDS */
   3927     if(SiS_Pr->ChipType < SIS_315H) {
   3928	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
   3929	   SiS_Pr->SiS_LCDHDES = 8;
   3930	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
   3931	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
   3932	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
   3933	   return;
   3934	}
   3935     }
   3936
   3937  } /* LCD */
   3938
   3939  if( (SiS_Pr->UseCustomMode) 		         ||
   3940      (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
   3941      (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
   3942      (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
   3943      (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
   3944     return;
   3945  }
   3946
   3947  if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   3948  else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   3949
   3950  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   3951
   3952#ifdef CONFIG_FB_SIS_315
   3953     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   3954	/* non-pass 1:1 only, see above */
   3955	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
   3956	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
   3957	}
   3958	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
   3959	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
   3960	}
   3961     }
   3962     if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
   3963	switch(SiS_Pr->SiS_CustomT) {
   3964	case CUT_UNIWILL1024:
   3965	case CUT_UNIWILL10242:
   3966	case CUT_CLEVO1400:
   3967	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   3968	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   3969	   }
   3970	   break;
   3971	}
   3972	switch(SiS_Pr->SiS_LCDResInfo) {
   3973	case Panel_1280x1024:
   3974	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
   3975	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   3976	   }
   3977	   break;
   3978	case Panel_1280x800:	/* Verified for Averatec 6240 */
   3979	case Panel_1280x800_2:	/* Verified for Asus A4L */
   3980	case Panel_1280x854:    /* Not verified yet FIXME */
   3981	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   3982	   break;
   3983	}
   3984     }
   3985#endif
   3986
   3987  } else {
   3988
   3989     if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
   3990
   3991	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
   3992	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
   3993	}
   3994
   3995     } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {
   3996
   3997	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
   3998	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
   3999
   4000     } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   4001
   4002	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
   4003	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
   4004	}
   4005	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
   4006	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
   4007	} else {
   4008	   if(SiS_Pr->ChipType < SIS_315H) {
   4009	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   4010	   } else {
   4011	      switch(SiS_Pr->SiS_LCDResInfo) {
   4012	      case Panel_800x600:
   4013	      case Panel_1024x768:
   4014	      case Panel_1280x1024:
   4015		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
   4016		 break;
   4017	      case Panel_1400x1050:
   4018		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   4019		 break;
   4020	      }
   4021	   }
   4022	}
   4023
   4024     } else {
   4025
   4026        if(SiS_Pr->ChipType < SIS_315H) {
   4027#ifdef CONFIG_FB_SIS_300
   4028	   switch(SiS_Pr->SiS_LCDResInfo) {
   4029	   case Panel_800x600:
   4030	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
   4031		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   4032	      } else {
   4033		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
   4034		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
   4035		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
   4036		 else                          SiS_Pr->SiS_LCDVDES -= 4;
   4037	      }
   4038	      break;
   4039	   case Panel_1024x768:
   4040	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
   4041		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   4042	      } else {
   4043		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
   4044		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
   4045		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
   4046	      }
   4047	      break;
   4048	   case Panel_1024x600:
   4049	   default:
   4050	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
   4051		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
   4052		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   4053	      } else {
   4054		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
   4055	      }
   4056	      break;
   4057	   }
   4058
   4059	   switch(SiS_Pr->SiS_LCDTypeInfo) {
   4060	   case 1:
   4061	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
   4062	      break;
   4063	   case 3: /* 640x480 only? */
   4064	      SiS_Pr->SiS_LCDHDES = 8;
   4065	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
   4066	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
   4067	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
   4068	      break;
   4069	   }
   4070#endif
   4071        } else {
   4072#ifdef CONFIG_FB_SIS_315
   4073	   switch(SiS_Pr->SiS_LCDResInfo) {
   4074	   case Panel_1024x768:
   4075	   case Panel_1280x1024:
   4076	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
   4077	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
   4078	      }
   4079	      break;
   4080	   case Panel_320x240_1:
   4081	   case Panel_320x240_2:
   4082	   case Panel_320x240_3:
   4083	      SiS_Pr->SiS_LCDVDES = 524;
   4084	      break;
   4085	   }
   4086#endif
   4087	}
   4088     }
   4089
   4090     if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
   4091	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   4092	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   4093	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
   4094	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
   4095	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
   4096	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
   4097	         if(SiS_Pr->ChipType < SIS_315H) {
   4098	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
   4099	         } else {
   4100#ifdef CONFIG_FB_SIS_315
   4101		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
   4102		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
   4103		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
   4104		    if(!(modeflag & HalfDCLK)) {
   4105		       SiS_Pr->SiS_LCDHDES = 320;
   4106		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
   4107		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
   4108        	    }
   4109#endif
   4110		 }
   4111	      }
   4112	   }
   4113	}
   4114     }
   4115  }
   4116}
   4117
   4118/*********************************************/
   4119/*           DISABLE VIDEO BRIDGE            */
   4120/*********************************************/
   4121
   4122#ifdef CONFIG_FB_SIS_315
   4123static int
   4124SiS_HandlePWD(struct SiS_Private *SiS_Pr)
   4125{
   4126   int ret = 0;
   4127#ifdef SET_PWD
   4128   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
   4129   unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
   4130   unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
   4131   unsigned short temp;
   4132
   4133   if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
   4134       (romptr)				&&
   4135       (SiS_Pr->SiS_PWDOffset) ) {
   4136      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
   4137      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
   4138      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
   4139      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
   4140      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
   4141      temp = 0x00;
   4142      if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
   4143         temp = 0x80;
   4144	 ret = 1;
   4145      }
   4146      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
   4147   }
   4148#endif
   4149   return ret;
   4150}
   4151#endif
   4152
   4153/* NEVER use any variables (VBInfo), this will be called
   4154 * from outside the context of modeswitch!
   4155 * MUST call getVBType before calling this
   4156 */
   4157void
   4158SiS_DisableBridge(struct SiS_Private *SiS_Pr)
   4159{
   4160#ifdef CONFIG_FB_SIS_315
   4161  unsigned short tempah, pushax=0, modenum;
   4162#endif
   4163  unsigned short temp=0;
   4164
   4165  if(SiS_Pr->SiS_VBType & VB_SISVB) {
   4166
   4167     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */
   4168
   4169	if(SiS_Pr->ChipType < SIS_315H) {
   4170
   4171#ifdef CONFIG_FB_SIS_300	   /* 300 series */
   4172
   4173	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
   4174	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4175		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
   4176	      } else {
   4177		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
   4178	      }
   4179	      SiS_PanelDelay(SiS_Pr, 3);
   4180	   }
   4181	   if(SiS_Is301B(SiS_Pr)) {
   4182	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
   4183	      SiS_ShortDelay(SiS_Pr,1);
   4184	   }
   4185	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
   4186	   SiS_DisplayOff(SiS_Pr);
   4187	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
   4188	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
   4189	   SiS_UnLockCRT2(SiS_Pr);
   4190	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
   4191	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
   4192	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
   4193	   }
   4194	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
   4195	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
   4196	      SiS_PanelDelay(SiS_Pr, 2);
   4197	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4198	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
   4199	      } else {
   4200		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
   4201	      }
   4202	   }
   4203
   4204#endif  /* CONFIG_FB_SIS_300 */
   4205
   4206        } else {
   4207
   4208#ifdef CONFIG_FB_SIS_315	   /* 315 series */
   4209
   4210	   int didpwd = 0;
   4211	   bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
   4212	                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
   4213
   4214	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
   4215
   4216	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4217
   4218#ifdef SET_EMI
   4219	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4220		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
   4221		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
   4222		 }
   4223	      }
   4224#endif
   4225
   4226	      didpwd = SiS_HandlePWD(SiS_Pr);
   4227
   4228	      if( (modenum <= 0x13)           ||
   4229		  (SiS_IsVAMode(SiS_Pr))      ||
   4230		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
   4231		 if(!didpwd) {
   4232		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
   4233		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);
   4234		 } else {
   4235		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
   4236		 }
   4237	      }
   4238
   4239	      if(!custom1) {
   4240		 SiS_DDC2Delay(SiS_Pr,0xff00);
   4241		 SiS_DDC2Delay(SiS_Pr,0xe000);
   4242		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
   4243		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
   4244		 if(IS_SIS740) {
   4245		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
   4246		 }
   4247	         SiS_PanelDelay(SiS_Pr, 3);
   4248	      }
   4249
   4250	   }
   4251
   4252	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {
   4253	      /* if(SiS_Pr->ChipType < SIS_340) {*/
   4254		 tempah = 0xef;
   4255		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
   4256		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
   4257	      /*}*/
   4258	   }
   4259
   4260	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4261	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
   4262	   }
   4263
   4264	   tempah = 0x3f;
   4265	   if(SiS_IsDualEdge(SiS_Pr)) {
   4266	      tempah = 0x7f;
   4267	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
   4268	   }
   4269	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
   4270
   4271	   if((SiS_IsVAMode(SiS_Pr)) ||
   4272	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
   4273
   4274	      SiS_DisplayOff(SiS_Pr);
   4275	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4276		 SiS_PanelDelay(SiS_Pr, 2);
   4277	      }
   4278	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
   4279	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
   4280
   4281	   }
   4282
   4283	   if((!(SiS_IsVAMode(SiS_Pr))) ||
   4284	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {
   4285
   4286	      if(!(SiS_IsDualEdge(SiS_Pr))) {
   4287		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
   4288		 SiS_DisplayOff(SiS_Pr);
   4289	      }
   4290	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
   4291
   4292	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4293		 SiS_PanelDelay(SiS_Pr, 2);
   4294	      }
   4295
   4296	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
   4297	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
   4298	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
   4299	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
   4300	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
   4301
   4302	   }
   4303
   4304	   if(SiS_IsNotM650orLater(SiS_Pr)) {
   4305	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
   4306	   }
   4307
   4308	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4309
   4310	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&
   4311		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
   4312		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
   4313
   4314		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
   4315		 if(!didpwd) {
   4316		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
   4317		 }
   4318		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
   4319	      }
   4320
   4321	      if(!custom1) {
   4322		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
   4323		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4324		    if(SiS_IsVAorLCD(SiS_Pr)) {
   4325		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);
   4326		    }
   4327		 }
   4328	      }
   4329
   4330	   }
   4331
   4332#endif /* CONFIG_FB_SIS_315 */
   4333
   4334	}
   4335
   4336     } else {     /* ============ For 301 ================ */
   4337
   4338        if(SiS_Pr->ChipType < SIS_315H) {
   4339#ifdef CONFIG_FB_SIS_300
   4340	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
   4341	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
   4342	      SiS_PanelDelay(SiS_Pr, 3);
   4343	   }
   4344#endif
   4345	}
   4346
   4347	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
   4348	SiS_DisplayOff(SiS_Pr);
   4349
   4350	if(SiS_Pr->ChipType >= SIS_315H) {
   4351	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
   4352	}
   4353
   4354	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
   4355
   4356	if(SiS_Pr->ChipType >= SIS_315H) {
   4357	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
   4358	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
   4359	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
   4360	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
   4361	} else {
   4362#ifdef CONFIG_FB_SIS_300
   4363	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
   4364	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
   4365		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
   4366		SiS_PanelDelay(SiS_Pr, 2);
   4367		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
   4368	    }
   4369#endif
   4370	}
   4371
   4372      }
   4373
   4374  } else {     /* ============ For LVDS =============*/
   4375
   4376    if(SiS_Pr->ChipType < SIS_315H) {
   4377
   4378#ifdef CONFIG_FB_SIS_300	/* 300 series */
   4379
   4380	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
   4381	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);
   4382	}
   4383
   4384	if(SiS_Pr->ChipType == SIS_730) {
   4385	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
   4386	      SiS_WaitVBRetrace(SiS_Pr);
   4387	   }
   4388	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
   4389	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
   4390	      SiS_PanelDelay(SiS_Pr, 3);
   4391	   }
   4392	} else {
   4393	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
   4394	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
   4395		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
   4396		    SiS_WaitVBRetrace(SiS_Pr);
   4397		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
   4398		       SiS_DisplayOff(SiS_Pr);
   4399		    }
   4400		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
   4401		    SiS_PanelDelay(SiS_Pr, 3);
   4402		 }
   4403	      }
   4404	   }
   4405	}
   4406
   4407	SiS_DisplayOff(SiS_Pr);
   4408
   4409	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
   4410
   4411	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
   4412	SiS_UnLockCRT2(SiS_Pr);
   4413	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
   4414	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
   4415
   4416	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
   4417	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
   4418	   SiS_PanelDelay(SiS_Pr, 2);
   4419	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
   4420	}
   4421
   4422#endif  /* CONFIG_FB_SIS_300 */
   4423
   4424    } else {
   4425
   4426#ifdef CONFIG_FB_SIS_315	/* 315 series */
   4427
   4428	if(!(SiS_IsNotM650orLater(SiS_Pr))) {
   4429	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
   4430	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
   4431	   /* } */
   4432	}
   4433
   4434	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   4435
   4436	   if(SiS_Pr->ChipType == SIS_740) {
   4437	      temp = SiS_GetCH701x(SiS_Pr,0x61);
   4438	      if(temp < 1) {
   4439		 SiS_SetCH701x(SiS_Pr,0x76,0xac);
   4440		 SiS_SetCH701x(SiS_Pr,0x66,0x00);
   4441	      }
   4442
   4443	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
   4444		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
   4445		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
   4446	      }
   4447	   }
   4448
   4449	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||
   4450	       (SiS_IsVAMode(SiS_Pr)) ) {
   4451	      SiS_Chrontel701xBLOff(SiS_Pr);
   4452	      SiS_Chrontel701xOff(SiS_Pr);
   4453	   }
   4454
   4455	   if(SiS_Pr->ChipType != SIS_740) {
   4456	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
   4457		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
   4458		 SiS_SetCH701x(SiS_Pr,0x49,0x01);
   4459	      }
   4460	   }
   4461
   4462	}
   4463
   4464	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
   4465	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
   4466	   SiS_PanelDelay(SiS_Pr, 3);
   4467	}
   4468
   4469	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
   4470	    (!(SiS_IsDualEdge(SiS_Pr))) ||
   4471	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
   4472	   SiS_DisplayOff(SiS_Pr);
   4473	}
   4474
   4475	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
   4476	    (!(SiS_IsDualEdge(SiS_Pr))) ||
   4477	    (!(SiS_IsVAMode(SiS_Pr))) ) {
   4478	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
   4479	}
   4480
   4481	if(SiS_Pr->ChipType == SIS_740) {
   4482	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
   4483	}
   4484
   4485	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
   4486
   4487	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
   4488	    (!(SiS_IsDualEdge(SiS_Pr))) ||
   4489	    (!(SiS_IsVAMode(SiS_Pr))) ) {
   4490	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
   4491	}
   4492
   4493	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
   4494	   if(SiS_CRT2IsLCD(SiS_Pr)) {
   4495	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
   4496	      if(SiS_Pr->ChipType == SIS_550) {
   4497		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
   4498		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
   4499	      }
   4500	   }
   4501	} else {
   4502	   if(SiS_Pr->ChipType == SIS_740) {
   4503	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {
   4504		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
   4505	      }
   4506	   } else if(SiS_IsVAMode(SiS_Pr)) {
   4507	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
   4508	   }
   4509	}
   4510
   4511	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   4512	   if(SiS_IsDualEdge(SiS_Pr)) {
   4513	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
   4514	   } else {
   4515	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
   4516	   }
   4517	}
   4518
   4519	SiS_UnLockCRT2(SiS_Pr);
   4520
   4521	if(SiS_Pr->ChipType == SIS_550) {
   4522	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
   4523	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
   4524	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
   4525		   (!(SiS_IsDualEdge(SiS_Pr))) ||
   4526		   (!(SiS_IsVAMode(SiS_Pr))) ) {
   4527	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
   4528	}
   4529
   4530        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
   4531	   if(SiS_CRT2IsLCD(SiS_Pr)) {
   4532	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
   4533		 SiS_PanelDelay(SiS_Pr, 2);
   4534		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
   4535	      }
   4536	   }
   4537        }
   4538
   4539#endif  /* CONFIG_FB_SIS_315 */
   4540
   4541    }  /* 315 series */
   4542
   4543  }  /* LVDS */
   4544
   4545}
   4546
   4547/*********************************************/
   4548/*            ENABLE VIDEO BRIDGE            */
   4549/*********************************************/
   4550
   4551/* NEVER use any variables (VBInfo), this will be called
   4552 * from outside the context of a mode switch!
   4553 * MUST call getVBType before calling this
   4554 */
   4555static
   4556void
   4557SiS_EnableBridge(struct SiS_Private *SiS_Pr)
   4558{
   4559  unsigned short temp=0, tempah;
   4560#ifdef CONFIG_FB_SIS_315
   4561  unsigned short temp1, pushax=0;
   4562  bool delaylong = false;
   4563#endif
   4564
   4565  if(SiS_Pr->SiS_VBType & VB_SISVB) {
   4566
   4567    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */
   4568
   4569      if(SiS_Pr->ChipType < SIS_315H) {
   4570
   4571#ifdef CONFIG_FB_SIS_300     /* 300 series */
   4572
   4573	 if(SiS_CRT2IsLCD(SiS_Pr)) {
   4574	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4575	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
   4576	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
   4577	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
   4578	    }
   4579	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
   4580	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
   4581		  SiS_PanelDelay(SiS_Pr, 0);
   4582	       }
   4583	    }
   4584	 }
   4585
   4586	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
   4587	    (SiS_CRT2IsLCD(SiS_Pr))) {
   4588
   4589	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
   4590	    SiS_DisplayOn(SiS_Pr);
   4591	    SiS_UnLockCRT2(SiS_Pr);
   4592	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
   4593	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
   4594	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
   4595	    } else {
   4596	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
   4597	    }
   4598	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
   4599	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
   4600		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
   4601		     SiS_PanelDelay(SiS_Pr, 1);
   4602		  }
   4603		  SiS_WaitVBRetrace(SiS_Pr);
   4604		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
   4605	       }
   4606	    }
   4607
   4608	 } else {
   4609
   4610	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
   4611	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
   4612	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   4613	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
   4614	    }
   4615	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
   4616	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
   4617	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
   4618	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
   4619	    SiS_DisplayOn(SiS_Pr);
   4620	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4621	       if(SiS_CRT2IsLCD(SiS_Pr)) {
   4622		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
   4623		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
   4624		        SiS_PanelDelay(SiS_Pr, 1);
   4625		     }
   4626		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
   4627		  }
   4628	       }
   4629	    }
   4630
   4631	 }
   4632
   4633
   4634#endif /* CONFIG_FB_SIS_300 */
   4635
   4636      } else {
   4637
   4638#ifdef CONFIG_FB_SIS_315    /* 315 series */
   4639
   4640#ifdef SET_EMI
   4641	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
   4642	 int didpwd = 0;
   4643	 /* unsigned short  emidelay=0; */
   4644#endif
   4645
   4646	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4647	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
   4648#ifdef SET_EMI
   4649	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4650	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
   4651	    }
   4652#endif
   4653	 }
   4654
   4655	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
   4656	    /*if(SiS_Pr->ChipType < SIS_340) { */
   4657	       tempah = 0x10;
   4658	       if(SiS_LCDAEnabled(SiS_Pr)) {
   4659		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
   4660		  else			    tempah = 0x08;
   4661	       }
   4662	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
   4663	    /*}*/
   4664	 }
   4665
   4666	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4667
   4668	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
   4669	    SiS_DisplayOff(SiS_Pr);
   4670	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
   4671	    if(IS_SIS740) {
   4672	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
   4673	    }
   4674
   4675	    didpwd = SiS_HandlePWD(SiS_Pr);
   4676
   4677	    if(SiS_IsVAorLCD(SiS_Pr)) {
   4678	       if(!didpwd) {
   4679		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
   4680		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
   4681		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
   4682		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
   4683		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4684		        SiS_GenericDelay(SiS_Pr, 17664);
   4685		     }
   4686		  }
   4687	       } else {
   4688		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
   4689		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4690		     SiS_GenericDelay(SiS_Pr, 17664);
   4691		  }
   4692	       }
   4693	    }
   4694
   4695	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
   4696	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);
   4697	       delaylong = true;
   4698	    }
   4699
   4700	 }
   4701
   4702	 if(!(SiS_IsVAMode(SiS_Pr))) {
   4703
   4704	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
   4705	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
   4706	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   4707	       if(!(tempah & SetCRT2ToRAMDAC)) {
   4708		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
   4709	       }
   4710	    }
   4711	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
   4712
   4713	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
   4714
   4715	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
   4716	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
   4717
   4718	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4719	       SiS_PanelDelay(SiS_Pr, 2);
   4720	    }
   4721
   4722	 } else {
   4723
   4724	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
   4725
   4726	 }
   4727
   4728	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
   4729	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
   4730
   4731	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
   4732	    if( (SiS_LCDAEnabled(SiS_Pr)) ||
   4733	        (SiS_CRT2IsLCD(SiS_Pr)) ) {
   4734	       /* Enable "LVDS PLL power on" (even on 301C) */
   4735	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
   4736	       /* Enable "LVDS Driver Power on" (even on 301C) */
   4737	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
   4738	    }
   4739	 }
   4740
   4741	 tempah = 0xc0;
   4742	 if(SiS_IsDualEdge(SiS_Pr)) {
   4743	    tempah = 0x80;
   4744	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
   4745	 }
   4746	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
   4747
   4748	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   4749
   4750	    SiS_PanelDelay(SiS_Pr, 2);
   4751
   4752	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
   4753	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
   4754
   4755	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
   4756#ifdef SET_EMI
   4757	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4758		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
   4759		  SiS_GenericDelay(SiS_Pr, 2048);
   4760	       }
   4761#endif
   4762	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
   4763
   4764	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4765#ifdef SET_EMI
   4766		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
   4767
   4768		  if(SiS_Pr->SiS_ROMNew) {
   4769		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   4770		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
   4771		     if(romptr) {
   4772			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
   4773			SiS_Pr->EMI_30 = 0;
   4774			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
   4775			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
   4776			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
   4777			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
   4778			/* emidelay = SISGETROMW((romptr + 0x22)); */
   4779			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
   4780		     }
   4781		  }
   4782
   4783		  /*                                              (P4_30|0x40)  */
   4784		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
   4785		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
   4786		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
   4787		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
   4788		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
   4789		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
   4790		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
   4791		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
   4792		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */
   4793
   4794		  if(SiS_Pr->HaveEMI) {
   4795		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
   4796		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
   4797		  } else {
   4798		     r30 = 0;
   4799		  }
   4800
   4801		  /* EMI_30 is read at driver start; however, the BIOS sets this
   4802		   * (if it is used) only if the LCD is in use. In case we caught
   4803		   * the machine while on TV output, this bit is not set and we
   4804		   * don't know if it should be set - hence our detection is wrong.
   4805		   * Work-around this here:
   4806		   */
   4807
   4808		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
   4809		     switch((cr36 & 0x0f)) {
   4810		     case 2:
   4811			r30 |= 0x40;
   4812			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
   4813			if(!SiS_Pr->HaveEMI) {
   4814			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
   4815			   if((cr36 & 0xf0) == 0x30) {
   4816			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
   4817			   }
   4818			}
   4819			break;
   4820		     case 3:  /* 1280x1024 */
   4821			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
   4822			if(!SiS_Pr->HaveEMI) {
   4823			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
   4824			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
   4825			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
   4826			   }
   4827			}
   4828			break;
   4829		     case 9:  /* 1400x1050 */
   4830			r30 |= 0x40;
   4831			if(!SiS_Pr->HaveEMI) {
   4832			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
   4833			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
   4834			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
   4835			   }
   4836			}
   4837			break;
   4838		     case 11: /* 1600x1200 - unknown */
   4839			r30 |= 0x40;
   4840			if(!SiS_Pr->HaveEMI) {
   4841			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
   4842			}
   4843		     }
   4844                  }
   4845
   4846		  /* BIOS values don't work so well sometimes */
   4847		  if(!SiS_Pr->OverruleEMI) {
   4848#ifdef COMPAL_HACK
   4849		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
   4850			if((cr36 & 0x0f) == 0x09) {
   4851			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
   4852			}
   4853 		     }
   4854#endif
   4855#ifdef COMPAQ_HACK
   4856		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
   4857			if((cr36 & 0x0f) == 0x03) {
   4858			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
   4859			}
   4860		     }
   4861#endif
   4862#ifdef ASUS_HACK
   4863		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
   4864			if((cr36 & 0x0f) == 0x02) {
   4865			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
   4866			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
   4867			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
   4868			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
   4869			}
   4870		     }
   4871#endif
   4872		  }
   4873
   4874		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
   4875		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
   4876		     SiS_GenericDelay(SiS_Pr, 2048);
   4877		  }
   4878		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
   4879		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
   4880		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
   4881#endif	/* SET_EMI */
   4882
   4883		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
   4884
   4885#ifdef SET_EMI
   4886		  if( (SiS_LCDAEnabled(SiS_Pr)) ||
   4887		      (SiS_CRT2IsLCD(SiS_Pr)) ) {
   4888		     if(r30 & 0x40) {
   4889			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
   4890			SiS_PanelDelayLoop(SiS_Pr, 3, 5);
   4891			if(delaylong) {
   4892			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);
   4893			   delaylong = false;
   4894			}
   4895			SiS_WaitVBRetrace(SiS_Pr);
   4896			SiS_WaitVBRetrace(SiS_Pr);
   4897			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
   4898			   SiS_GenericDelay(SiS_Pr, 1280);
   4899			}
   4900			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
   4901			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
   4902		     }
   4903		  }
   4904#endif
   4905	       }
   4906	    }
   4907
   4908	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
   4909	       if(SiS_IsVAorLCD(SiS_Pr)) {
   4910		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
   4911		  if(delaylong) {
   4912		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);
   4913		  }
   4914		  SiS_WaitVBRetrace(SiS_Pr);
   4915		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   4916		     SiS_GenericDelay(SiS_Pr, 2048);
   4917		     SiS_WaitVBRetrace(SiS_Pr);
   4918		  }
   4919		  if(!didpwd) {
   4920		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
   4921		  } else {
   4922		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
   4923		  }
   4924	       }
   4925	    }
   4926
   4927	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
   4928	    SiS_DisplayOn(SiS_Pr);
   4929	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
   4930
   4931	 }
   4932
   4933	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
   4934	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
   4935	 }
   4936
   4937#endif /* CONFIG_FB_SIS_315 */
   4938
   4939      }
   4940
   4941    } else {	/* ============  For 301 ================ */
   4942
   4943       if(SiS_Pr->ChipType < SIS_315H) {
   4944	  if(SiS_CRT2IsLCD(SiS_Pr)) {
   4945	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
   4946	     SiS_PanelDelay(SiS_Pr, 0);
   4947	  }
   4948       }
   4949
   4950       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
   4951       if(SiS_BridgeInSlavemode(SiS_Pr)) {
   4952	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
   4953	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
   4954       }
   4955       SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
   4956
   4957       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
   4958
   4959       if(SiS_Pr->ChipType >= SIS_315H) {
   4960	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
   4961	  if(!(temp & 0x80)) {
   4962	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
   4963	  }
   4964       }
   4965
   4966       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
   4967
   4968       SiS_VBLongWait(SiS_Pr);
   4969       SiS_DisplayOn(SiS_Pr);
   4970       if(SiS_Pr->ChipType >= SIS_315H) {
   4971	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
   4972       }
   4973       SiS_VBLongWait(SiS_Pr);
   4974
   4975       if(SiS_Pr->ChipType < SIS_315H) {
   4976	  if(SiS_CRT2IsLCD(SiS_Pr)) {
   4977	     SiS_PanelDelay(SiS_Pr, 1);
   4978	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
   4979	  }
   4980       }
   4981
   4982    }
   4983
   4984  } else {   /* =================== For LVDS ================== */
   4985
   4986    if(SiS_Pr->ChipType < SIS_315H) {
   4987
   4988#ifdef CONFIG_FB_SIS_300    /* 300 series */
   4989
   4990       if(SiS_CRT2IsLCD(SiS_Pr)) {
   4991	  if(SiS_Pr->ChipType == SIS_730) {
   4992	     SiS_PanelDelay(SiS_Pr, 1);
   4993	     SiS_PanelDelay(SiS_Pr, 1);
   4994	     SiS_PanelDelay(SiS_Pr, 1);
   4995	  }
   4996	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
   4997	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
   4998	     SiS_PanelDelay(SiS_Pr, 0);
   4999	  }
   5000       }
   5001
   5002       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
   5003       SiS_DisplayOn(SiS_Pr);
   5004       SiS_UnLockCRT2(SiS_Pr);
   5005       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
   5006       if(SiS_BridgeInSlavemode(SiS_Pr)) {
   5007	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
   5008       } else {
   5009	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
   5010       }
   5011
   5012       if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
   5013	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
   5014	     SiS_WaitVBRetrace(SiS_Pr);
   5015	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
   5016	  }
   5017       }
   5018
   5019       if(SiS_CRT2IsLCD(SiS_Pr)) {
   5020	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
   5021	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
   5022		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
   5023		   SiS_PanelDelay(SiS_Pr, 1);
   5024		   SiS_PanelDelay(SiS_Pr, 1);
   5025		}
   5026		SiS_WaitVBRetrace(SiS_Pr);
   5027		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
   5028	     }
   5029	  }
   5030       }
   5031
   5032#endif  /* CONFIG_FB_SIS_300 */
   5033
   5034    } else {
   5035
   5036#ifdef CONFIG_FB_SIS_315    /* 315 series */
   5037
   5038       if(!(SiS_IsNotM650orLater(SiS_Pr))) {
   5039	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
   5040	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
   5041	  /*}*/
   5042       }
   5043
   5044       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
   5045	  if(SiS_CRT2IsLCD(SiS_Pr)) {
   5046	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
   5047	     SiS_PanelDelay(SiS_Pr, 0);
   5048	  }
   5049       }
   5050
   5051       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
   5052       SiS_UnLockCRT2(SiS_Pr);
   5053
   5054       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
   5055
   5056       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   5057	  temp = SiS_GetCH701x(SiS_Pr,0x66);
   5058	  temp &= 0x20;
   5059	  SiS_Chrontel701xBLOff(SiS_Pr);
   5060       }
   5061
   5062       if(SiS_Pr->ChipType != SIS_550) {
   5063	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
   5064       }
   5065
   5066       if(SiS_Pr->ChipType == SIS_740) {
   5067	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   5068	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {
   5069		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
   5070	     }
   5071	  }
   5072       }
   5073
   5074       temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
   5075       if(!(temp1 & 0x80)) {
   5076	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
   5077       }
   5078
   5079       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   5080	  if(temp) {
   5081	     SiS_Chrontel701xBLOn(SiS_Pr);
   5082	  }
   5083       }
   5084
   5085       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
   5086	  if(SiS_CRT2IsLCD(SiS_Pr)) {
   5087	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
   5088	     if(SiS_Pr->ChipType == SIS_550) {
   5089		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
   5090		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
   5091	     }
   5092	  }
   5093       } else if(SiS_IsVAMode(SiS_Pr)) {
   5094	  if(SiS_Pr->ChipType != SIS_740) {
   5095	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
   5096	  }
   5097       }
   5098
   5099       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
   5100	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
   5101       }
   5102
   5103       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   5104	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
   5105	     SiS_Chrontel701xOn(SiS_Pr);
   5106	  }
   5107	  if( (SiS_IsVAMode(SiS_Pr)) ||
   5108	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
   5109	     SiS_ChrontelDoSomething1(SiS_Pr);
   5110	  }
   5111       }
   5112
   5113       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   5114	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
   5115	     if( (SiS_IsVAMode(SiS_Pr)) ||
   5116		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
   5117		SiS_Chrontel701xBLOn(SiS_Pr);
   5118		SiS_ChrontelInitTVVSync(SiS_Pr);
   5119	     }
   5120	  }
   5121       } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
   5122	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
   5123	     if(SiS_CRT2IsLCD(SiS_Pr)) {
   5124		SiS_PanelDelay(SiS_Pr, 1);
   5125		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
   5126	     }
   5127	  }
   5128       }
   5129
   5130#endif  /* CONFIG_FB_SIS_315 */
   5131
   5132    } /* 310 series */
   5133
   5134  }  /* LVDS */
   5135
   5136}
   5137
   5138/*********************************************/
   5139/*         SET PART 1 REGISTER GROUP         */
   5140/*********************************************/
   5141
   5142/* Set CRT2 OFFSET / PITCH */
   5143static void
   5144SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   5145		unsigned short RRTI)
   5146{
   5147   unsigned short offset;
   5148   unsigned char  temp;
   5149
   5150   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
   5151
   5152   offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);
   5153
   5154   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
   5155   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
   5156
   5157   temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
   5158   if(offset & 0x07) temp++;
   5159   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
   5160}
   5161
   5162/* Set CRT2 sync and PanelLink mode */
   5163static void
   5164SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
   5165{
   5166   unsigned short tempah=0, tempbl, infoflag;
   5167
   5168   tempbl = 0xC0;
   5169
   5170   if(SiS_Pr->UseCustomMode) {
   5171      infoflag = SiS_Pr->CInfoFlag;
   5172   } else {
   5173      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
   5174   }
   5175
   5176   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
   5177
   5178      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   5179	 tempah = 0;
   5180      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
   5181	 tempah = SiS_Pr->SiS_LCDInfo;
   5182      } else tempah = infoflag >> 8;
   5183      tempah &= 0xC0;
   5184      tempah |= 0x20;
   5185      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
   5186      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   5187	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
   5188	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
   5189	    tempah |= 0xf0;
   5190	 }
   5191	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
   5192	     (SiS_Pr->SiS_IF_DEF_DSTN) ||
   5193	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
   5194	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
   5195	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
   5196	    tempah |= 0x30;
   5197	 }
   5198	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
   5199	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {
   5200	    tempah &= ~0xc0;
   5201	 }
   5202      }
   5203      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   5204	 if(SiS_Pr->ChipType >= SIS_315H) {
   5205	    tempah >>= 3;
   5206	    tempah &= 0x18;
   5207	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
   5208	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
   5209	 } else {
   5210	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
   5211	 }
   5212      } else {
   5213	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
   5214      }
   5215
   5216   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
   5217
   5218      if(SiS_Pr->ChipType < SIS_315H) {
   5219
   5220#ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */
   5221
   5222	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */
   5223
   5224	    tempah = infoflag >> 8;
   5225	    tempbl = 0;
   5226	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   5227	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
   5228		  tempah = SiS_Pr->SiS_LCDInfo;
   5229		  tempbl = (tempah >> 6) & 0x03;
   5230	       }
   5231	    }
   5232	    tempah &= 0xC0;
   5233	    tempah |= 0x20;
   5234	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
   5235	    tempah |= 0xc0;
   5236	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
   5237	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
   5238	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
   5239	    }
   5240
   5241	 } else {							/* 630 - 301 */
   5242
   5243	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;
   5244	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
   5245	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
   5246
   5247	 }
   5248
   5249#endif /* CONFIG_FB_SIS_300 */
   5250
   5251      } else {
   5252
   5253#ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */
   5254
   5255	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */
   5256
   5257	    tempbl = 0;
   5258	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
   5259	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
   5260	       tempah = infoflag >> 8;
   5261	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
   5262		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
   5263	       }
   5264	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
   5265		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
   5266	       tempah = infoflag >> 8;
   5267	       tempbl = 0x03;
   5268	    } else {
   5269	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
   5270	       tempbl = (tempah >> 6) & 0x03;
   5271	       tempbl |= 0x08;
   5272	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
   5273	    }
   5274	    tempah &= 0xC0;
   5275	    tempah |= 0x20;
   5276	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
   5277	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
   5278	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
   5279	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   5280	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   5281		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
   5282	       }
   5283	    }
   5284
   5285	 } else {							/* 315 - TMDS */
   5286
   5287	    tempah = tempbl = infoflag >> 8;
   5288	    if(!SiS_Pr->UseCustomMode) {
   5289	       tempbl = 0;
   5290	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
   5291		  if(ModeNo <= 0x13) {
   5292		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
   5293		  }
   5294	       }
   5295	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5296		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   5297		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {
   5298		       tempah = SiS_Pr->SiS_LCDInfo;
   5299		       tempbl = (tempah >> 6) & 0x03;
   5300		    }
   5301		  }
   5302	       }
   5303	    }
   5304	    tempah &= 0xC0;
   5305	    tempah |= 0x20;
   5306	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
   5307	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {
   5308	       /* Imitate BIOS bug */
   5309	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
   5310	    }
   5311	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
   5312	       tempah >>= 3;
   5313	       tempah &= 0x18;
   5314	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
   5315	    } else {
   5316	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
   5317	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   5318		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   5319		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
   5320		  }
   5321	       }
   5322	    }
   5323
   5324         }
   5325#endif  /* CONFIG_FB_SIS_315 */
   5326      }
   5327   }
   5328}
   5329
   5330/* Set CRT2 FIFO on 300/540/630/730 */
   5331#ifdef CONFIG_FB_SIS_300
   5332static void
   5333SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
   5334{
   5335  unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
   5336  unsigned short temp, index, modeidindex, refreshratetableindex;
   5337  unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
   5338  unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
   5339  unsigned int   data, pci50, pciA0;
   5340  static const unsigned char colortharray[] = {
   5341  	1, 1, 2, 2, 3, 4
   5342  };
   5343
   5344  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
   5345
   5346  if(!SiS_Pr->CRT1UsesCustomMode) {
   5347
   5348     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
   5349     SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
   5350     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
   5351     SiS_Pr->SiS_SelectCRT2Rate = 0;
   5352     refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex);
   5353
   5354     if(CRT1ModeNo >= 0x13) {
   5355        /* Get VCLK */
   5356	index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide);
   5357	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
   5358
   5359	/* Get colordepth */
   5360	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1;
   5361	if(!colorth) colorth++;
   5362     }
   5363
   5364  } else {
   5365
   5366     CRT1ModeNo = 0xfe;
   5367
   5368     /* Get VCLK */
   5369     VCLK = SiS_Pr->CSRClock_CRT1;
   5370
   5371     /* Get color depth */
   5372     colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)];
   5373
   5374  }
   5375
   5376  if(CRT1ModeNo >= 0x13) {
   5377     /* Get MCLK */
   5378     if(SiS_Pr->ChipType == SIS_300) {
   5379        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
   5380     } else {
   5381        index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
   5382     }
   5383     index &= 0x07;
   5384     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;
   5385
   5386     temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1;
   5387     if(!temp) temp++;
   5388     temp <<= 2;
   5389
   5390     data2 = temp - ((colorth * VCLK) / MCLK);
   5391
   5392     temp = (28 * 16) % data2;
   5393     data2 = (28 * 16) / data2;
   5394     if(temp) data2++;
   5395
   5396     if(SiS_Pr->ChipType == SIS_300) {
   5397
   5398	SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl);
   5399	data = SiS_GetFIFOThresholdB300(tempbx, tempcl);
   5400
   5401     } else {
   5402
   5403	pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
   5404	pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
   5405
   5406        if(SiS_Pr->ChipType == SIS_730) {
   5407
   5408	   index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3);
   5409	   index += (unsigned short)(((pci50 >> 9)) & 0x03);
   5410
   5411	   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
   5412	   index = 0;  /* -- do it like the BIOS anyway... */
   5413
   5414	} else {
   5415
   5416	   pci50 >>= 24;
   5417	   pciA0 >>= 24;
   5418
   5419	   index = (pci50 >> 1) & 0x07;
   5420
   5421	   if(pci50 & 0x01)    index += 6;
   5422	   if(!(pciA0 & 0x01)) index += 24;
   5423
   5424	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12;
   5425
   5426	}
   5427
   5428	data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15;
   5429	if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5;
   5430
   5431     }
   5432
   5433     data += data2;						/* CRT1 Request Period */
   5434
   5435     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   5436     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
   5437
   5438     if(!SiS_Pr->UseCustomMode) {
   5439
   5440	CRT2ModeNo = ModeNo;
   5441	SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
   5442
   5443	refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex);
   5444
   5445	/* Get VCLK  */
   5446	index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex);
   5447	VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
   5448
   5449	if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
   5450	   if(SiS_Pr->SiS_UseROM) {
   5451	      if(ROMAddr[0x220] & 0x01) {
   5452		 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
   5453	      }
   5454           }
   5455        }
   5456
   5457     } else {
   5458
   5459	/* Get VCLK */
   5460	CRT2ModeNo = 0xfe;
   5461	VCLK = SiS_Pr->CSRClock;
   5462
   5463     }
   5464
   5465     /* Get colordepth */
   5466     colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1;
   5467     if(!colorth) colorth++;
   5468
   5469     data = data * VCLK * colorth;
   5470     temp = data % (MCLK << 4);
   5471     data = data / (MCLK << 4);
   5472     if(temp) data++;
   5473
   5474     if(data < 6) data = 6;
   5475     else if(data > 0x14) data = 0x14;
   5476
   5477     if(SiS_Pr->ChipType == SIS_300) {
   5478        temp = 0x16;
   5479	if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024))
   5480	   temp = 0x13;
   5481     } else {
   5482        temp = 0x16;
   5483	if(( (SiS_Pr->ChipType == SIS_630) ||
   5484	     (SiS_Pr->ChipType == SIS_730) )  &&
   5485	   (SiS_Pr->ChipRevision >= 0x30))
   5486	   temp = 0x1b;
   5487     }
   5488     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
   5489
   5490     if((SiS_Pr->ChipType == SIS_630) &&
   5491	(SiS_Pr->ChipRevision >= 0x30)) {
   5492	if(data > 0x13) data = 0x13;
   5493     }
   5494     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
   5495
   5496  } else {  /* If mode <= 0x13, we just restore everything */
   5497
   5498     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   5499     SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
   5500
   5501  }
   5502}
   5503#endif
   5504
   5505/* Set CRT2 FIFO on 315/330 series */
   5506#ifdef CONFIG_FB_SIS_315
   5507static void
   5508SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
   5509{
   5510  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
   5511  if( (SiS_Pr->ChipType == SIS_760)      &&
   5512      (SiS_Pr->SiS_SysFlags & SF_760LFB)  &&
   5513      (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
   5514      (SiS_Pr->SiS_VGAHDE >= 1280)	  &&
   5515      (SiS_Pr->SiS_VGAVDE >= 1024) ) {
   5516     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
   5517     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
   5518     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
   5519     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
   5520     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
   5521     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
   5522  } else {
   5523     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
   5524  }
   5525
   5526}
   5527#endif
   5528
   5529static unsigned short
   5530SiS_GetVGAHT2(struct SiS_Private *SiS_Pr)
   5531{
   5532  unsigned int tempax,tempbx;
   5533
   5534  tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
   5535  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
   5536  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
   5537  return (unsigned short)tempax;
   5538}
   5539
   5540/* Set Part 1 / SiS bridge slave mode */
   5541static void
   5542SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
   5543                  unsigned short RefreshRateTableIndex)
   5544{
   5545  unsigned short temp, modeflag, i, j, xres=0, VGAVDE;
   5546  static const unsigned short CRTranslation[] = {
   5547       /* CR0   CR1   CR2   CR3   CR4   CR5   CR6   CR7   */
   5548	  0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
   5549       /* CR8   CR9   SR0A  SR0B  SR0C  SR0D  SR0E  CR0F  */
   5550	  0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00,
   5551       /* CR10  CR11  CR12  CR13  CR14  CR15  CR16  CR17  */
   5552	  0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00
   5553  };
   5554
   5555  if(ModeNo <= 0x13) {
   5556     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   5557  } else if(SiS_Pr->UseCustomMode) {
   5558     modeflag = SiS_Pr->CModeFlag;
   5559     xres = SiS_Pr->CHDisplay;
   5560  } else {
   5561     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   5562     xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
   5563  }
   5564
   5565  /* The following is only done if bridge is in slave mode: */
   5566
   5567  if(SiS_Pr->ChipType >= SIS_315H) {
   5568     if(xres >= 1600) {  /* BIOS: == 1600 */
   5569        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
   5570     }
   5571  }
   5572
   5573  SiS_Pr->CHTotal = 8224;  /* Max HT, 0x2020, results in 0x3ff in registers */
   5574
   5575  SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE;
   5576  if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1;
   5577
   5578  SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay;
   5579  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   5580     SiS_Pr->CHBlankStart += 16;
   5581  }
   5582
   5583  SiS_Pr->CHBlankEnd = 32;
   5584  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   5585     if(xres == 1600) SiS_Pr->CHBlankEnd += 80;
   5586  }
   5587
   5588  temp = SiS_Pr->SiS_VGAHT - 96;
   5589  if(!(modeflag & HalfDCLK)) temp -= 32;
   5590  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
   5591     temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04);
   5592     temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2);
   5593     temp -= 3;
   5594     temp <<= 3;
   5595  } else {
   5596     if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2;
   5597  }
   5598  SiS_Pr->CHSyncStart = temp;
   5599
   5600  SiS_Pr->CHSyncEnd = 0xffe8; 	/* results in 0x2000 in registers */
   5601
   5602  SiS_Pr->CVTotal = 2049;  	/* Max VT, 0x0801, results in 0x7ff in registers */
   5603
   5604  VGAVDE = SiS_Pr->SiS_VGAVDE;
   5605  if     (VGAVDE ==  357) VGAVDE =  350;
   5606  else if(VGAVDE ==  360) VGAVDE =  350;
   5607  else if(VGAVDE ==  375) VGAVDE =  350;
   5608  else if(VGAVDE ==  405) VGAVDE =  400;
   5609  else if(VGAVDE ==  420) VGAVDE =  400;
   5610  else if(VGAVDE ==  525) VGAVDE =  480;
   5611  else if(VGAVDE == 1056) VGAVDE = 1024;
   5612  SiS_Pr->CVDisplay = VGAVDE;
   5613
   5614  SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay;
   5615
   5616  SiS_Pr->CVBlankEnd = 1;
   5617  if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226;
   5618
   5619  temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1;
   5620  SiS_Pr->CVSyncStart = VGAVDE + temp;
   5621
   5622  temp >>= 3;
   5623  SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp;
   5624
   5625  SiS_CalcCRRegisters(SiS_Pr, 0);
   5626  SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
   5627
   5628  for(i = 0; i <= 7; i++) {
   5629     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]);
   5630  }
   5631  for(i = 0x10, j = 8; i <= 0x12; i++, j++) {
   5632     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
   5633  }
   5634  for(i = 0x15, j = 11; i <= 0x16; i++, j++) {
   5635     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
   5636  }
   5637  for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) {
   5638     SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]);
   5639  }
   5640
   5641  temp = SiS_Pr->CCRT1CRTC[16] & 0xE0;
   5642  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp);
   5643
   5644  temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
   5645  if(modeflag & DoubleScanMode) temp |= 0x80;
   5646  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp);
   5647
   5648  temp = 0;
   5649  temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01);
   5650  if(modeflag & HalfDCLK) temp |= 0x08;
   5651  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* SR01: HalfDCLK[3], 8/9 div dotclock[0] */
   5652
   5653  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* CR14: (text mode: underline location) */
   5654  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* CR17: n/a */
   5655
   5656  temp = 0;
   5657  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
   5658     temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7;
   5659  }
   5660  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* SR0E, dither[7] */
   5661
   5662  temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
   5663  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);			/* ? */
   5664}
   5665
   5666/* Setup panel link
   5667 * This is used for LVDS, LCDA and Chrontel TV output
   5668 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
   5669 */
   5670static void
   5671SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   5672		unsigned short RefreshRateTableIndex)
   5673{
   5674  unsigned short modeflag, resinfo = 0;
   5675  unsigned short push2, tempax, tempbx, tempcx, temp;
   5676  unsigned int   tempeax = 0, tempebx, tempecx, tempvcfact = 0;
   5677  bool islvds = false, issis  = false, chkdclkfirst = false;
   5678#ifdef CONFIG_FB_SIS_300
   5679  unsigned short crt2crtc = 0;
   5680#endif
   5681#ifdef CONFIG_FB_SIS_315
   5682  unsigned short pushcx;
   5683#endif
   5684
   5685  if(ModeNo <= 0x13) {
   5686     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   5687     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   5688#ifdef CONFIG_FB_SIS_300
   5689     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   5690#endif
   5691  } else if(SiS_Pr->UseCustomMode) {
   5692     modeflag = SiS_Pr->CModeFlag;
   5693  } else {
   5694     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   5695     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   5696#ifdef CONFIG_FB_SIS_300
   5697     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   5698#endif
   5699  }
   5700
   5701  /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
   5702  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
   5703     islvds = true;
   5704  }
   5705
   5706  /* is really sis if sis bridge, but not 301B-DH */
   5707  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
   5708     issis = true;
   5709  }
   5710
   5711  if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
   5712     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
   5713        chkdclkfirst = true;
   5714     }
   5715  }
   5716
   5717#ifdef CONFIG_FB_SIS_315
   5718  if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   5719     if(IS_SIS330) {
   5720        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
   5721     } else if(IS_SIS740) {
   5722        if(islvds) {
   5723           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
   5724	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
   5725        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
   5726           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
   5727        }
   5728     } else {
   5729        if(islvds) {
   5730           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
   5731	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
   5732        } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
   5733           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
   5734	   if(SiS_Pr->SiS_VBType & VB_SIS30xC) {
   5735	      if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
   5736	         (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
   5737	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
   5738	      }
   5739	   }
   5740        }
   5741     }
   5742  }
   5743#endif
   5744
   5745  /* Horizontal */
   5746
   5747  tempax = SiS_Pr->SiS_LCDHDES;
   5748  if(islvds) {
   5749     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5750	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
   5751	   if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
   5752	      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
   5753	      tempax -= 8;
   5754	   }
   5755	}
   5756     }
   5757  }
   5758
   5759  temp = (tempax & 0x0007);
   5760  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);			/* BPLHDESKEW[2:0]   */
   5761  temp = (tempax >> 3) & 0x00FF;
   5762  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);			/* BPLHDESKEW[10:3]  */
   5763
   5764  tempbx = SiS_Pr->SiS_HDE;
   5765  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5766     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   5767        tempbx = SiS_Pr->PanelXRes;
   5768     }
   5769     if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) ||
   5770        (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) ||
   5771        (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) {
   5772        tempbx >>= 1;
   5773     }
   5774  }
   5775
   5776  tempax += tempbx;
   5777  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
   5778
   5779  temp = tempax;
   5780  if(temp & 0x07) temp += 8;
   5781  temp >>= 3;
   5782  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);			/* BPLHDEE  */
   5783
   5784  tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
   5785
   5786  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5787     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   5788        if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
   5789     }
   5790  }
   5791
   5792  tempcx += tempax;
   5793  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
   5794
   5795  temp = (tempcx >> 3) & 0x00FF;
   5796  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5797     if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
   5798	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   5799	   switch(ModeNo) {
   5800	   case 0x04:
   5801	   case 0x05:
   5802	   case 0x0d: temp = 0x56; break;
   5803	   case 0x10: temp = 0x60; break;
   5804	   case 0x13: temp = 0x5f; break;
   5805	   case 0x40:
   5806	   case 0x41:
   5807	   case 0x4f:
   5808	   case 0x43:
   5809	   case 0x44:
   5810	   case 0x62:
   5811	   case 0x56:
   5812	   case 0x53:
   5813	   case 0x5d:
   5814	   case 0x5e: temp = 0x54; break;
   5815	   }
   5816	}
   5817     }
   5818  }
   5819  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);			/* BPLHRS */
   5820
   5821  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5822     temp += 2;
   5823     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   5824	temp += 8;
   5825	if(SiS_Pr->PanelHRE != 999) {
   5826	   temp = tempcx + SiS_Pr->PanelHRE;
   5827	   if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
   5828	   temp >>= 3;
   5829	}
   5830     }
   5831  } else {
   5832     temp += 10;
   5833  }
   5834
   5835  temp &= 0x1F;
   5836  temp |= ((tempcx & 0x07) << 5);
   5837  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);			/* BPLHRE */
   5838
   5839  /* Vertical */
   5840
   5841  tempax = SiS_Pr->SiS_VGAVDE;
   5842  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5843     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   5844	tempax = SiS_Pr->PanelYRes;
   5845     }
   5846  }
   5847
   5848  tempbx = SiS_Pr->SiS_LCDVDES + tempax;
   5849  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
   5850
   5851  push2 = tempbx;
   5852
   5853  tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
   5854  if(SiS_Pr->ChipType < SIS_315H) {
   5855     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5856	if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   5857	   tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
   5858	}
   5859     }
   5860  }
   5861  if(islvds) tempcx >>= 1;
   5862  else       tempcx >>= 2;
   5863
   5864  if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
   5865      (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) 		    &&
   5866      (SiS_Pr->PanelVRS != 999) ) {
   5867     tempcx = SiS_Pr->PanelVRS;
   5868     tempbx += tempcx;
   5869     if(issis) tempbx++;
   5870  } else {
   5871     tempbx += tempcx;
   5872     if(SiS_Pr->ChipType < SIS_315H) tempbx++;
   5873     else if(issis)                   tempbx++;
   5874  }
   5875
   5876  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
   5877
   5878  temp = tempbx & 0x00FF;
   5879  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
   5880     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   5881	if(ModeNo == 0x10) temp = 0xa9;
   5882     }
   5883  }
   5884  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);			/* BPLVRS */
   5885
   5886  tempcx >>= 3;
   5887  tempcx++;
   5888
   5889  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5890     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
   5891        if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
   5892     }
   5893  }
   5894
   5895  tempcx += tempbx;
   5896  temp = tempcx & 0x000F;
   5897  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);	/* BPLVRE  */
   5898
   5899  temp = ((tempbx >> 8) & 0x07) << 3;
   5900  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
   5901     if(SiS_Pr->SiS_HDE != 640) {
   5902        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
   5903     }
   5904  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
   5905  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)          temp |= 0x40;
   5906  tempbx = 0x87;
   5907  if((SiS_Pr->ChipType >= SIS_315H) ||
   5908     (SiS_Pr->ChipRevision >= 0x30)) {
   5909     tempbx = 0x07;
   5910     if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
   5911	if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03)    temp |= 0x80;
   5912     }
   5913     /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */
   5914     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
   5915	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   5916	   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10)      temp |= 0x80;
   5917	} else {
   5918	   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
   5919	}
   5920     }
   5921  }
   5922  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
   5923
   5924  tempbx = push2;						/* BPLVDEE */
   5925
   5926  tempcx = SiS_Pr->SiS_LCDVDES;					/* BPLVDES */
   5927
   5928  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   5929     switch(SiS_Pr->SiS_LCDResInfo) {
   5930     case Panel_640x480:
   5931	tempbx = SiS_Pr->SiS_VGAVDE - 1;
   5932	tempcx = SiS_Pr->SiS_VGAVDE;
   5933	break;
   5934     case Panel_800x600:
   5935	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   5936	   if(resinfo == SIS_RI_800x600) tempcx++;
   5937	}
   5938	break;
   5939     case Panel_1024x600:
   5940	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   5941	   if(resinfo == SIS_RI_1024x600) tempcx++;
   5942	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   5943	      if(resinfo == SIS_RI_800x600) tempcx++;
   5944	   }
   5945	}
   5946	break;
   5947     case Panel_1024x768:
   5948	if(SiS_Pr->ChipType < SIS_315H) {
   5949	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   5950	      if(resinfo == SIS_RI_1024x768) tempcx++;
   5951	   }
   5952	}
   5953	break;
   5954     }
   5955  }
   5956
   5957  temp = ((tempbx >> 8) & 0x07) << 3;
   5958  temp |= ((tempcx >> 8) & 0x07);
   5959  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
   5960  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
   5961  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
   5962
   5963  /* Vertical scaling */
   5964
   5965  if(SiS_Pr->ChipType < SIS_315H) {
   5966
   5967#ifdef CONFIG_FB_SIS_300      /* 300 series */
   5968     tempeax = SiS_Pr->SiS_VGAVDE << 6;
   5969     temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
   5970     tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
   5971     if(temp) tempeax++;
   5972
   5973     if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
   5974
   5975     temp = (unsigned short)(tempeax & 0x00FF);
   5976     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      	/* BPLVCFACT */
   5977     tempvcfact = temp;
   5978#endif /* CONFIG_FB_SIS_300 */
   5979
   5980  } else {
   5981
   5982#ifdef CONFIG_FB_SIS_315  /* 315 series */
   5983     tempeax = SiS_Pr->SiS_VGAVDE << 18;
   5984     tempebx = SiS_Pr->SiS_VDE;
   5985     temp = (tempeax % tempebx);
   5986     tempeax = tempeax / tempebx;
   5987     if(temp) tempeax++;
   5988     tempvcfact = tempeax;
   5989
   5990     temp = (unsigned short)(tempeax & 0x00FF);
   5991     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
   5992     temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
   5993     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
   5994     temp = (unsigned short)((tempeax & 0x00030000) >> 16);
   5995     if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
   5996     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
   5997
   5998     if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) {
   5999        temp = (unsigned short)(tempeax & 0x00FF);
   6000        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
   6001        temp = (unsigned short)((tempeax & 0x00FF00) >> 8);
   6002        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
   6003        temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6);
   6004        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
   6005        temp = 0;
   6006        if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
   6007        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
   6008     }
   6009#endif
   6010
   6011  }
   6012
   6013  /* Horizontal scaling */
   6014
   6015  tempeax = SiS_Pr->SiS_VGAHDE;		/* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
   6016  if(chkdclkfirst) {
   6017     if(modeflag & HalfDCLK) tempeax >>= 1;
   6018  }
   6019  tempebx = tempeax << 16;
   6020  if(SiS_Pr->SiS_HDE == tempeax) {
   6021     tempecx = 0xFFFF;
   6022  } else {
   6023     tempecx = tempebx / SiS_Pr->SiS_HDE;
   6024     if(SiS_Pr->ChipType >= SIS_315H) {
   6025        if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
   6026     }
   6027  }
   6028
   6029  if(SiS_Pr->ChipType >= SIS_315H) {
   6030     tempeax = (tempebx / tempecx) - 1;
   6031  } else {
   6032     tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
   6033  }
   6034  tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
   6035  temp = (unsigned short)(tempecx & 0x00FF);
   6036  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
   6037
   6038  if(SiS_Pr->ChipType >= SIS_315H) {
   6039     tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
   6040     tempbx = (unsigned short)(tempeax & 0xFFFF);
   6041  } else {
   6042     tempeax = SiS_Pr->SiS_VGAVDE << 6;
   6043     tempbx = tempvcfact & 0x3f;
   6044     if(tempbx == 0) tempbx = 64;
   6045     tempeax /= tempbx;
   6046     tempbx = (unsigned short)(tempeax & 0xFFFF);
   6047  }
   6048  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
   6049  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
   6050     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
   6051     else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480)             tempbx = 1;
   6052  }
   6053
   6054  temp = ((tempbx >> 8) & 0x07) << 3;
   6055  temp = temp | ((tempecx >> 8) & 0x07);
   6056  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
   6057  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
   6058
   6059  tempecx >>= 16;						/* BPLHCFACT  */
   6060  if(!chkdclkfirst) {
   6061     if(modeflag & HalfDCLK) tempecx >>= 1;
   6062  }
   6063  temp = (unsigned short)((tempecx & 0xFF00) >> 8);
   6064  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
   6065  temp = (unsigned short)(tempecx & 0x00FF);
   6066  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
   6067
   6068#ifdef CONFIG_FB_SIS_315
   6069  if(SiS_Pr->ChipType >= SIS_315H) {
   6070     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   6071        if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
   6072           SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
   6073	}
   6074     } else {
   6075        if(islvds) {
   6076           if(SiS_Pr->ChipType == SIS_740) {
   6077              SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
   6078           } else {
   6079	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
   6080           }
   6081        }
   6082     }
   6083  }
   6084#endif
   6085
   6086#ifdef CONFIG_FB_SIS_300
   6087  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
   6088     unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
   6089     unsigned char *trumpdata;
   6090     int   i, j = crt2crtc;
   6091     unsigned char TrumpMode13[4]   = { 0x01, 0x10, 0x2c, 0x00 };
   6092     unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
   6093     unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
   6094
   6095     if(SiS_Pr->SiS_UseROM) {
   6096	trumpdata = &ROMAddr[0x8001 + (j * 80)];
   6097     } else {
   6098	if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7;
   6099	trumpdata = &SiS300_TrumpionData[j][0];
   6100     }
   6101
   6102     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
   6103     for(i=0; i<5; i++) {
   6104	SiS_SetTrumpionBlock(SiS_Pr, trumpdata);
   6105     }
   6106     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   6107	if(ModeNo == 0x13) {
   6108	   for(i=0; i<4; i++) {
   6109	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
   6110	   }
   6111	} else if(ModeNo == 0x10) {
   6112	   for(i=0; i<4; i++) {
   6113	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
   6114	      SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
   6115	   }
   6116	}
   6117     }
   6118     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
   6119  }
   6120#endif
   6121
   6122#ifdef CONFIG_FB_SIS_315
   6123  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
   6124     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
   6125     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
   6126     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
   6127     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
   6128     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
   6129     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
   6130     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
   6131     tempax = SiS_Pr->SiS_HDE;					/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
   6132     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
   6133        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
   6134        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
   6135     tempax += 64;
   6136     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff);
   6137     temp = (tempax >> 8) << 3;
   6138     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
   6139     tempax += 32;						/* Blpe = lBlps+32 */
   6140     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff);
   6141     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);		/* Bflml = 0 */
   6142     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007);
   6143
   6144     tempax = SiS_Pr->SiS_VDE;
   6145     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
   6146        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
   6147        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
   6148     tempax >>= 1;
   6149     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff);
   6150     temp = (tempax >> 8) << 3;
   6151     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
   6152
   6153     tempeax = SiS_Pr->SiS_HDE;
   6154     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
   6155        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
   6156        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1;
   6157     tempeax <<= 2;			 			/* BDxFIFOSTOP = (HDE*4)/128 */
   6158     temp = tempeax & 0x7f;
   6159     tempeax >>= 7;
   6160     if(temp) tempeax++;
   6161     temp = tempeax & 0x3f;
   6162     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp);
   6163     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);		/* BDxWadrst0 */
   6164     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
   6165     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
   6166     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040);
   6167
   6168     tempax = SiS_Pr->SiS_HDE;
   6169     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
   6170        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
   6171        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
   6172     tempax >>= 4;						/* BDxWadroff = HDE*4/8/8 */
   6173     pushcx = tempax;
   6174     temp = tempax & 0x00FF;
   6175     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
   6176     temp = ((tempax & 0xFF00) >> 8) << 3;
   6177     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp);
   6178
   6179     tempax = SiS_Pr->SiS_VDE;				 	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
   6180     if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 ||
   6181        SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 ||
   6182        SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1;
   6183     tempeax = tempax * pushcx;
   6184     temp = tempeax & 0xFF;
   6185     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
   6186     temp = (tempeax & 0xFF00) >> 8;
   6187     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
   6188     temp = ((tempeax & 0xFF0000) >> 16) | 0x10;
   6189     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
   6190     temp = ((tempeax & 0x01000000) >> 24) << 7;
   6191     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp);
   6192
   6193     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
   6194     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
   6195     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
   6196     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
   6197     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
   6198
   6199     if(SiS_Pr->SiS_IF_DEF_FSTN) {
   6200        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
   6201        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
   6202        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
   6203        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
   6204        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
   6205        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
   6206        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
   6207        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
   6208        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
   6209        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
   6210        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
   6211        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
   6212        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
   6213        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
   6214        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
   6215        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
   6216        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
   6217        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
   6218        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
   6219        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
   6220     }
   6221  }
   6222#endif  /* CONFIG_FB_SIS_315 */
   6223}
   6224
   6225/* Set Part 1 */
   6226static void
   6227SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   6228		unsigned short RefreshRateTableIndex)
   6229{
   6230#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
   6231  unsigned char   *ROMAddr = SiS_Pr->VirtualRomBase;
   6232#endif
   6233  unsigned short  temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
   6234  unsigned short  pushbx=0, CRT1Index=0, modeflag, resinfo=0;
   6235#ifdef CONFIG_FB_SIS_315
   6236  unsigned short  tempbl=0;
   6237#endif
   6238
   6239  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   6240     SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   6241     return;
   6242  }
   6243
   6244  if(ModeNo <= 0x13) {
   6245     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   6246  } else if(SiS_Pr->UseCustomMode) {
   6247     modeflag = SiS_Pr->CModeFlag;
   6248  } else {
   6249     CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);
   6250     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   6251     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   6252  }
   6253
   6254  SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   6255
   6256  if( ! ((SiS_Pr->ChipType >= SIS_315H) &&
   6257         (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
   6258         (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
   6259
   6260     if(SiS_Pr->ChipType < SIS_315H ) {
   6261#ifdef CONFIG_FB_SIS_300
   6262	SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
   6263#endif
   6264     } else {
   6265#ifdef CONFIG_FB_SIS_315
   6266	SiS_SetCRT2FIFO_310(SiS_Pr);
   6267#endif
   6268     }
   6269
   6270     /* 1. Horizontal setup */
   6271
   6272     if(SiS_Pr->ChipType < SIS_315H ) {
   6273
   6274#ifdef CONFIG_FB_SIS_300   /* ------------- 300 series --------------*/
   6275
   6276	temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   		  /* BTVGA2HT 0x08,0x09 */
   6277	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);              /* CRT2 Horizontal Total */
   6278
   6279	temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
   6280	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
   6281
   6282	temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                 /* BTVGA2HDEE 0x0A,0x0C */
   6283	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              /* CRT2 Horizontal Display Enable End */
   6284
   6285	pushbx = SiS_Pr->SiS_VGAHDE + 12;                         /* bx  BTVGA2HRS 0x0B,0x0C */
   6286	tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
   6287	tempbx = pushbx + tempcx;
   6288	tempcx <<= 1;
   6289	tempcx += tempbx;
   6290
   6291	bridgeadd = 12;
   6292
   6293#endif /* CONFIG_FB_SIS_300 */
   6294
   6295     } else {
   6296
   6297#ifdef CONFIG_FB_SIS_315  /* ------------------- 315/330 series --------------- */
   6298
   6299	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HT 0x08,0x09 */
   6300	if(modeflag & HalfDCLK) {
   6301	   if(SiS_Pr->SiS_VBType & VB_SISVB) {
   6302	      tempcx >>= 1;
   6303	   } else {
   6304	      tempax = SiS_Pr->SiS_VGAHDE >> 1;
   6305	      tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
   6306	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   6307	         tempcx = SiS_Pr->SiS_HT - tempax;
   6308	      }
   6309	   }
   6310	}
   6311	tempcx--;
   6312	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx);            /* CRT2 Horizontal Total */
   6313	temp = (tempcx >> 4) & 0xF0;
   6314	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);    /* CRT2 Horizontal Total Overflow [7:4] */
   6315
   6316	tempcx = SiS_Pr->SiS_VGAHT;				  /* BTVGA2HDEE 0x0A,0x0C */
   6317	tempbx = SiS_Pr->SiS_VGAHDE;
   6318	tempcx -= tempbx;
   6319	tempcx >>= 2;
   6320	if(modeflag & HalfDCLK) {
   6321	   tempbx >>= 1;
   6322	   tempcx >>= 1;
   6323	}
   6324	tempbx += 16;
   6325
   6326	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx);            /* CRT2 Horizontal Display Enable End */
   6327
   6328	pushbx = tempbx;
   6329	tempcx >>= 1;
   6330	tempbx += tempcx;
   6331	tempcx += tempbx;
   6332
   6333	bridgeadd = 16;
   6334
   6335	if(SiS_Pr->SiS_VBType & VB_SISVB) {
   6336	   if(SiS_Pr->ChipType >= SIS_661) {
   6337	      if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
   6338		 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
   6339		 if(resinfo == SIS_RI_1280x1024) {
   6340		    tempcx = (tempcx & 0xff00) | 0x30;
   6341		 } else if(resinfo == SIS_RI_1600x1200) {
   6342		    tempcx = (tempcx & 0xff00) | 0xff;
   6343		 }
   6344	      }
   6345	   }
   6346        }
   6347
   6348#endif  /* CONFIG_FB_SIS_315 */
   6349
   6350     }  /* 315/330 series */
   6351
   6352     if(SiS_Pr->SiS_VBType & VB_SISVB) {
   6353
   6354	if(SiS_Pr->UseCustomMode) {
   6355	   tempbx = SiS_Pr->CHSyncStart + bridgeadd;
   6356	   tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
   6357	   tempax = SiS_Pr->SiS_VGAHT;
   6358	   if(modeflag & HalfDCLK) tempax >>= 1;
   6359	   tempax--;
   6360	   if(tempcx > tempax) tempcx = tempax;
   6361	}
   6362
   6363	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
   6364	   unsigned char cr4, cr14, cr5, cr15;
   6365	   if(SiS_Pr->UseCustomMode) {
   6366	      cr4  = SiS_Pr->CCRT1CRTC[4];
   6367	      cr14 = SiS_Pr->CCRT1CRTC[14];
   6368	      cr5  = SiS_Pr->CCRT1CRTC[5];
   6369	      cr15 = SiS_Pr->CCRT1CRTC[15];
   6370	   } else {
   6371	      cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
   6372	      cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
   6373	      cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
   6374	      cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
   6375	   }
   6376	   tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		    /* (VGAHRS-3)*8 */
   6377	   tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3;   /* (VGAHRE-3)*8 */
   6378	   tempcx &= 0x00FF;
   6379	   tempcx |= (tempbx & 0xFF00);
   6380	   tempbx += bridgeadd;
   6381	   tempcx += bridgeadd;
   6382	   tempax = SiS_Pr->SiS_VGAHT;
   6383	   if(modeflag & HalfDCLK) tempax >>= 1;
   6384	   tempax--;
   6385	   if(tempcx > tempax) tempcx = tempax;
   6386	}
   6387
   6388	if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
   6389	   tempbx = 1040;
   6390	   tempcx = 1044;   /* HWCursor bug! */
   6391	}
   6392
   6393     }
   6394
   6395     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx);            	  /* CRT2 Horizontal Retrace Start */
   6396
   6397     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx);               /* CRT2 Horizontal Retrace End */
   6398
   6399     temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
   6400     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);		  /* Overflow */
   6401
   6402     /* 2. Vertical setup */
   6403
   6404     tempcx = SiS_Pr->SiS_VGAVT - 1;
   6405     temp = tempcx & 0x00FF;
   6406
   6407     if(SiS_Pr->ChipType < SIS_661) {
   6408        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   6409	   if(SiS_Pr->ChipType < SIS_315H) {
   6410	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   6411	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
   6412	            temp--;
   6413	         }
   6414	      }
   6415	   } else {
   6416	      temp--;
   6417	   }
   6418	} else if(SiS_Pr->ChipType >= SIS_315H) {
   6419	   temp--;
   6420	}
   6421     }
   6422     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                 /* CRT2 Vertical Total */
   6423
   6424     tempbx = SiS_Pr->SiS_VGAVDE - 1;
   6425     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx);               /* CRT2 Vertical Display Enable End */
   6426
   6427     temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
   6428     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                 /* Overflow */
   6429
   6430     if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
   6431	tempbx++;
   6432	tempax = tempbx;
   6433	tempcx++;
   6434	tempcx -= tempax;
   6435	tempcx >>= 2;
   6436	tempbx += tempcx;
   6437	if(tempcx < 4) tempcx = 4;
   6438	tempcx >>= 2;
   6439	tempcx += tempbx;
   6440	tempcx++;
   6441     } else {
   6442	tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
   6443	tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
   6444     }
   6445
   6446     if(SiS_Pr->SiS_VBType & VB_SISVB) {
   6447	if(SiS_Pr->UseCustomMode) {
   6448	   tempbx = SiS_Pr->CVSyncStart;
   6449	   tempcx = SiS_Pr->CVSyncEnd;
   6450	}
   6451	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
   6452	   unsigned char cr8, cr7, cr13;
   6453	   if(SiS_Pr->UseCustomMode) {
   6454	      cr8    = SiS_Pr->CCRT1CRTC[8];
   6455	      cr7    = SiS_Pr->CCRT1CRTC[7];
   6456	      cr13   = SiS_Pr->CCRT1CRTC[13];
   6457	      tempcx = SiS_Pr->CCRT1CRTC[9];
   6458	   } else {
   6459	      cr8    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
   6460	      cr7    = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
   6461	      cr13   = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
   6462	      tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
   6463	   }
   6464	   tempbx = cr8;
   6465	   if(cr7  & 0x04) tempbx |= 0x0100;
   6466	   if(cr7  & 0x80) tempbx |= 0x0200;
   6467	   if(cr13 & 0x08) tempbx |= 0x0400;
   6468	}
   6469     }
   6470     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx);               /* CRT2 Vertical Retrace Start */
   6471
   6472     temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
   6473     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);                 /* CRT2 Vert. Retrace End; Overflow */
   6474
   6475     /* 3. Panel delay compensation */
   6476
   6477     if(SiS_Pr->ChipType < SIS_315H) {
   6478
   6479#ifdef CONFIG_FB_SIS_300  /* ---------- 300 series -------------- */
   6480
   6481	if(SiS_Pr->SiS_VBType & VB_SISVB) {
   6482	   temp = 0x20;
   6483	   if(SiS_Pr->ChipType == SIS_300) {
   6484	      temp = 0x10;
   6485	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  temp = 0x2c;
   6486	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
   6487	   }
   6488	   if(SiS_Pr->SiS_VBType & VB_SIS301) {
   6489	      if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
   6490	   }
   6491	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960)     temp = 0x24;
   6492	   if(SiS_Pr->SiS_LCDResInfo == Panel_Custom)       temp = 0x2c;
   6493	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 	    temp = 0x08;
   6494	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   6495	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	    temp = 0x2c;
   6496	      else 					    temp = 0x20;
   6497	   }
   6498	   if(SiS_Pr->SiS_UseROM) {
   6499	      if(ROMAddr[0x220] & 0x80) {
   6500		 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
   6501		    temp = ROMAddr[0x221];
   6502		 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
   6503		    temp = ROMAddr[0x222];
   6504		 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
   6505		    temp = ROMAddr[0x223];
   6506		 else
   6507		    temp = ROMAddr[0x224];
   6508	      }
   6509	   }
   6510	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   6511	      if(SiS_Pr->PDC != -1)  temp = SiS_Pr->PDC;
   6512	   }
   6513
   6514	} else {
   6515	   temp = 0x20;
   6516	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
   6517	      if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
   6518	   }
   6519	   if(SiS_Pr->SiS_UseROM) {
   6520	      if(ROMAddr[0x220] & 0x80) {
   6521	         temp = ROMAddr[0x220];
   6522	      }
   6523	   }
   6524	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   6525	      if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC;
   6526	   }
   6527	}
   6528
   6529	temp &= 0x3c;
   6530
   6531	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);   /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
   6532
   6533#endif  /* CONFIG_FB_SIS_300 */
   6534
   6535     } else {
   6536
   6537#ifdef CONFIG_FB_SIS_315   /* --------------- 315/330 series ---------------*/
   6538
   6539	if(SiS_Pr->ChipType < SIS_661) {
   6540
   6541	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   6542
   6543	      if(SiS_Pr->ChipType == SIS_740) temp = 0x03;
   6544	      else 		              temp = 0x00;
   6545
   6546	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
   6547	      tempbl = 0xF0;
   6548	      if(SiS_Pr->ChipType == SIS_650) {
   6549		 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   6550		    if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
   6551		 }
   6552	      }
   6553
   6554	      if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
   6555		 temp = 0x08;
   6556		 tempbl = 0;
   6557		 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
   6558		    if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
   6559		 }
   6560	      }
   6561
   6562	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
   6563	   }
   6564
   6565	} /* < 661 */
   6566
   6567	tempax = 0;
   6568	if(modeflag & DoubleScanMode) tempax |= 0x80;
   6569	if(modeflag & HalfDCLK)       tempax |= 0x40;
   6570	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
   6571
   6572#endif  /* CONFIG_FB_SIS_315 */
   6573
   6574     }
   6575
   6576  }  /* Slavemode */
   6577
   6578  if(SiS_Pr->SiS_VBType & VB_SISVB) {
   6579     if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
   6580	/* For 301BDH with LCD, we set up the Panel Link */
   6581	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   6582     } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   6583	SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   6584     }
   6585  } else {
   6586     if(SiS_Pr->ChipType < SIS_315H) {
   6587	SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   6588     } else {
   6589	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   6590	   if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   6591	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
   6592	   }
   6593	} else {
   6594	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex);
   6595	}
   6596     }
   6597  }
   6598}
   6599
   6600/*********************************************/
   6601/*         SET PART 2 REGISTER GROUP         */
   6602/*********************************************/
   6603
   6604#ifdef CONFIG_FB_SIS_315
   6605static unsigned char *
   6606SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
   6607{
   6608   const unsigned char *tableptr = NULL;
   6609   unsigned short      a, b, p = 0;
   6610
   6611   a = SiS_Pr->SiS_VGAHDE;
   6612   b = SiS_Pr->SiS_HDE;
   6613   if(tabletype) {
   6614      a = SiS_Pr->SiS_VGAVDE;
   6615      b = SiS_Pr->SiS_VDE;
   6616   }
   6617
   6618   if(a < b) {
   6619      tableptr = SiS_Part2CLVX_1;
   6620   } else if(a == b) {
   6621      tableptr = SiS_Part2CLVX_2;
   6622   } else {
   6623      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   6624	 tableptr = SiS_Part2CLVX_4;
   6625      } else {
   6626	 tableptr = SiS_Part2CLVX_3;
   6627      }
   6628      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   6629	 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) 	tableptr = SiS_Part2CLVX_3;
   6630	 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) 	tableptr = SiS_Part2CLVX_3;
   6631	 else 				         	tableptr = SiS_Part2CLVX_5;
   6632      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   6633	 tableptr = SiS_Part2CLVX_6;
   6634      }
   6635      do {
   6636	 if((tableptr[p] | tableptr[p+1] << 8) == a) break;
   6637	 p += 0x42;
   6638      } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
   6639      if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
   6640   }
   6641   p += 2;
   6642   return ((unsigned char *)&tableptr[p]);
   6643}
   6644
   6645static void
   6646SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   6647	      	    unsigned short RefreshRateTableIndex)
   6648{
   6649   unsigned char *tableptr;
   6650   unsigned char temp;
   6651   int i, j;
   6652
   6653   if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return;
   6654
   6655   tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0);
   6656   for(i = 0x80, j = 0; i <= 0xbf; i++, j++) {
   6657      SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
   6658   }
   6659   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   6660      tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1);
   6661      for(i = 0xc0, j = 0; i <= 0xff; i++, j++) {
   6662         SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]);
   6663      }
   6664   }
   6665   temp = 0x10;
   6666   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04;
   6667   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
   6668}
   6669
   6670static bool
   6671SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
   6672		    unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
   6673		    unsigned short *ResIndex)
   6674{
   6675
   6676  if(SiS_Pr->ChipType < SIS_315H) return false;
   6677
   6678  if(ModeNo <= 0x13)
   6679     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   6680  else
   6681     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   6682
   6683  (*ResIndex) &= 0x3f;
   6684  (*CRT2Index) = 0;
   6685
   6686  if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   6687     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
   6688        (*CRT2Index) = 200;
   6689     }
   6690  }
   6691
   6692  if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
   6693     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   6694        if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
   6695     }
   6696  }
   6697  return (((*CRT2Index) != 0));
   6698}
   6699#endif
   6700
   6701#ifdef CONFIG_FB_SIS_300
   6702static void
   6703SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
   6704{
   6705   unsigned short tempcx;
   6706   static const unsigned char atable[] = {
   6707       0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
   6708       0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
   6709   };
   6710
   6711   if(!SiS_Pr->UseCustomMode) {
   6712      if( ( ( (SiS_Pr->ChipType == SIS_630) ||
   6713	      (SiS_Pr->ChipType == SIS_730) ) &&
   6714	    (SiS_Pr->ChipRevision > 2) )  &&
   6715	  (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
   6716	  (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
   6717	  (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
   6718	 if(ModeNo == 0x13) {
   6719	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
   6720	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
   6721	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
   6722	 } else if((crt2crtc & 0x3F) == 4) {
   6723	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
   6724	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
   6725	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
   6726	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
   6727	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
   6728	 }
   6729      }
   6730
   6731      if(SiS_Pr->ChipType < SIS_315H) {
   6732	 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
   6733	    crt2crtc &= 0x1f;
   6734	    tempcx = 0;
   6735	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
   6736	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   6737		  tempcx += 7;
   6738	       }
   6739	    }
   6740	    tempcx += crt2crtc;
   6741	    if(crt2crtc >= 4) {
   6742	       SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
   6743	    }
   6744
   6745	    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
   6746	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   6747		  if(crt2crtc == 4) {
   6748		     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
   6749		  }
   6750	       }
   6751	    }
   6752	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
   6753	    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
   6754	 }
   6755      }
   6756   }
   6757}
   6758
   6759/* For ECS A907. Highly preliminary. */
   6760static void
   6761SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex,
   6762		    unsigned short ModeNo)
   6763{
   6764  const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
   6765  unsigned short crt2crtc, resindex;
   6766  int i, j;
   6767
   6768  if(SiS_Pr->ChipType != SIS_300) return;
   6769  if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
   6770  if(SiS_Pr->UseCustomMode) return;
   6771
   6772  if(ModeNo <= 0x13) {
   6773     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   6774  } else {
   6775     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   6776  }
   6777
   6778  resindex = crt2crtc & 0x3F;
   6779  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
   6780  else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
   6781
   6782  /* The BIOS code (1.16.51,56) is obviously a fragment! */
   6783  if(ModeNo > 0x13) {
   6784     CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
   6785     resindex = 4;
   6786  }
   6787
   6788  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
   6789  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
   6790  for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
   6791     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   6792  }
   6793  for(j = 0x1c; j <= 0x1d; i++, j++ ) {
   6794     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   6795  }
   6796  for(j = 0x1f; j <= 0x21; i++, j++ ) {
   6797     SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   6798  }
   6799  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
   6800  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
   6801}
   6802#endif
   6803
   6804static void
   6805SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
   6806{
   6807  if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return;
   6808  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return;
   6809  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return;
   6810
   6811  if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
   6812     if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
   6813        static const unsigned char specialtv[] = {
   6814		0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
   6815		0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a,
   6816		0x58,0xe4,0x73,0xda,0x13
   6817	};
   6818	int i, j;
   6819	for(i = 0x1c, j = 0; i <= 0x30; i++, j++) {
   6820	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]);
   6821	}
   6822	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
   6823	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
   6824	   if(SiS_Pr->SiS_TVMode & TVSetPALM) {
   6825	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
   6826	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
   6827	   } else {
   6828	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);  /* 15 */
   6829	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a);  /* 1b */
   6830	   }
   6831	}
   6832     }
   6833  } else {
   6834     if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
   6835        (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
   6836        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);  /* 21 */
   6837        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);  /* 5a */
   6838     } else {
   6839        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a);  /* 21 */
   6840        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53);  /* 5a */
   6841     }
   6842  }
   6843}
   6844
   6845static void
   6846SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
   6847{
   6848  unsigned short temp;
   6849
   6850  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
   6851     if(SiS_Pr->SiS_VGAVDE == 525) {
   6852	temp = 0xc3;
   6853	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
   6854	   temp++;
   6855	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2;
   6856	}
   6857	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
   6858	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
   6859     } else if(SiS_Pr->SiS_VGAVDE == 420) {
   6860	temp = 0x4d;
   6861	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
   6862	   temp++;
   6863	   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++;
   6864	}
   6865	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
   6866     }
   6867  }
   6868
   6869  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   6870     if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
   6871	if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
   6872	   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
   6873	   /* Not always for LV, see SetGrp2 */
   6874	}
   6875	temp = 1;
   6876	if(ModeNo <= 0x13) temp = 3;
   6877	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
   6878     }
   6879#if 0
   6880     /* 651+301C, for 1280x768 - do I really need that? */
   6881     if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
   6882        if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
   6883	   if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
   6884	      ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
   6885	      SiS_SetReg(SiS_Part2Port,0x01,0x2b);
   6886	      SiS_SetReg(SiS_Part2Port,0x02,0x13);
   6887	      SiS_SetReg(SiS_Part2Port,0x04,0xe5);
   6888	      SiS_SetReg(SiS_Part2Port,0x05,0x08);
   6889	      SiS_SetReg(SiS_Part2Port,0x06,0xe2);
   6890	      SiS_SetReg(SiS_Part2Port,0x1c,0x21);
   6891	      SiS_SetReg(SiS_Part2Port,0x1d,0x45);
   6892	      SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
   6893	      SiS_SetReg(SiS_Part2Port,0x20,0x00);
   6894	      SiS_SetReg(SiS_Part2Port,0x21,0xa9);
   6895	      SiS_SetReg(SiS_Part2Port,0x23,0x0b);
   6896	      SiS_SetReg(SiS_Part2Port,0x25,0x04);
   6897	   }
   6898	}
   6899     }
   6900#endif
   6901  }
   6902}
   6903
   6904static void
   6905SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   6906		unsigned short RefreshRateTableIndex)
   6907{
   6908  unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
   6909  unsigned short push2, modeflag, crt2crtc, bridgeoffset;
   6910  unsigned int   longtemp, PhaseIndex;
   6911  bool           newtvphase;
   6912  const unsigned char *TimingPoint;
   6913#ifdef CONFIG_FB_SIS_315
   6914  unsigned short resindex, CRT2Index;
   6915  const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
   6916
   6917  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
   6918#endif
   6919
   6920  if(ModeNo <= 0x13) {
   6921     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   6922     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   6923  } else if(SiS_Pr->UseCustomMode) {
   6924     modeflag = SiS_Pr->CModeFlag;
   6925     crt2crtc = 0;
   6926  } else {
   6927     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   6928     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   6929  }
   6930
   6931  temp = 0;
   6932  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08;
   6933  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04;
   6934  if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)     temp |= 0x02;
   6935  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)  temp |= 0x01;
   6936
   6937  if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) 	      temp |= 0x10;
   6938
   6939  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
   6940
   6941  PhaseIndex  = 0x01; /* SiS_PALPhase */
   6942  TimingPoint = SiS_Pr->SiS_PALTiming;
   6943
   6944  newtvphase = false;
   6945  if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
   6946      ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
   6947	(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
   6948     newtvphase = true;
   6949  }
   6950
   6951  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   6952
   6953     TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
   6954     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   6955        TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
   6956        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
   6957	   TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
   6958        }
   6959     }
   6960
   6961  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   6962
   6963     i = 0;
   6964     if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      i = 2;
   6965     else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1;
   6966
   6967     TimingPoint = &SiS_YPbPrTable[i][0];
   6968
   6969     PhaseIndex = 0x00; /* SiS_NTSCPhase */
   6970
   6971  } else if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   6972
   6973     if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */
   6974
   6975  } else {
   6976
   6977     TimingPoint = SiS_Pr->SiS_NTSCTiming;
   6978     PhaseIndex  = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00;	/* SiS_PALPhase : SiS_NTSCPhase */
   6979     if(newtvphase) PhaseIndex += 8;					/* SiS_PALPhase2 : SiS_NTSCPhase2 */
   6980
   6981  }
   6982
   6983  if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) {
   6984     PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03;	/* SiS_PALMPhase : SiS_PALNPhase */
   6985     if(newtvphase) PhaseIndex += 8;					/* SiS_PALMPhase2 : SiS_PALNPhase2 */
   6986  }
   6987
   6988  if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
   6989     if(SiS_Pr->SiS_TVMode & TVSetPALM) {
   6990        PhaseIndex = 0x05; /* SiS_SpecialPhaseM */
   6991     } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) {
   6992        PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */
   6993     } else {
   6994        PhaseIndex = 0x10; /* SiS_SpecialPhase */
   6995     }
   6996  }
   6997
   6998  for(i = 0x31, j = 0; i <= 0x34; i++, j++) {
   6999     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]);
   7000  }
   7001
   7002  for(i = 0x01, j = 0; i <= 0x2D; i++, j++) {
   7003     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   7004  }
   7005  for(i = 0x39; i <= 0x45; i++, j++) {
   7006     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   7007  }
   7008
   7009  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   7010     if(SiS_Pr->SiS_ModeType != ModeText) {
   7011        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
   7012     }
   7013  }
   7014
   7015  SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
   7016
   7017  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
   7018  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
   7019  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
   7020  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
   7021
   7022  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)	tempax = 950;
   7023  else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  tempax = 680;
   7024  else if(SiS_Pr->SiS_TVMode & TVSetPAL)	tempax = 520;
   7025  else						tempax = 440; /* NTSC, YPbPr 525 */
   7026
   7027  if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) ||
   7028      ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
   7029        ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) {
   7030
   7031     tempax -= SiS_Pr->SiS_VDE;
   7032     tempax >>= 1;
   7033     if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
   7034        tempax >>= 1;
   7035     }
   7036     tempax &= 0x00ff;
   7037
   7038     temp = tempax + (unsigned short)TimingPoint[0];
   7039     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
   7040
   7041     temp = tempax + (unsigned short)TimingPoint[1];
   7042     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
   7043
   7044     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
   7045        if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   7046           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b);
   7047           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54);
   7048        } else {
   7049           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
   7050           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
   7051        }
   7052     }
   7053
   7054  }
   7055
   7056  tempcx = SiS_Pr->SiS_HT;
   7057  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
   7058  tempcx--;
   7059  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--;
   7060  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
   7061  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
   7062
   7063  tempcx = SiS_Pr->SiS_HT >> 1;
   7064  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
   7065  tempcx += 7;
   7066  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
   7067  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
   7068
   7069  tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
   7070  tempbx += tempcx;
   7071  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
   7072  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
   7073
   7074  tempbx += 8;
   7075  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   7076     tempbx -= 4;
   7077     tempcx = tempbx;
   7078  }
   7079  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
   7080
   7081  j += 2;
   7082  tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
   7083  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
   7084  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
   7085
   7086  tempcx += 8;
   7087  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
   7088  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
   7089
   7090  tempcx = SiS_Pr->SiS_HT >> 1;
   7091  if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1;
   7092  j += 2;
   7093  tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
   7094  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
   7095
   7096  tempcx -= 11;
   7097  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
   7098     tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
   7099  }
   7100  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
   7101
   7102  tempbx = SiS_Pr->SiS_VDE;
   7103  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   7104     if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
   7105     if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
   7106     if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
   7107  } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
   7108             (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
   7109     tempbx >>= 1;
   7110     if(SiS_Pr->ChipType >= SIS_315H) {
   7111        if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
   7112	   if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
   7113	} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   7114	   if(SiS_Pr->SiS_ModeType <= ModeVGA) {
   7115	      if(crt2crtc == 4) tempbx++;
   7116	   }
   7117	}
   7118     }
   7119     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   7120        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   7121	   if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
   7122	}
   7123	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
   7124	   if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
   7125        }
   7126     }
   7127  }
   7128  tempbx -= 2;
   7129  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
   7130
   7131  temp = (tempcx >> 8) & 0x0F;
   7132  temp |= ((tempbx >> 2) & 0xC0);
   7133  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
   7134     temp |= 0x10;
   7135     if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
   7136  }
   7137  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
   7138
   7139  if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
   7140     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
   7141  }
   7142
   7143  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   7144     tempbx = SiS_Pr->SiS_VDE;
   7145     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
   7146         (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
   7147        tempbx >>= 1;
   7148     }
   7149     tempbx -= 3;
   7150     temp = ((tempbx >> 3) & 0x60) | 0x18;
   7151     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
   7152     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
   7153
   7154     if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) {
   7155	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
   7156     }
   7157  }
   7158
   7159  tempbx = 0;
   7160  if(!(modeflag & HalfDCLK)) {
   7161     if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
   7162        tempax = 0;
   7163        tempbx |= 0x20;
   7164     }
   7165  }
   7166
   7167  tempch = tempcl = 0x01;
   7168  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   7169     if(SiS_Pr->SiS_VGAHDE >= 960) {
   7170        if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) {
   7171	   tempcl = 0x20;
   7172	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
   7173              tempch = 20;
   7174              tempbx &= ~0x20;
   7175           } else {
   7176	      tempch = 25; /* OK */
   7177	   }
   7178        }
   7179     }
   7180  }
   7181
   7182  if(!(tempbx & 0x20)) {
   7183     if(modeflag & HalfDCLK) tempcl <<= 1;
   7184     longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
   7185     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3;
   7186     tempax = longtemp / SiS_Pr->SiS_HDE;
   7187     if(longtemp % SiS_Pr->SiS_HDE) tempax++;
   7188     tempbx |= ((tempax >> 8) & 0x1F);
   7189     tempcx = tempax >> 13;
   7190  }
   7191
   7192  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
   7193  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
   7194
   7195  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   7196
   7197     tempcx &= 0x07;
   7198     if(tempbx & 0x20) tempcx = 0;
   7199     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
   7200
   7201     if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   7202        tempbx = 0x0382;
   7203        tempcx = 0x007e;
   7204     } else {
   7205        tempbx = 0x0369;
   7206        tempcx = 0x0061;
   7207     }
   7208     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
   7209     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
   7210     temp = (tempcx & 0x0300) >> 6;
   7211     temp |= ((tempbx >> 8) & 0x03);
   7212     if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   7213        temp |= 0x10;
   7214	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)      temp |= 0x20;
   7215	else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40;
   7216     }
   7217     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
   7218
   7219     temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
   7220     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
   7221
   7222     SiS_SetTVSpecial(SiS_Pr, ModeNo);
   7223
   7224     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
   7225        temp = 0;
   7226        if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8;
   7227        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp);
   7228     }
   7229
   7230  }
   7231
   7232  if(SiS_Pr->SiS_TVMode & TVSetPALM) {
   7233     if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
   7234        temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
   7235        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
   7236     }
   7237     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
   7238  }
   7239
   7240  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   7241     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   7242        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
   7243     }
   7244  }
   7245
   7246  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return;
   7247
   7248  /* From here: Part2 LCD setup */
   7249
   7250  tempbx = SiS_Pr->SiS_HDE;
   7251  if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
   7252  tempbx--;			         	/* RHACTE = HDE - 1 */
   7253  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
   7254  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
   7255
   7256  temp = 0x01;
   7257  if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
   7258     if(SiS_Pr->SiS_ModeType == ModeEGA) {
   7259        if(SiS_Pr->SiS_VGAHDE >= 1024) {
   7260           temp = 0x02;
   7261           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
   7262              temp = 0x01;
   7263	   }
   7264        }
   7265     }
   7266  }
   7267  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
   7268
   7269  tempbx = SiS_Pr->SiS_VDE - 1;
   7270  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
   7271  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
   7272
   7273  tempcx = SiS_Pr->SiS_VT - 1;
   7274  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
   7275  temp = (tempcx >> 3) & 0xE0;
   7276  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
   7277     /* Enable dithering; only do this for 32bpp mode */
   7278     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
   7279        temp |= 0x10;
   7280     }
   7281  }
   7282  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
   7283
   7284  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
   7285  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
   7286
   7287  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
   7288  SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
   7289
   7290#ifdef CONFIG_FB_SIS_315
   7291  if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
   7292                          			&CRT2Index, &resindex)) {
   7293      switch(CRT2Index) {
   7294        case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3;    break;
   7295	default:
   7296        case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;   break;
   7297      }
   7298
   7299      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
   7300      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
   7301      for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
   7302        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   7303      }
   7304      for(j = 0x1c; j <= 0x1d; i++, j++ ) {
   7305        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   7306      }
   7307      for(j = 0x1f; j <= 0x21; i++, j++ ) {
   7308        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
   7309      }
   7310      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
   7311      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
   7312
   7313      SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
   7314
   7315  } else {
   7316#endif
   7317
   7318    /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
   7319    /*             Clevo dual-link 1024x768 */
   7320    /* 		   Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct)  */
   7321    /*		   Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
   7322
   7323    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   7324       if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
   7325          tempbx = SiS_Pr->SiS_VDE - 1;
   7326          tempcx = SiS_Pr->SiS_VT - 1;
   7327       } else {
   7328          tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
   7329	  tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
   7330       }
   7331    } else {
   7332       tempbx = SiS_Pr->PanelYRes;
   7333       tempcx = SiS_Pr->SiS_VT;
   7334       tempax = 1;
   7335       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
   7336          tempax = SiS_Pr->PanelYRes;
   7337	  /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c;   */  /* 651+301C */
   7338          if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
   7339             tempax = tempcx = 0;
   7340          } else {
   7341             tempax -= SiS_Pr->SiS_VDE;
   7342          }
   7343          tempax >>= 1;
   7344       }
   7345       tempcx -= tempax; /* lcdvdes */
   7346       tempbx -= tempax; /* lcdvdee */
   7347    }
   7348
   7349    /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
   7350
   7351    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx);	/* lcdvdes  */
   7352    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx);	/* lcdvdee  */
   7353
   7354    temp = (tempbx >> 5) & 0x38;
   7355    temp |= ((tempcx >> 8) & 0x07);
   7356    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
   7357
   7358    tempax = SiS_Pr->SiS_VDE;
   7359    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
   7360       tempax = SiS_Pr->PanelYRes;
   7361    }
   7362    tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
   7363    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
   7364       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
   7365	  tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
   7366       }
   7367    }
   7368
   7369    tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
   7370    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   7371       if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
   7372          if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
   7373             tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
   7374	     if(tempax % 4) { tempax >>= 2; tempax++; }
   7375	     else           { tempax >>= 2;           }
   7376             tempbx -= (tempax - 1);
   7377	  } else {
   7378	     tempbx -= 10;
   7379	     if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
   7380	  }
   7381       }
   7382    }
   7383    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   7384       tempbx++;
   7385       if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
   7386          if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
   7387	     tempbx = 770;
   7388	     tempcx = 3;
   7389	  }
   7390       }
   7391    }
   7392
   7393    /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
   7394
   7395    if(SiS_Pr->UseCustomMode) {
   7396       tempbx = SiS_Pr->CVSyncStart;
   7397    }
   7398
   7399    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);	    /* lcdvrs */
   7400
   7401    temp = (tempbx >> 4) & 0xF0;
   7402    tempbx += (tempcx + 1);
   7403    temp |= (tempbx & 0x0F);
   7404
   7405    if(SiS_Pr->UseCustomMode) {
   7406       temp &= 0xf0;
   7407       temp |= (SiS_Pr->CVSyncEnd & 0x0f);
   7408    }
   7409
   7410    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
   7411
   7412#ifdef CONFIG_FB_SIS_300
   7413    SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
   7414#endif
   7415
   7416    bridgeoffset = 7;
   7417    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)	bridgeoffset += 2;
   7418    if(SiS_Pr->SiS_VBType & VB_SIS30xCLV)	bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */
   7419    if(SiS_IsDualLink(SiS_Pr))			bridgeoffset++;
   7420    else if(SiS_Pr->SiS_VBType & VB_SIS302LV)	bridgeoffset++;    /* OK for Asus A4L 1280x800 */
   7421    /* Higher bridgeoffset shifts to the LEFT */
   7422
   7423    temp = 0;
   7424    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
   7425       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
   7426	  temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
   7427	  if(SiS_IsDualLink(SiS_Pr)) temp >>= 1;
   7428       }
   7429    }
   7430    temp += bridgeoffset;
   7431    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	     /* lcdhdes */
   7432    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
   7433
   7434    tempcx = SiS_Pr->SiS_HT;
   7435    tempax = tempbx = SiS_Pr->SiS_HDE;
   7436    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
   7437       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
   7438          tempax = SiS_Pr->PanelXRes;
   7439          tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
   7440       }
   7441    }
   7442    if(SiS_IsDualLink(SiS_Pr)) {
   7443       tempcx >>= 1;
   7444       tempbx >>= 1;
   7445       tempax >>= 1;
   7446    }
   7447
   7448    tempbx += bridgeoffset;
   7449
   7450    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx);	    /* lcdhdee */
   7451    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
   7452
   7453    tempcx = (tempcx - tempax) >> 2;
   7454
   7455    tempbx += tempcx;
   7456    push2 = tempbx;
   7457
   7458    if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
   7459       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
   7460          if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
   7461             if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
   7462	  }
   7463       }
   7464    }
   7465
   7466    if(SiS_Pr->UseCustomMode) {
   7467       tempbx = SiS_Pr->CHSyncStart;
   7468       if(modeflag & HalfDCLK) tempbx <<= 1;
   7469       if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
   7470       tempbx += bridgeoffset;
   7471    }
   7472
   7473    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx);	    /* lcdhrs */
   7474    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
   7475
   7476    tempbx = push2;
   7477
   7478    tempcx <<= 1;
   7479    if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
   7480       if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
   7481    }
   7482    tempbx += tempcx;
   7483
   7484    if(SiS_Pr->UseCustomMode) {
   7485       tempbx = SiS_Pr->CHSyncEnd;
   7486       if(modeflag & HalfDCLK) tempbx <<= 1;
   7487       if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
   7488       tempbx += bridgeoffset;
   7489    }
   7490
   7491    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx);	    /* lcdhre */
   7492
   7493    SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
   7494
   7495#ifdef CONFIG_FB_SIS_300
   7496    SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
   7497#endif
   7498#ifdef CONFIG_FB_SIS_315
   7499  } /* CRT2-LCD from table */
   7500#endif
   7501}
   7502
   7503/*********************************************/
   7504/*         SET PART 3 REGISTER GROUP         */
   7505/*********************************************/
   7506
   7507static void
   7508SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   7509{
   7510  unsigned short i;
   7511  const unsigned char *tempdi;
   7512
   7513  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
   7514
   7515#ifndef SIS_CP
   7516  SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
   7517#else
   7518  SIS_CP_INIT301_CP
   7519#endif
   7520
   7521  if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   7522     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
   7523     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
   7524  } else {
   7525     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
   7526     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
   7527  }
   7528
   7529  if(SiS_Pr->SiS_TVMode & TVSetPALM) {
   7530     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
   7531     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
   7532     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
   7533  }
   7534
   7535  tempdi = NULL;
   7536  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   7537     tempdi = SiS_Pr->SiS_HiTVGroup3Data;
   7538     if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
   7539        tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
   7540     }
   7541  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
   7542     if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
   7543        tempdi = SiS_HiTVGroup3_1;
   7544        if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2;
   7545     }
   7546  }
   7547  if(tempdi) {
   7548     for(i=0; i<=0x3E; i++) {
   7549        SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
   7550     }
   7551     if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
   7552	if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
   7553	   SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f);
   7554	}
   7555     }
   7556  }
   7557
   7558#ifdef SIS_CP
   7559  SIS_CP_INIT301_CP2
   7560#endif
   7561}
   7562
   7563/*********************************************/
   7564/*         SET PART 4 REGISTER GROUP         */
   7565/*********************************************/
   7566
   7567#ifdef CONFIG_FB_SIS_315
   7568#if 0
   7569static void
   7570SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
   7571{
   7572   unsigned short temp, temp1, temp2;
   7573
   7574   temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
   7575   temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
   7576   temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
   7577   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
   7578   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
   7579   temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
   7580   temp = (unsigned short)((int)(temp) + shift);
   7581   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
   7582   temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
   7583   temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
   7584   temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
   7585   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
   7586   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
   7587}
   7588#endif
   7589
   7590static void
   7591SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   7592{
   7593   unsigned short temp, temp1;
   7594   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   7595
   7596   if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return;
   7597   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
   7598
   7599   if(SiS_Pr->ChipType >= XGI_20) return;
   7600
   7601   if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) {
   7602      if(!(ROMAddr[0x61] & 0x04)) return;
   7603   }
   7604
   7605   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
   7606   temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
   7607   if(!(temp & 0x01)) {
   7608      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf);
   7609      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc);
   7610      if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) {
   7611         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
   7612      }
   7613      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
   7614      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)      temp = 0x0000;
   7615      else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
   7616      else if(SiS_Pr->SiS_TVMode & TVSetHiVision)  temp = 0x0400;
   7617      else					   temp = 0x0402;
   7618      if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
   7619         temp1 = 0;
   7620	 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
   7621	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
   7622	 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
   7623	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
   7624	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
   7625	 if(ModeNo > 0x13) {
   7626            SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd);
   7627         }
   7628      } else {
   7629         temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
   7630	 if(temp1 == 0x01) temp |= 0x01;
   7631	 if(temp1 == 0x03) temp |= 0x04;  /* ? why not 0x10? */
   7632	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
   7633	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
   7634	 if(ModeNo > 0x13) {
   7635            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd);
   7636         }
   7637      }
   7638
   7639#if 0
   7640      if(SiS_Pr->ChipType >= SIS_661) { 		/* ? */
   7641         if(SiS_Pr->SiS_TVMode & TVAspect43) {
   7642            if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
   7643	       if(resinfo == SIS_RI_1024x768) {
   7644	          SiS_ShiftXPos(SiS_Pr, 97);
   7645	       } else {
   7646	          SiS_ShiftXPos(SiS_Pr, 111);
   7647	       }
   7648	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
   7649	       SiS_ShiftXPos(SiS_Pr, 136);
   7650	    }
   7651         }
   7652      }
   7653#endif
   7654
   7655   }
   7656
   7657}
   7658#endif
   7659
   7660static void
   7661SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   7662                 unsigned short RefreshRateTableIndex)
   7663{
   7664  unsigned short vclkindex, temp, reg1, reg2;
   7665
   7666  if(SiS_Pr->UseCustomMode) {
   7667     reg1 = SiS_Pr->CSR2B;
   7668     reg2 = SiS_Pr->CSR2C;
   7669  } else {
   7670     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   7671     reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
   7672     reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
   7673  }
   7674
   7675  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   7676     if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) {
   7677        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
   7678 	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
   7679	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
   7680     } else {
   7681        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
   7682        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
   7683     }
   7684  } else {
   7685     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01);
   7686     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2);
   7687     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1);
   7688  }
   7689  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
   7690  temp = 0x08;
   7691  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
   7692  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
   7693}
   7694
   7695static void
   7696SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr)
   7697{
   7698  if(SiS_Pr->ChipType >= SIS_315H) {
   7699     if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
   7700	if((SiS_CRT2IsLCD(SiS_Pr)) ||
   7701	   (SiS_IsVAMode(SiS_Pr))) {
   7702	   if(SiS_Pr->SiS_LCDInfo & LCDDualLink) {
   7703	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
   7704	   } else {
   7705	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20);
   7706	   }
   7707	}
   7708     }
   7709  }
   7710  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
   7711     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
   7712#ifdef SET_EMI
   7713     SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
   7714#endif
   7715     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
   7716  }
   7717}
   7718
   7719static void
   7720SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   7721		unsigned short RefreshRateTableIndex)
   7722{
   7723  unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo;
   7724  unsigned int   tempebx, tempeax, templong;
   7725
   7726  if(ModeNo <= 0x13) {
   7727     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   7728     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   7729  } else if(SiS_Pr->UseCustomMode) {
   7730     modeflag = SiS_Pr->CModeFlag;
   7731     resinfo = 0;
   7732  } else {
   7733     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   7734     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   7735  }
   7736
   7737  if(SiS_Pr->ChipType >= SIS_315H) {
   7738     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   7739	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   7740	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
   7741	}
   7742     }
   7743  }
   7744
   7745  if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) {
   7746     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   7747	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f);
   7748     }
   7749  }
   7750
   7751  if(SiS_Pr->ChipType >= SIS_315H) {
   7752     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   7753	SiS_SetDualLinkEtc(SiS_Pr);
   7754	return;
   7755     }
   7756  }
   7757
   7758  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
   7759
   7760  tempbx = SiS_Pr->SiS_RVBHCMAX;
   7761  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
   7762
   7763  temp = (tempbx >> 1) & 0x80;
   7764
   7765  tempcx = SiS_Pr->SiS_VGAHT - 1;
   7766  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
   7767
   7768  temp |= ((tempcx >> 5) & 0x78);
   7769
   7770  tempcx = SiS_Pr->SiS_VGAVT - 1;
   7771  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
   7772  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
   7773
   7774  temp |= ((tempcx >> 8) & 0x07);
   7775  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
   7776
   7777  tempbx = SiS_Pr->SiS_VGAHDE;
   7778  if(modeflag & HalfDCLK)    tempbx >>= 1;
   7779  if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
   7780
   7781  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   7782     temp = 0;
   7783     if(tempbx > 800)        temp = 0x60;
   7784  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   7785     temp = 0;
   7786     if(tempbx > 1024)       temp = 0xC0;
   7787     else if(tempbx >= 960)  temp = 0xA0;
   7788  } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
   7789     temp = 0;
   7790     if(tempbx >= 1280)      temp = 0x40;
   7791     else if(tempbx >= 1024) temp = 0x20;
   7792  } else {
   7793     temp = 0x80;
   7794     if(tempbx >= 1024)      temp = 0xA0;
   7795  }
   7796
   7797  temp |= SiS_Pr->Init_P4_0E;
   7798
   7799  if(SiS_Pr->SiS_VBType & VB_SIS301) {
   7800     if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
   7801        temp &= 0xf0;
   7802        temp |= 0x0A;
   7803     }
   7804  }
   7805
   7806  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
   7807
   7808  tempeax = SiS_Pr->SiS_VGAVDE;
   7809  tempebx = SiS_Pr->SiS_VDE;
   7810  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
   7811     if(!(temp & 0xE0)) tempebx >>=1;
   7812  }
   7813
   7814  tempcx = SiS_Pr->SiS_RVBHRS;
   7815  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
   7816  tempcx >>= 8;
   7817  tempcx |= 0x40;
   7818
   7819  if(tempeax <= tempebx) {
   7820     tempcx ^= 0x40;
   7821  } else {
   7822     tempeax -= tempebx;
   7823  }
   7824
   7825  tempeax *= (256 * 1024);
   7826  templong = tempeax % tempebx;
   7827  tempeax /= tempebx;
   7828  if(templong) tempeax++;
   7829
   7830  temp = (unsigned short)(tempeax & 0x000000FF);
   7831  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
   7832  temp = (unsigned short)((tempeax & 0x0000FF00) >> 8);
   7833  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
   7834  temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */
   7835  temp |= (tempcx & 0x4F);
   7836  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
   7837
   7838  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   7839
   7840     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
   7841
   7842     /* Calc Linebuffer max address and set/clear decimode */
   7843     tempbx = 0;
   7844     if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
   7845     tempax = SiS_Pr->SiS_VGAHDE;
   7846     if(modeflag & HalfDCLK)    tempax >>= 1;
   7847     if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1;
   7848     if(tempax > 800) {
   7849        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   7850	   tempax -= 800;
   7851	} else {
   7852	   tempbx = 0x08;
   7853	   if(tempax == 960)	   tempax *= 25; /* Correct */
   7854           else if(tempax == 1024) tempax *= 25;
   7855           else			   tempax *= 20;
   7856	   temp = tempax % 32;
   7857	   tempax /= 32;
   7858	   if(temp) tempax++;
   7859	   tempax++;
   7860	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   7861	      if(resinfo == SIS_RI_1024x768 ||
   7862	         resinfo == SIS_RI_1024x576 ||
   7863		 resinfo == SIS_RI_1280x1024 ||
   7864		 resinfo == SIS_RI_1280x720) {
   7865	         /* Otherwise white line or garbage at right edge */
   7866	         tempax = (tempax & 0xff00) | 0x20;
   7867	      }
   7868	   }
   7869	}
   7870     }
   7871     tempax--;
   7872     temp = ((tempax >> 4) & 0x30) | tempbx;
   7873     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
   7874     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
   7875
   7876     temp = 0x0036; tempbx = 0xD0;
   7877     if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
   7878	temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
   7879     }
   7880     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   7881        if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
   7882	   temp |= 0x01;
   7883	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   7884	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
   7885  	         temp &= ~0x01;
   7886	      }
   7887	   }
   7888	}
   7889     }
   7890     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
   7891
   7892     tempbx = SiS_Pr->SiS_HT >> 1;
   7893     if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1;
   7894     tempbx -= 2;
   7895     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
   7896     temp = (tempbx >> 5) & 0x38;
   7897     SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
   7898
   7899     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
   7900	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   7901           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
   7902	   /* LCD-too-dark-error-source, see FinalizeLCD() */
   7903	}
   7904     }
   7905
   7906     SiS_SetDualLinkEtc(SiS_Pr);
   7907
   7908  }  /* 301B */
   7909
   7910  SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   7911}
   7912
   7913/*********************************************/
   7914/*         SET PART 5 REGISTER GROUP         */
   7915/*********************************************/
   7916
   7917static void
   7918SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
   7919{
   7920
   7921  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
   7922
   7923  if(SiS_Pr->SiS_ModeType == ModeVGA) {
   7924     if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
   7925        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
   7926        SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
   7927     }
   7928  }
   7929}
   7930
   7931/*********************************************/
   7932/*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
   7933/*********************************************/
   7934
   7935static bool
   7936SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   7937		   unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
   7938		   unsigned short *DisplayType)
   7939 {
   7940  unsigned short modeflag = 0;
   7941  bool checkhd = true;
   7942
   7943  /* Pass 1:1 not supported here */
   7944
   7945  if(ModeNo <= 0x13) {
   7946     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   7947     (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   7948  } else {
   7949     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   7950     (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   7951  }
   7952
   7953  (*ResIndex) &= 0x3F;
   7954
   7955  if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
   7956
   7957     (*DisplayType) = 80;
   7958     if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
   7959      	(*DisplayType) = 82;
   7960	if(SiS_Pr->SiS_ModeType > ModeVGA) {
   7961	   if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84;
   7962	}
   7963     }
   7964     if((*DisplayType) != 84) {
   7965        if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
   7966     }
   7967
   7968  } else {
   7969
   7970     (*DisplayType = 0);
   7971     switch(SiS_Pr->SiS_LCDResInfo) {
   7972     case Panel_320x240_1: (*DisplayType) = 50;
   7973			   checkhd = false;
   7974			   break;
   7975     case Panel_320x240_2: (*DisplayType) = 14;
   7976			   break;
   7977     case Panel_320x240_3: (*DisplayType) = 18;
   7978			   break;
   7979     case Panel_640x480:   (*DisplayType) = 10;
   7980			   break;
   7981     case Panel_1024x600:  (*DisplayType) = 26;
   7982			   break;
   7983     default: return true;
   7984     }
   7985
   7986     if(checkhd) {
   7987        if(modeflag & HalfDCLK) (*DisplayType)++;
   7988     }
   7989
   7990     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
   7991        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
   7992     }
   7993
   7994  }
   7995
   7996  return true;
   7997}
   7998
   7999static void
   8000SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   8001                unsigned short RefreshRateTableIndex)
   8002{
   8003  unsigned short tempah, i, modeflag, j, ResIndex, DisplayType;
   8004  const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL;
   8005  static const unsigned short CRIdx[] = {
   8006	0x00, 0x02, 0x03, 0x04, 0x05, 0x06,
   8007	0x07, 0x10, 0x11, 0x15, 0x16
   8008  };
   8009
   8010  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
   8011     (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
   8012     (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
   8013     (SiS_Pr->SiS_CustomT == CUT_PANEL856) )
   8014     return;
   8015
   8016  if(SiS_Pr->SiS_IF_DEF_LVDS) {
   8017     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   8018        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
   8019     }
   8020  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
   8021     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return;
   8022  } else return;
   8023
   8024  if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
   8025
   8026  if(SiS_Pr->ChipType < SIS_315H) {
   8027     if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
   8028  }
   8029
   8030  if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
   8031                          &ResIndex, &DisplayType))) {
   8032     return;
   8033  }
   8034
   8035  switch(DisplayType) {
   8036    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1;           break; /* xSTN */
   8037    case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2;           break; /* xSTN */
   8038    case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H;         break; /* xSTN */
   8039    case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3;           break; /* xSTN */
   8040    case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H;         break; /* xSTN */
   8041    case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
   8042    case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
   8043#if 0 /* Works better with calculated numbers */
   8044    case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
   8045    case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
   8046    case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
   8047    case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
   8048#endif
   8049    case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
   8050    case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
   8051    case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
   8052    case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
   8053    case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
   8054  }
   8055
   8056  if(LVDSCRT1Ptr) {
   8057
   8058     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
   8059
   8060     for(i = 0; i <= 10; i++) {
   8061        tempah = (LVDSCRT1Ptr + ResIndex)->CR[i];
   8062        SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah);
   8063     }
   8064
   8065     for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) {
   8066        tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
   8067        SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
   8068     }
   8069
   8070     tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0;
   8071     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
   8072
   8073     if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   8074     else               modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   8075
   8076     tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5;
   8077     if(modeflag & DoubleScanMode) tempah |= 0x80;
   8078     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
   8079
   8080  } else {
   8081
   8082     SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
   8083
   8084  }
   8085}
   8086
   8087/*********************************************/
   8088/*              SET CRT2 ECLK                */
   8089/*********************************************/
   8090
   8091static void
   8092SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   8093           unsigned short RefreshRateTableIndex)
   8094{
   8095  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   8096  unsigned short clkbase, vclkindex = 0;
   8097  unsigned char  sr2b, sr2c;
   8098
   8099  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
   8100     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
   8101     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) {
   8102	RefreshRateTableIndex--;
   8103     }
   8104     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
   8105                                    RefreshRateTableIndex);
   8106     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   8107  } else {
   8108     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
   8109                                    RefreshRateTableIndex);
   8110  }
   8111
   8112  sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
   8113  sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
   8114
   8115  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
   8116     if(SiS_Pr->SiS_UseROM) {
   8117	if(ROMAddr[0x220] & 0x01) {
   8118	   sr2b = ROMAddr[0x227];
   8119	   sr2c = ROMAddr[0x228];
   8120	}
   8121     }
   8122  }
   8123
   8124  clkbase = 0x02B;
   8125  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
   8126     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
   8127	clkbase += 3;
   8128     }
   8129  }
   8130
   8131  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
   8132  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
   8133  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
   8134  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
   8135  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
   8136  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
   8137  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
   8138  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
   8139  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
   8140}
   8141
   8142/*********************************************/
   8143/*           SET UP CHRONTEL CHIPS           */
   8144/*********************************************/
   8145
   8146static void
   8147SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
   8148               unsigned short RefreshRateTableIndex)
   8149{
   8150   unsigned short TVType, resindex;
   8151   const struct SiS_CHTVRegData *CHTVRegData = NULL;
   8152
   8153   if(ModeNo <= 0x13)
   8154      resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   8155   else
   8156      resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   8157
   8158   resindex &= 0x3F;
   8159
   8160   TVType = 0;
   8161   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
   8162   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   8163      TVType += 2;
   8164      if(SiS_Pr->SiS_ModeType > ModeVGA) {
   8165	 if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
   8166      }
   8167      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
   8168	 TVType = 4;
   8169	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
   8170      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
   8171	 TVType = 6;
   8172	 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
   8173      }
   8174   }
   8175
   8176   switch(TVType) {
   8177      case  0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
   8178      case  1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
   8179      case  2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL;  break;
   8180      case  3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
   8181      case  4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
   8182      case  5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
   8183      case  6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
   8184      case  7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
   8185      case  8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
   8186      default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL;  break;
   8187   }
   8188
   8189
   8190   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
   8191
   8192#ifdef CONFIG_FB_SIS_300
   8193
   8194      /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
   8195
   8196      /* We don't support modes >800x600 */
   8197      if (resindex > 5) return;
   8198
   8199      if(SiS_Pr->SiS_TVMode & TVSetPAL) {
   8200	 SiS_SetCH700x(SiS_Pr,0x04,0x43);  /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
   8201	 SiS_SetCH700x(SiS_Pr,0x09,0x69);  /* Black level for PAL (105)*/
   8202      } else {
   8203	 SiS_SetCH700x(SiS_Pr,0x04,0x03);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
   8204	 SiS_SetCH700x(SiS_Pr,0x09,0x71);   /* Black level for NTSC (113)*/
   8205      }
   8206
   8207      SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]);	/* Mode register */
   8208      SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]);	/* Start active video register */
   8209      SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]);	/* Position overflow register */
   8210      SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]);	/* Horiz Position register */
   8211      SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]);	/* Vertical Position register */
   8212
   8213      /* Set minimum flicker filter for Luma channel (SR1-0=00),
   8214                minimum text enhancement (S3-2=10),
   8215   	        maximum flicker filter for Chroma channel (S5-4=10)
   8216	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
   8217       */
   8218      SiS_SetCH700x(SiS_Pr,0x01,0x28);
   8219
   8220      /* Set video bandwidth
   8221            High bandwidth Luma composite video filter(S0=1)
   8222            low bandwidth Luma S-video filter (S2-1=00)
   8223	    disable peak filter in S-video channel (S3=0)
   8224	    high bandwidth Chroma Filter (S5-4=11)
   8225	    =00110001=0x31
   8226      */
   8227      SiS_SetCH700x(SiS_Pr,0x03,0xb1);       /* old: 3103 */
   8228
   8229      /* Register 0x3D does not exist in non-macrovision register map
   8230            (Maybe this is a macrovision register?)
   8231       */
   8232#ifndef SIS_CP
   8233      SiS_SetCH70xx(SiS_Pr,0x3d,0x00);
   8234#endif
   8235
   8236      /* Register 0x10 only contains 1 writable bit (S0) for sensing,
   8237             all other bits a read-only. Macrovision?
   8238       */
   8239      SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F);
   8240
   8241      /* Register 0x11 only contains 3 writable bits (S0-S2) for
   8242             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
   8243       */
   8244      SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8);
   8245
   8246      /* Clear DSEN
   8247       */
   8248      SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF);
   8249
   8250      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {		/* ---- NTSC ---- */
   8251         if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) {
   8252            if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
   8253      	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
   8254               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on, no need to set FSCI */
   8255            } else if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
   8256               SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
   8257               SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0);
   8258               SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0);
   8259               SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0);
   8260               SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0);
   8261               SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0);
   8262               SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0);
   8263               SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0);
   8264               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF);	/* Loop filter on for mode 23 */
   8265               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	/* ACIV off, need to set FSCI */
   8266            }
   8267         } else {
   8268            if(resindex == 0x04) {     			/* ----- 640x480 underscan; Mode 17 */
   8269               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
   8270               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
   8271            } else if(resindex == 0x05) {   		/* ----- 800x600 underscan: Mode 24 */
   8272#if 0
   8273               SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0);	/* (FSCI was 0x1f1c71c7 - this is for mode 22) */
   8274               SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0);	/* FSCI for mode 24 is 428,554,851 */
   8275               SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0);       /* 198b3a63 */
   8276               SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0);
   8277               SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0);
   8278               SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0);
   8279               SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0);
   8280               SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0);
   8281               SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off for mode 24 */
   8282               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE);	* ACIV off, need to set FSCI */
   8283#endif         /* All alternatives wrong (datasheet wrong?), don't use FSCI */
   8284	       SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	 /* loop filter off */
   8285               SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);
   8286            }
   8287         }
   8288      } else {						/* ---- PAL ---- */
   8289	/* We don't play around with FSCI in PAL mode */
   8290	SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);	/* loop filter off */
   8291	SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);	/* ACIV on */
   8292      }
   8293
   8294#endif  /* 300 */
   8295
   8296   } else {
   8297
   8298      /* Chrontel 7019 - assumed that it does not come with a 300 series chip */
   8299
   8300#ifdef CONFIG_FB_SIS_315
   8301
   8302      unsigned short temp;
   8303
   8304      /* We don't support modes >1024x768 */
   8305      if (resindex > 6) return;
   8306
   8307      temp = CHTVRegData[resindex].Reg[0];
   8308      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10;
   8309      SiS_SetCH701x(SiS_Pr,0x00,temp);
   8310
   8311      SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]);
   8312      SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]);
   8313      SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]);
   8314      SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]);
   8315      SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]);
   8316      SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]);
   8317
   8318      temp = CHTVRegData[resindex].Reg[7];
   8319      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66;
   8320      SiS_SetCH701x(SiS_Pr,0x07,temp);
   8321
   8322      SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]);
   8323      SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]);
   8324      SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]);
   8325      SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]);
   8326      SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]);
   8327      SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]);
   8328      SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]);
   8329      SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]);
   8330
   8331      temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02;
   8332      /* D1 should be set for PAL, PAL-N and NTSC-J,
   8333         but I won't do that for PAL unless somebody
   8334	 tells me to do so. Since the BIOS uses
   8335	 non-default CIV values and blacklevels,
   8336	 this might be compensated anyway.
   8337       */
   8338      if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02;
   8339      SiS_SetCH701x(SiS_Pr,0x21,temp);
   8340
   8341#endif	/* 315 */
   8342
   8343   }
   8344
   8345#ifdef SIS_CP
   8346   SIS_CP_INIT301_CP3
   8347#endif
   8348
   8349}
   8350
   8351#ifdef CONFIG_FB_SIS_315  /* ----------- 315 series only ---------- */
   8352
   8353void
   8354SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
   8355{
   8356   unsigned short temp;
   8357
   8358   /* Enable Chrontel 7019 LCD panel backlight */
   8359   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   8360      if(SiS_Pr->ChipType == SIS_740) {
   8361	 SiS_SetCH701x(SiS_Pr,0x66,0x65);
   8362      } else {
   8363	 temp = SiS_GetCH701x(SiS_Pr,0x66);
   8364	 temp |= 0x20;
   8365	 SiS_SetCH701x(SiS_Pr,0x66,temp);
   8366      }
   8367   }
   8368}
   8369
   8370void
   8371SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr)
   8372{
   8373   unsigned short temp;
   8374
   8375   /* Disable Chrontel 7019 LCD panel backlight */
   8376   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   8377      temp = SiS_GetCH701x(SiS_Pr,0x66);
   8378      temp &= 0xDF;
   8379      SiS_SetCH701x(SiS_Pr,0x66,temp);
   8380   }
   8381}
   8382
   8383static void
   8384SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr)
   8385{
   8386  static const unsigned char regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
   8387  static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
   8388  static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
   8389  static const unsigned char asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
   8390  static const unsigned char asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
   8391  static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
   8392  static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
   8393  const unsigned char *tableptr = NULL;
   8394  int i;
   8395
   8396  /* Set up Power up/down timing */
   8397
   8398  if(SiS_Pr->ChipType == SIS_740) {
   8399     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   8400	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
   8401	else    			          tableptr = table1024_740;
   8402     } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
   8403	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
   8404	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
   8405	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
   8406        else					  tableptr = table1400_740;
   8407     } else return;
   8408  } else {
   8409     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
   8410	tableptr = table1024_650;
   8411     } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
   8412	       (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
   8413	       (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
   8414	tableptr = table1400_650;
   8415     } else return;
   8416  }
   8417
   8418  for(i=0; i<5; i++) {
   8419     SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
   8420  }
   8421}
   8422
   8423static void
   8424SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr)
   8425{
   8426  const unsigned char *tableptr = NULL;
   8427  unsigned short tempbh;
   8428  int i;
   8429  static const unsigned char regtable[] = {
   8430		0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
   8431		0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66
   8432  };
   8433  static const unsigned char table1024_740[] = {
   8434		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
   8435		0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44
   8436  };
   8437  static const unsigned char table1280_740[] = {
   8438		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
   8439		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
   8440  };
   8441  static const unsigned char table1400_740[] = {
   8442		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
   8443		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44
   8444  };
   8445  static const unsigned char table1600_740[] = {
   8446		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
   8447		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44
   8448  };
   8449  static const unsigned char table1024_650[] = {
   8450		0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
   8451		0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02
   8452  };
   8453  static const unsigned char table1280_650[] = {
   8454		0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
   8455		0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02
   8456  };
   8457  static const unsigned char table1400_650[] = {
   8458		0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
   8459		0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02
   8460  };
   8461  static const unsigned char table1600_650[] = {
   8462		0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
   8463		0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a
   8464  };
   8465
   8466  if(SiS_Pr->ChipType == SIS_740) {
   8467     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_740;
   8468     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
   8469     else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
   8470     else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
   8471     else return;
   8472  } else {
   8473     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)       tableptr = table1024_650;
   8474     else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
   8475     else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
   8476     else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
   8477     else return;
   8478  }
   8479
   8480  tempbh = SiS_GetCH701x(SiS_Pr,0x74);
   8481  if((tempbh == 0xf6) || (tempbh == 0xc7)) {
   8482     tempbh = SiS_GetCH701x(SiS_Pr,0x73);
   8483     if(tempbh == 0xc8) {
   8484        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
   8485     } else if(tempbh == 0xdb) {
   8486        if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
   8487	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
   8488     } else if(tempbh == 0xde) {
   8489        if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
   8490     }
   8491  }
   8492
   8493  if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d;
   8494  else     			  tempbh = 0x0c;
   8495
   8496  for(i = 0; i < tempbh; i++) {
   8497     SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]);
   8498  }
   8499  SiS_ChrontelPowerSequencing(SiS_Pr);
   8500  tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
   8501  tempbh |= 0xc0;
   8502  SiS_SetCH701x(SiS_Pr,0x1e,tempbh);
   8503
   8504  if(SiS_Pr->ChipType == SIS_740) {
   8505     tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
   8506     tempbh &= 0xfb;
   8507     SiS_SetCH701x(SiS_Pr,0x1c,tempbh);
   8508     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
   8509     tempbh = SiS_GetCH701x(SiS_Pr,0x64);
   8510     tempbh |= 0x40;
   8511     SiS_SetCH701x(SiS_Pr,0x64,tempbh);
   8512     tempbh = SiS_GetCH701x(SiS_Pr,0x03);
   8513     tempbh &= 0x3f;
   8514     SiS_SetCH701x(SiS_Pr,0x03,tempbh);
   8515  }
   8516}
   8517
   8518static void
   8519SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr)
   8520{
   8521  unsigned char temp, temp1;
   8522
   8523  temp1 = SiS_GetCH701x(SiS_Pr,0x49);
   8524  SiS_SetCH701x(SiS_Pr,0x49,0x3e);
   8525  temp = SiS_GetCH701x(SiS_Pr,0x47);
   8526  temp &= 0x7f;	/* Use external VSYNC */
   8527  SiS_SetCH701x(SiS_Pr,0x47,temp);
   8528  SiS_LongDelay(SiS_Pr, 3);
   8529  temp = SiS_GetCH701x(SiS_Pr,0x47);
   8530  temp |= 0x80;	/* Use internal VSYNC */
   8531  SiS_SetCH701x(SiS_Pr,0x47,temp);
   8532  SiS_SetCH701x(SiS_Pr,0x49,temp1);
   8533}
   8534
   8535static void
   8536SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr)
   8537{
   8538  unsigned short temp;
   8539
   8540  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   8541     if(SiS_Pr->ChipType == SIS_740) {
   8542        temp = SiS_GetCH701x(SiS_Pr,0x1c);
   8543        temp |= 0x04;	/* Invert XCLK phase */
   8544        SiS_SetCH701x(SiS_Pr,0x1c,temp);
   8545     }
   8546     if(SiS_IsYPbPr(SiS_Pr)) {
   8547        temp = SiS_GetCH701x(SiS_Pr,0x01);
   8548	temp &= 0x3f;
   8549	temp |= 0x80;	/* Enable YPrPb (HDTV) */
   8550	SiS_SetCH701x(SiS_Pr,0x01,temp);
   8551     }
   8552     if(SiS_IsChScart(SiS_Pr)) {
   8553        temp = SiS_GetCH701x(SiS_Pr,0x01);
   8554	temp &= 0x3f;
   8555	temp |= 0xc0;	/* Enable SCART + CVBS */
   8556	SiS_SetCH701x(SiS_Pr,0x01,temp);
   8557     }
   8558     if(SiS_Pr->ChipType == SIS_740) {
   8559        SiS_ChrontelResetVSync(SiS_Pr);
   8560        SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
   8561     } else {
   8562        SiS_SetCH701x(SiS_Pr,0x49,0x20);   /* Enable TV path */
   8563        temp = SiS_GetCH701x(SiS_Pr,0x49);
   8564        if(SiS_IsYPbPr(SiS_Pr)) {
   8565           temp = SiS_GetCH701x(SiS_Pr,0x73);
   8566	   temp |= 0x60;
   8567	   SiS_SetCH701x(SiS_Pr,0x73,temp);
   8568        }
   8569        temp = SiS_GetCH701x(SiS_Pr,0x47);
   8570        temp &= 0x7f;
   8571        SiS_SetCH701x(SiS_Pr,0x47,temp);
   8572        SiS_LongDelay(SiS_Pr, 2);
   8573        temp = SiS_GetCH701x(SiS_Pr,0x47);
   8574        temp |= 0x80;
   8575        SiS_SetCH701x(SiS_Pr,0x47,temp);
   8576     }
   8577  }
   8578}
   8579
   8580static void
   8581SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr)
   8582{
   8583  unsigned short temp;
   8584
   8585  /* Complete power down of LVDS */
   8586  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   8587     if(SiS_Pr->ChipType == SIS_740) {
   8588        SiS_LongDelay(SiS_Pr, 1);
   8589	SiS_GenericDelay(SiS_Pr, 5887);
   8590	SiS_SetCH701x(SiS_Pr,0x76,0xac);
   8591	SiS_SetCH701x(SiS_Pr,0x66,0x00);
   8592     } else {
   8593        SiS_LongDelay(SiS_Pr, 2);
   8594	temp = SiS_GetCH701x(SiS_Pr,0x76);
   8595	temp &= 0xfc;
   8596	SiS_SetCH701x(SiS_Pr,0x76,temp);
   8597	SiS_SetCH701x(SiS_Pr,0x66,0x00);
   8598     }
   8599  }
   8600}
   8601
   8602static void
   8603SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr)
   8604{
   8605     unsigned short temp;
   8606
   8607     if(SiS_Pr->ChipType == SIS_740) {
   8608
   8609        temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
   8610        temp &= 0x01;
   8611        if(!temp) {
   8612
   8613           if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
   8614	      temp = SiS_GetCH701x(SiS_Pr,0x49);
   8615	      SiS_SetCH701x(SiS_Pr,0x49,0x3e);
   8616	   }
   8617
   8618	   /* Reset Chrontel 7019 datapath */
   8619           SiS_SetCH701x(SiS_Pr,0x48,0x10);
   8620           SiS_LongDelay(SiS_Pr, 1);
   8621           SiS_SetCH701x(SiS_Pr,0x48,0x18);
   8622
   8623	   if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
   8624	      SiS_ChrontelResetVSync(SiS_Pr);
   8625	      SiS_SetCH701x(SiS_Pr,0x49,temp);
   8626	   }
   8627
   8628        } else {
   8629
   8630	   /* Clear/set/clear GPIO */
   8631           temp = SiS_GetCH701x(SiS_Pr,0x5c);
   8632	   temp &= 0xef;
   8633	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
   8634	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
   8635	   temp |= 0x10;
   8636	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
   8637	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
   8638	   temp &= 0xef;
   8639	   SiS_SetCH701x(SiS_Pr,0x5c,temp);
   8640	   temp = SiS_GetCH701x(SiS_Pr,0x61);
   8641	   if(!temp) {
   8642	      SiS_SetCH701xForLCD(SiS_Pr);
   8643	   }
   8644        }
   8645
   8646     } else { /* 650 */
   8647        /* Reset Chrontel 7019 datapath */
   8648        SiS_SetCH701x(SiS_Pr,0x48,0x10);
   8649        SiS_LongDelay(SiS_Pr, 1);
   8650        SiS_SetCH701x(SiS_Pr,0x48,0x18);
   8651     }
   8652}
   8653
   8654static void
   8655SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr)
   8656{
   8657     unsigned short temp;
   8658
   8659     if(SiS_Pr->ChipType == SIS_740) {
   8660
   8661        if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
   8662           SiS_ChrontelResetVSync(SiS_Pr);
   8663        }
   8664
   8665     } else {
   8666
   8667        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* Power up LVDS block */
   8668        temp = SiS_GetCH701x(SiS_Pr,0x49);
   8669        temp &= 1;
   8670        if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
   8671	   temp = SiS_GetCH701x(SiS_Pr,0x47);
   8672	   temp &= 0x70;
   8673	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* enable VSYNC */
   8674	   SiS_LongDelay(SiS_Pr, 3);
   8675	   temp = SiS_GetCH701x(SiS_Pr,0x47);
   8676	   temp |= 0x80;
   8677	   SiS_SetCH701x(SiS_Pr,0x47,temp);  /* disable VSYNC */
   8678        }
   8679
   8680     }
   8681}
   8682
   8683static void
   8684SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
   8685{
   8686     unsigned short temp,temp1;
   8687
   8688     if(SiS_Pr->ChipType == SIS_740) {
   8689
   8690        temp = SiS_GetCH701x(SiS_Pr,0x61);
   8691        if(temp < 1) {
   8692           temp++;
   8693	   SiS_SetCH701x(SiS_Pr,0x61,temp);
   8694        }
   8695        SiS_SetCH701x(SiS_Pr,0x66,0x45);  /* Panel power on */
   8696        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on */
   8697        SiS_LongDelay(SiS_Pr, 1);
   8698        SiS_GenericDelay(SiS_Pr, 5887);
   8699
   8700     } else {  /* 650 */
   8701
   8702        temp1 = 0;
   8703        temp = SiS_GetCH701x(SiS_Pr,0x61);
   8704        if(temp < 2) {
   8705           temp++;
   8706	   SiS_SetCH701x(SiS_Pr,0x61,temp);
   8707	   temp1 = 1;
   8708        }
   8709        SiS_SetCH701x(SiS_Pr,0x76,0xac);
   8710        temp = SiS_GetCH701x(SiS_Pr,0x66);
   8711        temp |= 0x5f;
   8712        SiS_SetCH701x(SiS_Pr,0x66,temp);
   8713        if(ModeNo > 0x13) {
   8714           if(SiS_WeHaveBacklightCtrl(SiS_Pr)) {
   8715	      SiS_GenericDelay(SiS_Pr, 1023);
   8716	   } else {
   8717	      SiS_GenericDelay(SiS_Pr, 767);
   8718	   }
   8719        } else {
   8720           if(!temp1)
   8721	      SiS_GenericDelay(SiS_Pr, 767);
   8722        }
   8723        temp = SiS_GetCH701x(SiS_Pr,0x76);
   8724        temp |= 0x03;
   8725        SiS_SetCH701x(SiS_Pr,0x76,temp);
   8726        temp = SiS_GetCH701x(SiS_Pr,0x66);
   8727        temp &= 0x7f;
   8728        SiS_SetCH701x(SiS_Pr,0x66,temp);
   8729        SiS_LongDelay(SiS_Pr, 1);
   8730
   8731     }
   8732}
   8733
   8734static void
   8735SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr)
   8736{
   8737     unsigned short temp;
   8738
   8739     SiS_LongDelay(SiS_Pr, 1);
   8740
   8741     do {
   8742       temp = SiS_GetCH701x(SiS_Pr,0x66);
   8743       temp &= 0x04;  /* PLL stable? -> bail out */
   8744       if(temp == 0x04) break;
   8745
   8746       if(SiS_Pr->ChipType == SIS_740) {
   8747          /* Power down LVDS output, PLL normal operation */
   8748          SiS_SetCH701x(SiS_Pr,0x76,0xac);
   8749       }
   8750
   8751       SiS_SetCH701xForLCD(SiS_Pr);
   8752
   8753       temp = SiS_GetCH701x(SiS_Pr,0x76);
   8754       temp &= 0xfb;  /* Reset PLL */
   8755       SiS_SetCH701x(SiS_Pr,0x76,temp);
   8756       SiS_LongDelay(SiS_Pr, 2);
   8757       temp = SiS_GetCH701x(SiS_Pr,0x76);
   8758       temp |= 0x04;  /* PLL normal operation */
   8759       SiS_SetCH701x(SiS_Pr,0x76,temp);
   8760       if(SiS_Pr->ChipType == SIS_740) {
   8761          SiS_SetCH701x(SiS_Pr,0x78,0xe0);	/* PLL loop filter */
   8762       } else {
   8763          SiS_SetCH701x(SiS_Pr,0x78,0x60);
   8764       }
   8765       SiS_LongDelay(SiS_Pr, 2);
   8766    } while(0);
   8767
   8768    SiS_SetCH701x(SiS_Pr,0x77,0x00);  /* MV? */
   8769}
   8770
   8771static void
   8772SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
   8773{
   8774     unsigned short temp;
   8775
   8776     temp = SiS_GetCH701x(SiS_Pr,0x03);
   8777     temp |= 0x80;	/* Set datapath 1 to TV   */
   8778     temp &= 0xbf;	/* Set datapath 2 to LVDS */
   8779     SiS_SetCH701x(SiS_Pr,0x03,temp);
   8780
   8781     if(SiS_Pr->ChipType == SIS_740) {
   8782
   8783        temp = SiS_GetCH701x(SiS_Pr,0x1c);
   8784        temp &= 0xfb;	/* Normal XCLK phase */
   8785        SiS_SetCH701x(SiS_Pr,0x1c,temp);
   8786
   8787        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
   8788
   8789        temp = SiS_GetCH701x(SiS_Pr,0x64);
   8790        temp |= 0x40;	/* ? Bit not defined */
   8791        SiS_SetCH701x(SiS_Pr,0x64,temp);
   8792
   8793        temp = SiS_GetCH701x(SiS_Pr,0x03);
   8794        temp &= 0x3f;	/* D1 input to both LVDS and TV */
   8795        SiS_SetCH701x(SiS_Pr,0x03,temp);
   8796
   8797	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
   8798	   SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */
   8799	   SiS_LongDelay(SiS_Pr, 1);
   8800	   SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */
   8801	   SiS_ChrontelResetDB(SiS_Pr);
   8802	   SiS_ChrontelDoSomething2(SiS_Pr);
   8803	   SiS_ChrontelDoSomething3(SiS_Pr, 0);
   8804	} else {
   8805           temp = SiS_GetCH701x(SiS_Pr,0x66);
   8806           if(temp != 0x45) {
   8807              SiS_ChrontelResetDB(SiS_Pr);
   8808              SiS_ChrontelDoSomething2(SiS_Pr);
   8809              SiS_ChrontelDoSomething3(SiS_Pr, 0);
   8810           }
   8811	}
   8812
   8813     } else { /* 650 */
   8814
   8815        SiS_ChrontelResetDB(SiS_Pr);
   8816        SiS_ChrontelDoSomething2(SiS_Pr);
   8817        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
   8818        SiS_ChrontelDoSomething3(SiS_Pr,temp);
   8819        SiS_SetCH701x(SiS_Pr,0x76,0xaf);  /* All power on, LVDS normal operation */
   8820
   8821     }
   8822
   8823}
   8824#endif  /* 315 series  */
   8825
   8826/*********************************************/
   8827/*      MAIN: SET CRT2 REGISTER GROUP        */
   8828/*********************************************/
   8829
   8830bool
   8831SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
   8832{
   8833#ifdef CONFIG_FB_SIS_300
   8834   unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
   8835#endif
   8836   unsigned short ModeIdIndex, RefreshRateTableIndex;
   8837
   8838   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   8839
   8840   if(!SiS_Pr->UseCustomMode) {
   8841      SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
   8842   } else {
   8843      ModeIdIndex = 0;
   8844   }
   8845
   8846   /* Used for shifting CR33 */
   8847   SiS_Pr->SiS_SelectCRT2Rate = 4;
   8848
   8849   SiS_UnLockCRT2(SiS_Pr);
   8850
   8851   RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex);
   8852
   8853   SiS_SaveCRT2Info(SiS_Pr,ModeNo);
   8854
   8855   if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8856      SiS_DisableBridge(SiS_Pr);
   8857      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) {
   8858         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
   8859      }
   8860      SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex);
   8861   }
   8862
   8863   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
   8864      SiS_LockCRT2(SiS_Pr);
   8865      SiS_DisplayOn(SiS_Pr);
   8866      return true;
   8867   }
   8868
   8869   SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8870
   8871   /* Set up Panel Link for LVDS and LCDA */
   8872   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
   8873   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
   8874       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
   8875       ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) {
   8876      SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8877   }
   8878
   8879   if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8880      SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8881   }
   8882
   8883   if(SiS_Pr->SiS_VBType & VB_SISVB) {
   8884
   8885      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8886
   8887	 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8888#ifdef CONFIG_FB_SIS_315
   8889	 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8890#endif
   8891	 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
   8892	 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8893#ifdef CONFIG_FB_SIS_315
   8894	 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
   8895#endif
   8896	 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
   8897
   8898	 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
   8899
   8900	 /* For 301BDH (Panel link initialization): */
   8901	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
   8902
   8903	    if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
   8904	       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
   8905		  SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8906	       }
   8907            }
   8908	    SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8909	 }
   8910      }
   8911
   8912   } else {
   8913
   8914      SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex);
   8915
   8916      SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
   8917
   8918      SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
   8919
   8920      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8921	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
   8922	    if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
   8923	       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
   8924#ifdef CONFIG_FB_SIS_315
   8925		  SiS_SetCH701xForLCD(SiS_Pr);
   8926#endif
   8927	       }
   8928	    }
   8929	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   8930	       SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
   8931	    }
   8932	 }
   8933      }
   8934
   8935   }
   8936
   8937#ifdef CONFIG_FB_SIS_300
   8938   if(SiS_Pr->ChipType < SIS_315H) {
   8939      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8940	 if(SiS_Pr->SiS_UseOEM) {
   8941	    if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
   8942	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
   8943		  SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8944	       }
   8945	    } else {
   8946	       SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8947	    }
   8948	 }
   8949	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   8950	    if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
   8951	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
   8952	       SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex);
   8953	    }
   8954	    SiS_DisplayOn(SiS_Pr);
   8955         }
   8956      }
   8957   }
   8958#endif
   8959
   8960#ifdef CONFIG_FB_SIS_315
   8961   if(SiS_Pr->ChipType >= SIS_315H) {
   8962      if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8963	 if(SiS_Pr->ChipType < SIS_661) {
   8964	    SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex);
   8965	    SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8966	 } else {
   8967	    SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
   8968	 }
   8969	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
   8970      }
   8971   }
   8972#endif
   8973
   8974   if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8975      SiS_EnableBridge(SiS_Pr);
   8976   }
   8977
   8978   SiS_DisplayOn(SiS_Pr);
   8979
   8980   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
   8981      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
   8982	 /* Disable LCD panel when using TV */
   8983	 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C);
   8984      } else {
   8985	 /* Disable TV when using LCD */
   8986	 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8);
   8987      }
   8988   }
   8989
   8990   if(SiS_Pr->SiS_SetFlag & LowModeTests) {
   8991      SiS_LockCRT2(SiS_Pr);
   8992   }
   8993
   8994   return true;
   8995}
   8996
   8997
   8998/*********************************************/
   8999/*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
   9000/*********************************************/
   9001
   9002void
   9003SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr)
   9004{
   9005  /* Switch on LCD backlight on SiS30xLV */
   9006  SiS_DDC2Delay(SiS_Pr,0xff00);
   9007  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
   9008     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
   9009     SiS_WaitVBRetrace(SiS_Pr);
   9010  }
   9011  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
   9012     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
   9013  }
   9014}
   9015
   9016void
   9017SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr)
   9018{
   9019  /* Switch off LCD backlight on SiS30xLV */
   9020  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
   9021  SiS_DDC2Delay(SiS_Pr,0xff00);
   9022}
   9023
   9024/*********************************************/
   9025/*          DDC RELATED FUNCTIONS            */
   9026/*********************************************/
   9027
   9028static void
   9029SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
   9030{
   9031  SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data;
   9032  SiS_Pr->SiS_DDC_NClk  = ~SiS_Pr->SiS_DDC_Clk;
   9033  if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) {
   9034     SiS_Pr->SiS_DDC_NData &= 0x0f;
   9035     SiS_Pr->SiS_DDC_NClk  &= 0x0f;
   9036  }
   9037}
   9038
   9039#ifdef CONFIG_FB_SIS_300
   9040static unsigned char *
   9041SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
   9042{
   9043  int i, j, num;
   9044  unsigned short tempah,temp;
   9045  unsigned char *mydataptr;
   9046
   9047  for(i=0; i<20; i++) {				/* Do 20 attempts to write */
   9048     mydataptr = dataptr;
   9049     num = *mydataptr++;
   9050     if(!num) return mydataptr;
   9051     if(i) {
   9052        SiS_SetStop(SiS_Pr);
   9053	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2);
   9054     }
   9055     if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
   9056     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
   9057     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
   9058     if(temp) continue;				/*    (ERROR: no ack) */
   9059     tempah = *mydataptr++;
   9060     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write register number */
   9061     if(temp) continue;				/*    (ERROR: no ack) */
   9062     for(j=0; j<num; j++) {
   9063        tempah = *mydataptr++;
   9064        temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
   9065	if(temp) break;
   9066     }
   9067     if(temp) continue;
   9068     if(SiS_SetStop(SiS_Pr)) continue;
   9069     return mydataptr;
   9070  }
   9071  return NULL;
   9072}
   9073
   9074static bool
   9075SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
   9076{
   9077  SiS_Pr->SiS_DDC_DeviceAddr = 0xF0;  		/* DAB (Device Address Byte) */
   9078  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
   9079  SiS_Pr->SiS_DDC_Data  = 0x02;			/* Bitmask in IndexReg for Data */
   9080  SiS_Pr->SiS_DDC_Clk   = 0x01;			/* Bitmask in IndexReg for Clk */
   9081  SiS_SetupDDCN(SiS_Pr);
   9082
   9083  SiS_SetSwitchDDC2(SiS_Pr);
   9084
   9085  while(*dataptr) {
   9086     dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
   9087     if(!dataptr) return false;
   9088  }
   9089  return true;
   9090}
   9091#endif
   9092
   9093/* The Chrontel 700x is connected to the 630/730 via
   9094 * the 630/730's DDC/I2C port.
   9095 *
   9096 * On 630(S)T chipset, the index changed from 0x11 to
   9097 * 0x0a, possibly for working around the DDC problems
   9098 */
   9099
   9100static bool
   9101SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
   9102{
   9103  unsigned short temp, i;
   9104
   9105  for(i=0; i<20; i++) {				/* Do 20 attempts to write */
   9106     if(i) {
   9107	SiS_SetStop(SiS_Pr);
   9108	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
   9109     }
   9110     if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
   9111     temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
   9112     if(temp) continue;							/*    (ERROR: no ack) */
   9113     temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor));			/* Write RAB (700x: set bit 7, see datasheet) */
   9114     if(temp) continue;							/*    (ERROR: no ack) */
   9115     temp = SiS_WriteDDC2Data(SiS_Pr, val);				/* Write data */
   9116     if(temp) continue;							/*    (ERROR: no ack) */
   9117     if(SiS_SetStop(SiS_Pr)) continue;					/* Set stop condition */
   9118     SiS_Pr->SiS_ChrontelInit = 1;
   9119     return true;
   9120  }
   9121  return false;
   9122}
   9123
   9124/* Write to Chrontel 700x */
   9125void
   9126SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
   9127{
   9128  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
   9129
   9130  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   9131
   9132  if(!(SiS_Pr->SiS_ChrontelInit)) {
   9133     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
   9134     SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
   9135     SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
   9136     SiS_SetupDDCN(SiS_Pr);
   9137  }
   9138
   9139  if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) &&
   9140      (!(SiS_Pr->SiS_ChrontelInit)) ) {
   9141     SiS_Pr->SiS_DDC_Index = 0x0a;
   9142     SiS_Pr->SiS_DDC_Data  = 0x80;
   9143     SiS_Pr->SiS_DDC_Clk   = 0x40;
   9144     SiS_SetupDDCN(SiS_Pr);
   9145
   9146     SiS_SetChReg(SiS_Pr, reg, val, 0x80);
   9147  }
   9148}
   9149
   9150/* Write to Chrontel 701x */
   9151/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
   9152void
   9153SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
   9154{
   9155  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
   9156  SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
   9157  SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
   9158  SiS_SetupDDCN(SiS_Pr);
   9159  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB (Device Address Byte) */
   9160  SiS_SetChReg(SiS_Pr, reg, val, 0);
   9161}
   9162
   9163static
   9164void
   9165SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
   9166{
   9167  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
   9168     SiS_SetCH700x(SiS_Pr, reg, val);
   9169  else
   9170     SiS_SetCH701x(SiS_Pr, reg, val);
   9171}
   9172
   9173static unsigned short
   9174SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor)
   9175{
   9176  unsigned short tempah, temp, i;
   9177
   9178  for(i=0; i<20; i++) {				/* Do 20 attempts to read */
   9179     if(i) {
   9180	SiS_SetStop(SiS_Pr);
   9181	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4);
   9182     }
   9183     if(SiS_SetStart(SiS_Pr)) continue;					/* Set start condition */
   9184     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr);	/* Write DAB (S0=0=write) */
   9185     if(temp) continue;							/*        (ERROR: no ack) */
   9186     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor);	/* Write RAB (700x: | 0x80) */
   9187     if(temp) continue;							/*        (ERROR: no ack) */
   9188     if (SiS_SetStart(SiS_Pr)) continue;				/* Re-start */
   9189     temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */
   9190     if(temp) continue;							/*        (ERROR: no ack) */
   9191     tempah = SiS_ReadDDC2Data(SiS_Pr);					/* Read byte */
   9192     if(SiS_SetStop(SiS_Pr)) continue;					/* Stop condition */
   9193     SiS_Pr->SiS_ChrontelInit = 1;
   9194     return tempah;
   9195  }
   9196  return 0xFFFF;
   9197}
   9198
   9199/* Read from Chrontel 700x */
   9200/* Parameter is [Register no (S7-S0)] */
   9201unsigned short
   9202SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
   9203{
   9204  unsigned short result;
   9205
   9206  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
   9207
   9208  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   9209
   9210  if(!(SiS_Pr->SiS_ChrontelInit)) {
   9211     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
   9212     SiS_Pr->SiS_DDC_Data  = 0x02;		/* Bitmask in IndexReg for Data */
   9213     SiS_Pr->SiS_DDC_Clk   = 0x01;		/* Bitmask in IndexReg for Clk */
   9214     SiS_SetupDDCN(SiS_Pr);
   9215  }
   9216
   9217  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
   9218
   9219  if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
   9220      (!SiS_Pr->SiS_ChrontelInit) ) {
   9221
   9222     SiS_Pr->SiS_DDC_Index = 0x0a;
   9223     SiS_Pr->SiS_DDC_Data  = 0x80;
   9224     SiS_Pr->SiS_DDC_Clk   = 0x40;
   9225     SiS_SetupDDCN(SiS_Pr);
   9226
   9227     result = SiS_GetChReg(SiS_Pr,0x80);
   9228  }
   9229  return result;
   9230}
   9231
   9232/* Read from Chrontel 701x */
   9233/* Parameter is [Register no (S7-S0)] */
   9234unsigned short
   9235SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
   9236{
   9237  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
   9238  SiS_Pr->SiS_DDC_Data  = 0x08;			/* Bitmask in IndexReg for Data */
   9239  SiS_Pr->SiS_DDC_Clk   = 0x04;			/* Bitmask in IndexReg for Clk */
   9240  SiS_SetupDDCN(SiS_Pr);
   9241  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
   9242
   9243  SiS_Pr->SiS_DDC_ReadAddr = tempbx;
   9244
   9245  return SiS_GetChReg(SiS_Pr,0);
   9246}
   9247
   9248/* Read from Chrontel 70xx */
   9249/* Parameter is [Register no (S7-S0)] */
   9250static
   9251unsigned short
   9252SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
   9253{
   9254  if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
   9255     return SiS_GetCH700x(SiS_Pr, tempbx);
   9256  else
   9257     return SiS_GetCH701x(SiS_Pr, tempbx);
   9258}
   9259
   9260void
   9261SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
   9262		unsigned char myor, unsigned short myand)
   9263{
   9264  unsigned short tempbl;
   9265
   9266  tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor;
   9267  SiS_SetCH70xx(SiS_Pr, reg, tempbl);
   9268}
   9269
   9270/* Our own DDC functions */
   9271static
   9272unsigned short
   9273SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
   9274                unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
   9275		unsigned int VBFlags2)
   9276{
   9277     unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
   9278     unsigned char flag, cr32;
   9279     unsigned short        temp = 0, myadaptnum = adaptnum;
   9280
   9281     if(adaptnum != 0) {
   9282	if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF;
   9283	if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF;
   9284     }
   9285
   9286     /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
   9287
   9288     SiS_Pr->SiS_ChrontelInit = 0;   /* force re-detection! */
   9289
   9290     SiS_Pr->SiS_DDC_SecAddr = 0;
   9291     SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype];
   9292     SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4;
   9293     SiS_Pr->SiS_DDC_Index = 0x11;
   9294     flag = 0xff;
   9295
   9296     cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
   9297
   9298#if 0
   9299     if(VBFlags2 & VB2_SISBRIDGE) {
   9300	if(myadaptnum == 0) {
   9301	   if(!(cr32 & 0x20)) {
   9302	      myadaptnum = 2;
   9303	      if(!(cr32 & 0x10)) {
   9304	         myadaptnum = 1;
   9305		 if(!(cr32 & 0x08)) {
   9306		    myadaptnum = 0;
   9307		 }
   9308	      }
   9309	   }
   9310        }
   9311     }
   9312#endif
   9313
   9314     if(VGAEngine == SIS_300_VGA) {		/* 300 series */
   9315
   9316        if(myadaptnum != 0) {
   9317	   flag = 0;
   9318	   if(VBFlags2 & VB2_SISBRIDGE) {
   9319	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
   9320              SiS_Pr->SiS_DDC_Index = 0x0f;
   9321	   }
   9322        }
   9323
   9324	if(!(VBFlags2 & VB2_301)) {
   9325	   if((cr32 & 0x80) && (checkcr32)) {
   9326              if(myadaptnum >= 1) {
   9327	         if(!(cr32 & 0x08)) {
   9328		     myadaptnum = 1;
   9329		     if(!(cr32 & 0x10)) return 0xFFFF;
   9330                 }
   9331	      }
   9332	   }
   9333	}
   9334
   9335	temp = 4 - (myadaptnum * 2);
   9336	if(flag) temp = 0;
   9337
   9338     } else {						/* 315/330 series */
   9339
   9340	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
   9341
   9342	if(VBFlags2 & VB2_SISBRIDGE) {
   9343	   if(myadaptnum == 2) {
   9344	      myadaptnum = 1;
   9345	   }
   9346	}
   9347
   9348        if(myadaptnum == 1) {
   9349	   flag = 0;
   9350	   if(VBFlags2 & VB2_SISBRIDGE) {
   9351	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
   9352              SiS_Pr->SiS_DDC_Index = 0x0f;
   9353	   }
   9354        }
   9355
   9356        if((cr32 & 0x80) && (checkcr32)) {
   9357           if(myadaptnum >= 1) {
   9358	      if(!(cr32 & 0x08)) {
   9359	         myadaptnum = 1;
   9360		 if(!(cr32 & 0x10)) return 0xFFFF;
   9361	      }
   9362	   }
   9363        }
   9364
   9365        temp = myadaptnum;
   9366        if(myadaptnum == 1) {
   9367           temp = 0;
   9368	   if(VBFlags2 & VB2_LVDS) flag = 0xff;
   9369        }
   9370
   9371	if(flag) temp = 0;
   9372    }
   9373
   9374    SiS_Pr->SiS_DDC_Data = 0x02 << temp;
   9375    SiS_Pr->SiS_DDC_Clk  = 0x01 << temp;
   9376
   9377    SiS_SetupDDCN(SiS_Pr);
   9378
   9379    return 0;
   9380}
   9381
   9382static unsigned short
   9383SiS_WriteDABDDC(struct SiS_Private *SiS_Pr)
   9384{
   9385   if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
   9386   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
   9387      return 0xFFFF;
   9388   }
   9389   if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
   9390      return 0xFFFF;
   9391   }
   9392   return 0;
   9393}
   9394
   9395static unsigned short
   9396SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr)
   9397{
   9398   if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
   9399   if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
   9400      return 0xFFFF;
   9401   }
   9402   return 0;
   9403}
   9404
   9405static unsigned short
   9406SiS_PrepareDDC(struct SiS_Private *SiS_Pr)
   9407{
   9408   if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr);
   9409   if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr));
   9410   return 0;
   9411}
   9412
   9413static void
   9414SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno)
   9415{
   9416   SiS_SetSCLKLow(SiS_Pr);
   9417   if(yesno) {
   9418      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9419		      SiS_Pr->SiS_DDC_Index,
   9420		      SiS_Pr->SiS_DDC_NData,
   9421		      SiS_Pr->SiS_DDC_Data);
   9422   } else {
   9423      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9424		      SiS_Pr->SiS_DDC_Index,
   9425		      SiS_Pr->SiS_DDC_NData,
   9426		      0);
   9427   }
   9428   SiS_SetSCLKHigh(SiS_Pr);
   9429}
   9430
   9431static unsigned short
   9432SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
   9433{
   9434    unsigned char mask, value;
   9435    unsigned short  temp, ret=0;
   9436    bool failed = false;
   9437
   9438    SiS_SetSwitchDDC2(SiS_Pr);
   9439    if(SiS_PrepareDDC(SiS_Pr)) {
   9440         SiS_SetStop(SiS_Pr);
   9441         return 0xFFFF;
   9442    }
   9443    mask = 0xf0;
   9444    value = 0x20;
   9445    if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
   9446       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
   9447       SiS_SendACK(SiS_Pr, 0);
   9448       if(temp == 0) {
   9449           mask = 0xff;
   9450	   value = 0xff;
   9451       } else {
   9452           failed = true;
   9453	   ret = 0xFFFF;
   9454       }
   9455    }
   9456    if(!failed) {
   9457       temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
   9458       SiS_SendACK(SiS_Pr, 1);
   9459       temp &= mask;
   9460       if(temp == value) ret = 0;
   9461       else {
   9462          ret = 0xFFFF;
   9463          if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
   9464             if(temp == 0x30) ret = 0;
   9465          }
   9466       }
   9467    }
   9468    SiS_SetStop(SiS_Pr);
   9469    return ret;
   9470}
   9471
   9472static
   9473unsigned short
   9474SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
   9475{
   9476   unsigned short flag;
   9477
   9478   flag = 0x180;
   9479   SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
   9480   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02;
   9481   SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;
   9482   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08;
   9483   SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;
   9484   if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10;
   9485   if(!(flag & 0x1a)) flag = 0;
   9486   return flag;
   9487}
   9488
   9489static
   9490unsigned short
   9491SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
   9492{
   9493   unsigned short flag, length, i;
   9494   unsigned char chksum,gotcha;
   9495
   9496   if(DDCdatatype > 4) return 0xFFFF;
   9497
   9498   flag = 0;
   9499   SiS_SetSwitchDDC2(SiS_Pr);
   9500   if(!(SiS_PrepareDDC(SiS_Pr))) {
   9501      length = 127;
   9502      if(DDCdatatype != 1) length = 255;
   9503      chksum = 0;
   9504      gotcha = 0;
   9505      for(i=0; i<length; i++) {
   9506	 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
   9507	 chksum += buffer[i];
   9508	 gotcha |= buffer[i];
   9509	 SiS_SendACK(SiS_Pr, 0);
   9510      }
   9511      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
   9512      chksum += buffer[i];
   9513      SiS_SendACK(SiS_Pr, 1);
   9514      if(gotcha) flag = (unsigned short)chksum;
   9515      else flag = 0xFFFF;
   9516   } else {
   9517      flag = 0xFFFF;
   9518   }
   9519   SiS_SetStop(SiS_Pr);
   9520   return flag;
   9521}
   9522
   9523/* Our private DDC functions
   9524
   9525   It complies somewhat with the corresponding VESA function
   9526   in arguments and return values.
   9527
   9528   Since this is probably called before the mode is changed,
   9529   we use our pre-detected pSiS-values instead of SiS_Pr as
   9530   regards chipset and video bridge type.
   9531
   9532   Arguments:
   9533       adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog)
   9534                 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B.
   9535		 LCDA is CRT1, but DDC is read from CRT2 port.
   9536       DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
   9537       buffer: ptr to 256 data bytes which will be filled with read data.
   9538
   9539   Returns 0xFFFF if error, otherwise
   9540       if DDCdatatype > 0:  Returns 0 if reading OK (included a correct checksum)
   9541       if DDCdatatype = 0:  Returns supported DDC modes
   9542
   9543 */
   9544unsigned short
   9545SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
   9546              unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer,
   9547	      unsigned int VBFlags2)
   9548{
   9549   unsigned char  sr1f, cr17=1;
   9550   unsigned short result;
   9551
   9552   if(adaptnum > 2)
   9553      return 0xFFFF;
   9554
   9555   if(DDCdatatype > 4)
   9556      return 0xFFFF;
   9557
   9558   if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
   9559      return 0xFFFF;
   9560
   9561   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
   9562      return 0xFFFF;
   9563
   9564   sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
   9565   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
   9566   if(VGAEngine == SIS_300_VGA) {
   9567      cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
   9568      if(!cr17) {
   9569         SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
   9570         SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
   9571         SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
   9572      }
   9573   }
   9574   if((sr1f) || (!cr17)) {
   9575      SiS_WaitRetrace1(SiS_Pr);
   9576      SiS_WaitRetrace1(SiS_Pr);
   9577      SiS_WaitRetrace1(SiS_Pr);
   9578      SiS_WaitRetrace1(SiS_Pr);
   9579   }
   9580
   9581   if(DDCdatatype == 0) {
   9582      result = SiS_ProbeDDC(SiS_Pr);
   9583   } else {
   9584      result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
   9585      if((!result) && (DDCdatatype == 1)) {
   9586         if((buffer[0] == 0x00) && (buffer[1] == 0xff) &&
   9587	    (buffer[2] == 0xff) && (buffer[3] == 0xff) &&
   9588	    (buffer[4] == 0xff) && (buffer[5] == 0xff) &&
   9589	    (buffer[6] == 0xff) && (buffer[7] == 0x00) &&
   9590	    (buffer[0x12] == 1)) {
   9591	    if(!SiS_Pr->DDCPortMixup) {
   9592	       if(adaptnum == 1) {
   9593	          if(!(buffer[0x14] & 0x80)) result = 0xFFFE;
   9594	       } else {
   9595	          if(buffer[0x14] & 0x80)    result = 0xFFFE;
   9596	       }
   9597	    }
   9598	 }
   9599      }
   9600   }
   9601   SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
   9602   if(VGAEngine == SIS_300_VGA) {
   9603      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
   9604   }
   9605   return result;
   9606}
   9607
   9608/* Generic I2C functions for Chrontel & DDC --------- */
   9609
   9610static void
   9611SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr)
   9612{
   9613  SiS_SetSCLKHigh(SiS_Pr);
   9614  SiS_WaitRetrace1(SiS_Pr);
   9615
   9616  SiS_SetSCLKLow(SiS_Pr);
   9617  SiS_WaitRetrace1(SiS_Pr);
   9618}
   9619
   9620unsigned short
   9621SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr)
   9622{
   9623   SiS_WaitRetrace1(SiS_Pr);
   9624   return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
   9625}
   9626
   9627/* Set I2C start condition */
   9628/* This is done by a SD high-to-low transition while SC is high */
   9629static unsigned short
   9630SiS_SetStart(struct SiS_Private *SiS_Pr)
   9631{
   9632  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low)  */
   9633  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9634		  SiS_Pr->SiS_DDC_Index,
   9635		  SiS_Pr->SiS_DDC_NData,
   9636		  SiS_Pr->SiS_DDC_Data);        		/* SD->high */
   9637  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high */
   9638  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9639		  SiS_Pr->SiS_DDC_Index,
   9640		  SiS_Pr->SiS_DDC_NData,
   9641		  0x00);					/* SD->low = start condition */
   9642  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
   9643  return 0;
   9644}
   9645
   9646/* Set I2C stop condition */
   9647/* This is done by a SD low-to-high transition while SC is high */
   9648static unsigned short
   9649SiS_SetStop(struct SiS_Private *SiS_Pr)
   9650{
   9651  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			/* (SC->low) */
   9652  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9653		  SiS_Pr->SiS_DDC_Index,
   9654		  SiS_Pr->SiS_DDC_NData,
   9655		  0x00);					/* SD->low   */
   9656  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* SC->high  */
   9657  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9658		  SiS_Pr->SiS_DDC_Index,
   9659		  SiS_Pr->SiS_DDC_NData,
   9660		  SiS_Pr->SiS_DDC_Data);			/* SD->high = stop condition */
   9661  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			/* (SC->high) */
   9662  return 0;
   9663}
   9664
   9665/* Write 8 bits of data */
   9666static unsigned short
   9667SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax)
   9668{
   9669  unsigned short i,flag,temp;
   9670
   9671  flag = 0x80;
   9672  for(i = 0; i < 8; i++) {
   9673    SiS_SetSCLKLow(SiS_Pr);					/* SC->low */
   9674    if(tempax & flag) {
   9675      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9676		      SiS_Pr->SiS_DDC_Index,
   9677		      SiS_Pr->SiS_DDC_NData,
   9678		      SiS_Pr->SiS_DDC_Data);			/* Write bit (1) to SD */
   9679    } else {
   9680      SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9681		      SiS_Pr->SiS_DDC_Index,
   9682		      SiS_Pr->SiS_DDC_NData,
   9683		      0x00);					/* Write bit (0) to SD */
   9684    }
   9685    SiS_SetSCLKHigh(SiS_Pr);					/* SC->high */
   9686    flag >>= 1;
   9687  }
   9688  temp = SiS_CheckACK(SiS_Pr);					/* Check acknowledge */
   9689  return temp;
   9690}
   9691
   9692static unsigned short
   9693SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr)
   9694{
   9695  unsigned short i, temp, getdata;
   9696
   9697  getdata = 0;
   9698  for(i = 0; i < 8; i++) {
   9699    getdata <<= 1;
   9700    SiS_SetSCLKLow(SiS_Pr);
   9701    SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9702		    SiS_Pr->SiS_DDC_Index,
   9703		    SiS_Pr->SiS_DDC_NData,
   9704		    SiS_Pr->SiS_DDC_Data);
   9705    SiS_SetSCLKHigh(SiS_Pr);
   9706    temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
   9707    if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
   9708  }
   9709  return getdata;
   9710}
   9711
   9712static unsigned short
   9713SiS_SetSCLKLow(struct SiS_Private *SiS_Pr)
   9714{
   9715  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9716		  SiS_Pr->SiS_DDC_Index,
   9717		  SiS_Pr->SiS_DDC_NClk,
   9718		  0x00);					/* SetSCLKLow()  */
   9719  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   9720  return 0;
   9721}
   9722
   9723static unsigned short
   9724SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
   9725{
   9726  unsigned short temp, watchdog=1000;
   9727
   9728  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9729		  SiS_Pr->SiS_DDC_Index,
   9730		  SiS_Pr->SiS_DDC_NClk,
   9731		  SiS_Pr->SiS_DDC_Clk);  			/* SetSCLKHigh()  */
   9732  do {
   9733    temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
   9734  } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
   9735  if (!watchdog) {
   9736  	return 0xFFFF;
   9737  }
   9738  SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   9739  return 0;
   9740}
   9741
   9742/* Check I2C acknowledge */
   9743/* Returns 0 if ack ok, non-0 if ack not ok */
   9744static unsigned short
   9745SiS_CheckACK(struct SiS_Private *SiS_Pr)
   9746{
   9747  unsigned short tempah;
   9748
   9749  SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
   9750  SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,
   9751		  SiS_Pr->SiS_DDC_Index,
   9752		  SiS_Pr->SiS_DDC_NData,
   9753		  SiS_Pr->SiS_DDC_Data);			   /* (SD->high) */
   9754  SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
   9755  tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */
   9756  SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
   9757  if(tempah & SiS_Pr->SiS_DDC_Data) return 1;			   /* Ack OK if bit = 0 */
   9758  return 0;
   9759}
   9760
   9761/* End of I2C functions ----------------------- */
   9762
   9763
   9764/* =============== SiS 315/330 O.E.M. ================= */
   9765
   9766#ifdef CONFIG_FB_SIS_315
   9767
   9768static unsigned short
   9769GetRAMDACromptr(struct SiS_Private *SiS_Pr)
   9770{
   9771  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   9772  unsigned short romptr;
   9773
   9774  if(SiS_Pr->ChipType < SIS_330) {
   9775     romptr = SISGETROMW(0x128);
   9776     if(SiS_Pr->SiS_VBType & VB_SIS30xB)
   9777        romptr = SISGETROMW(0x12a);
   9778  } else {
   9779     romptr = SISGETROMW(0x1a8);
   9780     if(SiS_Pr->SiS_VBType & VB_SIS30xB)
   9781        romptr = SISGETROMW(0x1aa);
   9782  }
   9783  return romptr;
   9784}
   9785
   9786static unsigned short
   9787GetLCDromptr(struct SiS_Private *SiS_Pr)
   9788{
   9789  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   9790  unsigned short romptr;
   9791
   9792  if(SiS_Pr->ChipType < SIS_330) {
   9793     romptr = SISGETROMW(0x120);
   9794     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
   9795        romptr = SISGETROMW(0x122);
   9796  } else {
   9797     romptr = SISGETROMW(0x1a0);
   9798     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
   9799        romptr = SISGETROMW(0x1a2);
   9800  }
   9801  return romptr;
   9802}
   9803
   9804static unsigned short
   9805GetTVromptr(struct SiS_Private *SiS_Pr)
   9806{
   9807  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   9808  unsigned short romptr;
   9809
   9810  if(SiS_Pr->ChipType < SIS_330) {
   9811     romptr = SISGETROMW(0x114);
   9812     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
   9813        romptr = SISGETROMW(0x11a);
   9814  } else {
   9815     romptr = SISGETROMW(0x194);
   9816     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV)
   9817        romptr = SISGETROMW(0x19a);
   9818  }
   9819  return romptr;
   9820}
   9821
   9822static unsigned short
   9823GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr)
   9824{
   9825  unsigned short index;
   9826
   9827  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
   9828     if(!(SiS_IsNotM650orLater(SiS_Pr))) {
   9829        if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
   9830	   index >>= 4;
   9831	   index *= 3;
   9832	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
   9833           else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
   9834           return index;
   9835	}
   9836     }
   9837  }
   9838
   9839  index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
   9840  if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)      index -= 5;
   9841  if(SiS_Pr->SiS_VBType & VB_SIS301C) {  /* 1.15.20 and later (not VB specific) */
   9842     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5;
   9843     if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5;
   9844  } else {
   9845     if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
   9846  }
   9847  index--;
   9848  index *= 3;
   9849  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
   9850  else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
   9851  return index;
   9852}
   9853
   9854static unsigned short
   9855GetLCDPtrIndex(struct SiS_Private *SiS_Pr)
   9856{
   9857  unsigned short index;
   9858
   9859  index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
   9860  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         index += 2;
   9861  else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
   9862  return index;
   9863}
   9864
   9865static unsigned short
   9866GetTVPtrIndex(struct SiS_Private *SiS_Pr)
   9867{
   9868  unsigned short index;
   9869
   9870  index = 0;
   9871  if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1;
   9872  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2;
   9873
   9874  if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0;
   9875
   9876  index <<= 1;
   9877
   9878  if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) &&
   9879     (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
   9880     index++;
   9881  }
   9882
   9883  return index;
   9884}
   9885
   9886static unsigned int
   9887GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme)
   9888{
   9889   unsigned short index = 0, temp = 0;
   9890
   9891   if(SiS_Pr->SiS_TVMode & TVSetPAL)   index = 1;
   9892   if(SiS_Pr->SiS_TVMode & TVSetPALM)  index = 2;
   9893   if(SiS_Pr->SiS_TVMode & TVSetPALN)  index = 3;
   9894   if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6;
   9895   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
   9896      index = 4;
   9897      if(SiS_Pr->SiS_TVMode & TVSetPALM)  index++;
   9898      if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7;
   9899   }
   9900
   9901   if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
   9902      if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
   9903         (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
   9904	 index += addme;
   9905	 temp++;
   9906      }
   9907      temp += 0x0100;
   9908   }
   9909   return (unsigned int)(index | (temp << 16));
   9910}
   9911
   9912static unsigned int
   9913GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr)
   9914{
   9915   return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
   9916}
   9917
   9918#if 0
   9919static unsigned int
   9920GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr)
   9921{
   9922   return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
   9923}
   9924#endif
   9925
   9926static int
   9927GetOEMTVPtr661(struct SiS_Private *SiS_Pr)
   9928{
   9929   int index = 0;
   9930
   9931   if(SiS_Pr->SiS_TVMode & TVSetPAL)          index = 2;
   9932   if(SiS_Pr->SiS_ROMNew) {
   9933      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
   9934      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
   9935      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
   9936      if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 10;
   9937   } else {
   9938      if(SiS_Pr->SiS_TVMode & TVSetHiVision)  index = 4;
   9939      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
   9940      if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
   9941      if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
   9942   }
   9943
   9944   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
   9945
   9946   return index;
   9947}
   9948
   9949static void
   9950SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
   9951{
   9952  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   9953  unsigned short delay=0,index,myindex,temp,romptr=0;
   9954  bool dochiptest = true;
   9955
   9956  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
   9957     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
   9958  } else {
   9959     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
   9960  }
   9961
   9962  /* Find delay (from ROM, internal tables, PCI subsystem) */
   9963
   9964  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
   9965
   9966     if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
   9967        romptr = GetRAMDACromptr(SiS_Pr);
   9968     }
   9969     if(romptr) delay = ROMAddr[romptr];
   9970     else {
   9971        delay = 0x04;
   9972        if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
   9973	   if(IS_SIS650) {
   9974	      delay = 0x0a;
   9975	   } else if(IS_SIS740) {
   9976	      delay = 0x00;
   9977	   } else {
   9978	      delay = 0x0c;
   9979	   }
   9980	} else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
   9981           delay = 0x00;
   9982	}
   9983     }
   9984
   9985  } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
   9986
   9987     bool gotitfrompci = false;
   9988
   9989     /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
   9990
   9991     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
   9992	if(SiS_Pr->PDC != -1) {
   9993           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
   9994	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
   9995	   return;
   9996	}
   9997     } else {
   9998	if(SiS_Pr->PDCA != -1) {
   9999	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
  10000	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
  10001	   return;
  10002	}
  10003     }
  10004
  10005     /* Custom Panel? */
  10006
  10007     if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
  10008        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  10009	   delay = 0x00;
  10010	   if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
  10011	      delay = 0x20;
  10012	   }
  10013	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
  10014	} else {
  10015	   delay = 0x0c;
  10016	   if(SiS_Pr->SiS_VBType & VB_SIS301C) {
  10017	      delay = 0x03;
  10018	      if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) {
  10019	         delay = 0x00;
  10020	      }
  10021	   } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
  10022	      if(IS_SIS740) delay = 0x01;
  10023	      else          delay = 0x03;
  10024	   }
  10025	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
  10026	}
  10027        return;
  10028     }
  10029
  10030     /* This is a piece of typical SiS crap: They code the OEM LCD
  10031      * delay into the code, at no defined place in the BIOS.
  10032      * We now have to start doing a PCI subsystem check here.
  10033      */
  10034
  10035     switch(SiS_Pr->SiS_CustomT) {
  10036     case CUT_COMPAQ1280:
  10037     case CUT_COMPAQ12802:
  10038	if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
  10039	   gotitfrompci = true;
  10040	   dochiptest = false;
  10041	   delay = 0x03;
  10042	}
  10043	break;
  10044     case CUT_CLEVO1400:
  10045     case CUT_CLEVO14002:
  10046	gotitfrompci = true;
  10047	dochiptest = false;
  10048	delay = 0x02;
  10049	break;
  10050     case CUT_CLEVO1024:
  10051     case CUT_CLEVO10242:
  10052        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
  10053	   gotitfrompci = true;
  10054	   dochiptest = false;
  10055	   delay = 0x33;
  10056	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
  10057	   delay &= 0x0f;
  10058	}
  10059	break;
  10060     }
  10061
  10062     /* Could we find it through the PCI ID? If no, use ROM or table */
  10063
  10064     if(!gotitfrompci) {
  10065
  10066        index = GetLCDPtrIndexBIOS(SiS_Pr);
  10067        myindex = GetLCDPtrIndex(SiS_Pr);
  10068
  10069        if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
  10070
  10071           if(SiS_IsNotM650orLater(SiS_Pr)) {
  10072
  10073              if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
  10074	         /* Always use the second pointer on 650; some BIOSes */
  10075                 /* still carry old 301 data at the first location    */
  10076	         /* romptr = SISGETROMW(0x120);                       */
  10077	         /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
  10078	         romptr = SISGETROMW(0x122);
  10079	         if(!romptr) return;
  10080	         delay = ROMAddr[(romptr + index)];
  10081	      } else {
  10082                 delay = SiS310_LCDDelayCompensation_650301LV[myindex];
  10083	      }
  10084
  10085          } else {
  10086
  10087             delay = SiS310_LCDDelayCompensation_651301LV[myindex];
  10088	     if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV))
  10089	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
  10090
  10091          }
  10092
  10093        } else if(SiS_Pr->SiS_UseROM 			      &&
  10094		  (!(SiS_Pr->SiS_ROMNew))		      &&
  10095	          (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
  10096		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x768)  &&
  10097		  (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)  &&
  10098		  (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)  &&
  10099		  ((romptr = GetLCDromptr(SiS_Pr)))) {
  10100
  10101	   /* Data for 1280x1024 wrong in 301B BIOS */
  10102	   /* Data for 1600x1200 wrong in 301C BIOS */
  10103	   delay = ROMAddr[(romptr + index)];
  10104
  10105        } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  10106
  10107	   if(IS_SIS740) delay = 0x03;
  10108	   else          delay = 0x00;
  10109
  10110	} else {
  10111
  10112           delay = SiS310_LCDDelayCompensation_301[myindex];
  10113	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
  10114	      if(IS_SIS740) delay = 0x01;
  10115	      else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
  10116	      else          delay = SiS310_LCDDelayCompensation_650301LV[myindex];
  10117	   } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
  10118	      if(IS_SIS740) delay = 0x01;  /* ? */
  10119	      else          delay = 0x03;
  10120	      if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */
  10121	   } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) {
  10122	      if(IS_SIS740) delay = 0x01;
  10123	      else          delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
  10124	   }
  10125
  10126        }
  10127
  10128     }  /* got it from PCI */
  10129
  10130     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  10131	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
  10132	dochiptest = false;
  10133     }
  10134
  10135  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
  10136
  10137     index = GetTVPtrIndex(SiS_Pr);
  10138
  10139     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
  10140
  10141        if(SiS_IsNotM650orLater(SiS_Pr)) {
  10142
  10143           if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
  10144	      /* Always use the second pointer on 650; some BIOSes */
  10145              /* still carry old 301 data at the first location    */
  10146              /* romptr = SISGETROMW(0x114);			   */
  10147	      /* if(SiS_Pr->SiS_VBType & VB_SIS302LV)              */
  10148	      romptr = SISGETROMW(0x11a);
  10149	      if(!romptr) return;
  10150	      delay = ROMAddr[romptr + index];
  10151
  10152	   } else {
  10153
  10154	      delay = SiS310_TVDelayCompensation_301B[index];
  10155
  10156	   }
  10157
  10158        } else {
  10159
  10160           switch(SiS_Pr->SiS_CustomT) {
  10161	   case CUT_COMPAQ1280:
  10162	   case CUT_COMPAQ12802:
  10163	   case CUT_CLEVO1400:
  10164	   case CUT_CLEVO14002:
  10165	      delay = 0x02;
  10166	      dochiptest = false;
  10167	      break;
  10168	   case CUT_CLEVO1024:
  10169	   case CUT_CLEVO10242:
  10170	      delay = 0x03;
  10171	      dochiptest = false;
  10172   	      break;
  10173	   default:
  10174              delay = SiS310_TVDelayCompensation_651301LV[index];
  10175	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
  10176	         delay = SiS310_TVDelayCompensation_651302LV[index];
  10177	      }
  10178	   }
  10179        }
  10180
  10181     } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
  10182
  10183        romptr = GetTVromptr(SiS_Pr);
  10184	if(!romptr) return;
  10185	delay = ROMAddr[romptr + index];
  10186
  10187     } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  10188
  10189        delay = SiS310_TVDelayCompensation_LVDS[index];
  10190
  10191     } else {
  10192
  10193	delay = SiS310_TVDelayCompensation_301[index];
  10194        if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  10195	   if(IS_SIS740) {
  10196	      delay = SiS310_TVDelayCompensation_740301B[index];
  10197	      /* LV: use 301 data? BIOS bug? */
  10198	   } else {
  10199              delay = SiS310_TVDelayCompensation_301B[index];
  10200	      if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
  10201	   }
  10202	}
  10203
  10204     }
  10205
  10206     if(SiS_LCDAEnabled(SiS_Pr)) {
  10207	delay &= 0x0f;
  10208	dochiptest = false;
  10209     }
  10210
  10211  } else return;
  10212
  10213  /* Write delay */
  10214
  10215  if(SiS_Pr->SiS_VBType & VB_SISVB) {
  10216
  10217     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) {
  10218
  10219        temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
  10220        if(temp == 8) {		/* 1400x1050 BIOS (COMPAL) */
  10221	   delay &= 0x0f;
  10222	   delay |= 0xb0;
  10223        } else if(temp == 6) {
  10224           delay &= 0x0f;
  10225	   delay |= 0xc0;
  10226        } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
  10227	   delay = 0x35;
  10228        }
  10229        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
  10230
  10231     } else {
  10232
  10233        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
  10234
  10235     }
  10236
  10237  } else {  /* LVDS */
  10238
  10239     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  10240        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
  10241     } else {
  10242        if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) {
  10243           delay <<= 4;
  10244           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay);
  10245        } else {
  10246           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
  10247        }
  10248     }
  10249
  10250  }
  10251
  10252}
  10253
  10254static void
  10255SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  10256{
  10257  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  10258  unsigned short index,temp,temp1,romptr=0;
  10259
  10260  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return;
  10261
  10262  if(ModeNo<=0x13)
  10263     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
  10264  else
  10265     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
  10266
  10267  temp = GetTVPtrIndex(SiS_Pr);
  10268  temp >>= 1;  	  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
  10269  temp1 = temp;
  10270
  10271  if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
  10272     if(SiS_Pr->ChipType >= SIS_661) {
  10273        temp1 = GetOEMTVPtr661(SiS_Pr);
  10274        temp1 >>= 1;
  10275        romptr = SISGETROMW(0x260);
  10276        if(SiS_Pr->ChipType >= SIS_760) {
  10277	   romptr = SISGETROMW(0x360);
  10278	}
  10279     } else if(SiS_Pr->ChipType >= SIS_330) {
  10280        romptr = SISGETROMW(0x192);
  10281     } else {
  10282        romptr = SISGETROMW(0x112);
  10283     }
  10284  }
  10285
  10286  if(romptr) {
  10287     temp1 <<= 1;
  10288     temp = ROMAddr[romptr + temp1 + index];
  10289  } else {
  10290     temp = SiS310_TVAntiFlick1[temp][index];
  10291  }
  10292  temp <<= 4;
  10293
  10294  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp);  /* index 0A D[6:4] */
  10295}
  10296
  10297static void
  10298SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
  10299{
  10300  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  10301  unsigned short index,temp,temp1,romptr=0;
  10302
  10303  temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; 	/* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
  10304
  10305  if(ModeNo <= 0x13)
  10306     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
  10307  else
  10308     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
  10309
  10310  if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
  10311     if(SiS_Pr->ChipType >= SIS_661) {
  10312        romptr = SISGETROMW(0x26c);
  10313        if(SiS_Pr->ChipType >= SIS_760) {
  10314	   romptr = SISGETROMW(0x36c);
  10315	}
  10316	temp1 = GetOEMTVPtr661(SiS_Pr);
  10317        temp1 >>= 1;
  10318     } else if(SiS_Pr->ChipType >= SIS_330) {
  10319        romptr = SISGETROMW(0x1a4);
  10320     } else {
  10321        romptr = SISGETROMW(0x124);
  10322     }
  10323  }
  10324
  10325  if(romptr) {
  10326     temp1 <<= 1;
  10327     temp = ROMAddr[romptr + temp1 + index];
  10328  } else {
  10329     temp = SiS310_TVEdge1[temp][index];
  10330  }
  10331  temp <<= 5;
  10332  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp);  /* index 0A D[7:5] */
  10333}
  10334
  10335static void
  10336SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
  10337{
  10338  unsigned short index, temp, i, j;
  10339
  10340  if(ModeNo <= 0x13) {
  10341     index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
  10342  } else {
  10343     index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
  10344  }
  10345
  10346  temp = GetTVPtrIndex(SiS_Pr) >> 1;  /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
  10347
  10348  if(SiS_Pr->SiS_TVMode & TVSetNTSCJ)	     temp = 1;  /* NTSC-J uses PAL */
  10349  else if(SiS_Pr->SiS_TVMode & TVSetPALM)    temp = 3;  /* PAL-M */
  10350  else if(SiS_Pr->SiS_TVMode & TVSetPALN)    temp = 4;  /* PAL-N */
  10351  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1;  /* HiVision uses PAL */
  10352
  10353  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  10354     for(i=0x35, j=0; i<=0x38; i++, j++) {
  10355        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
  10356     }
  10357     for(i=0x48; i<=0x4A; i++, j++) {
  10358        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
  10359     }
  10360  } else {
  10361     for(i=0x35, j=0; i<=0x38; i++, j++) {
  10362        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
  10363     }
  10364  }
  10365}
  10366
  10367static void
  10368SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  10369{
  10370  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  10371  unsigned short index,temp,i,j,resinfo,romptr=0;
  10372  unsigned int  lindex;
  10373
  10374  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
  10375
  10376  /* NTSC-J data not in BIOS, and already set in SetGroup2 */
  10377  if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
  10378
  10379  if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
  10380     lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
  10381     lindex <<= 2;
  10382     for(j=0, i=0x31; i<=0x34; i++, j++) {
  10383        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]);
  10384     }
  10385     return;
  10386  }
  10387
  10388  /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */
  10389  if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return;
  10390
  10391  if(ModeNo<=0x13) {
  10392     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
  10393  } else {
  10394     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  10395  }
  10396
  10397  temp = GetTVPtrIndex(SiS_Pr);
  10398  /* 0: NTSC Graphics, 1: NTSC Text,    2: PAL Graphics,
  10399   * 3: PAL Text,      4: HiTV Graphics 5: HiTV Text
  10400   */
  10401  if(SiS_Pr->SiS_UseROM) {
  10402     romptr = SISGETROMW(0x116);
  10403     if(SiS_Pr->ChipType >= SIS_330) {
  10404        romptr = SISGETROMW(0x196);
  10405     }
  10406     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  10407        romptr = SISGETROMW(0x11c);
  10408	if(SiS_Pr->ChipType >= SIS_330) {
  10409	   romptr = SISGETROMW(0x19c);
  10410	}
  10411	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
  10412	   romptr = SISGETROMW(0x116);
  10413	   if(SiS_Pr->ChipType >= SIS_330) {
  10414              romptr = SISGETROMW(0x196);
  10415           }
  10416	}
  10417     }
  10418  }
  10419  if(romptr) {
  10420     romptr += (temp << 2);
  10421     for(j=0, i=0x31; i<=0x34; i++, j++) {
  10422        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
  10423     }
  10424  } else {
  10425     index = temp % 2;
  10426     temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
  10427     for(j=0, i=0x31; i<=0x34; i++, j++) {
  10428        if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV))
  10429	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
  10430        else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode))
  10431           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
  10432        else
  10433           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
  10434     }
  10435  }
  10436
  10437  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) {
  10438     if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) {
  10439        if((resinfo == SIS_RI_640x480) ||
  10440	   (resinfo == SIS_RI_800x600)) {
  10441	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
  10442	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
  10443	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
  10444	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
  10445	} else if(resinfo == SIS_RI_1024x768) {
  10446	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
  10447	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
  10448	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
  10449	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
  10450	}
  10451     }
  10452  }
  10453}
  10454
  10455static void
  10456SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
  10457                unsigned short ModeIdIndex, unsigned short RTI)
  10458{
  10459   unsigned short delay = 0, romptr = 0, index, lcdpdcindex;
  10460   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  10461
  10462   if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
  10463      return;
  10464
  10465   /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
  10466   /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */
  10467
  10468   if(SiS_Pr->SiS_ROMNew) {
  10469      if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) 			||
  10470         ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
  10471	  (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
  10472         index = 25;
  10473         if(SiS_Pr->UseCustomMode) {
  10474	    index = SiS_Pr->CSRClock;
  10475         } else if(ModeNo > 0x13) {
  10476            index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI);
  10477            index = SiS_Pr->SiS_VCLKData[index].CLOCK;
  10478         }
  10479	 if(index < 25) index = 25;
  10480         index = ((index / 25) - 1) << 1;
  10481         if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
  10482	    index++;
  10483	 }
  10484	 romptr = SISGETROMW(0x104);
  10485         delay = ROMAddr[romptr + index];
  10486         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
  10487            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
  10488            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
  10489         } else {
  10490            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
  10491	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
  10492         }
  10493         return;
  10494      }
  10495   }
  10496
  10497   /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
  10498
  10499   if(SiS_Pr->UseCustomMode) delay = 0x04;
  10500   else if(ModeNo <= 0x13)   delay = 0x04;
  10501   else                      delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
  10502   delay |= (delay << 8);
  10503
  10504   if(SiS_Pr->ChipType >= XGI_20) {
  10505
  10506      delay = 0x0606;
  10507      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  10508
  10509	 delay = 0x0404;
  10510         if(SiS_Pr->SiS_XGIROM) {
  10511	     index = GetTVPtrIndex(SiS_Pr);
  10512	     if((romptr = SISGETROMW(0x35e))) {
  10513	        delay = (ROMAddr[romptr + index] & 0x0f) << 1;
  10514		delay |= (delay << 8);
  10515	     }
  10516	 }
  10517
  10518	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
  10519	    if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) {
  10520	       delay -= 0x0404;
  10521	    }
  10522	 }
  10523      }
  10524
  10525   } else if(SiS_Pr->ChipType >= SIS_340) {
  10526
  10527      delay = 0x0606;
  10528      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  10529         delay = 0x0404;
  10530      }
  10531      /* TODO (eventually) */
  10532
  10533   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  10534
  10535      /* 3. TV */
  10536
  10537      index = GetOEMTVPtr661(SiS_Pr);
  10538      if(SiS_Pr->SiS_ROMNew) {
  10539         romptr = SISGETROMW(0x106);
  10540	 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12;
  10541         delay = ROMAddr[romptr + index];
  10542      } else {
  10543         delay = 0x04;
  10544	 if(index > 3) delay = 0;
  10545      }
  10546
  10547   } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  10548
  10549      /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
  10550
  10551      if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
  10552          ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) {
  10553
  10554	 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12;
  10555
  10556	 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */
  10557	 delay = ROMAddr[romptr + lcdpdcindex + 1];	/* LCD  */
  10558	 delay |= (ROMAddr[romptr + lcdpdcindex] << 8);	/* LCDA */
  10559
  10560      } else {
  10561
  10562         /* TMDS: Set our own, since BIOS has no idea */
  10563	 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */
  10564         if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
  10565	    switch(SiS_Pr->SiS_LCDResInfo) {
  10566	    case Panel_1024x768:  delay = 0x0008; break;
  10567	    case Panel_1280x720:  delay = 0x0004; break;
  10568	    case Panel_1280x768:
  10569	    case Panel_1280x768_2:delay = 0x0004; break;
  10570	    case Panel_1280x800:
  10571	    case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */
  10572	    case Panel_1280x854:  delay = 0x0004; break; /* FIXME */
  10573	    case Panel_1280x1024: delay = 0x1e04; break;
  10574	    case Panel_1400x1050: delay = 0x0004; break;
  10575	    case Panel_1600x1200: delay = 0x0400; break;
  10576	    case Panel_1680x1050: delay = 0x0e04; break;
  10577	    default:
  10578               if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
  10579	          delay = 0x0008;
  10580	       } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) {
  10581	          delay = 0x1e04;
  10582               } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
  10583	          delay = 0x0004;
  10584	       } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) {
  10585	          delay = 0x0400;
  10586               } else
  10587	          delay = 0x0e04;
  10588	       break;
  10589	    }
  10590         }
  10591
  10592	 /* Override by detected or user-set values */
  10593	 /* (but only if, for some reason, we can't read value from BIOS) */
  10594         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
  10595            delay = SiS_Pr->PDC & 0x1f;
  10596         }
  10597         if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
  10598            delay = (SiS_Pr->PDCA & 0x1f) << 8;
  10599         }
  10600
  10601      }
  10602
  10603   }
  10604
  10605   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  10606      delay >>= 8;
  10607      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
  10608      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
  10609   } else {
  10610      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
  10611      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
  10612   }
  10613}
  10614
  10615static void
  10616SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI)
  10617{
  10618   unsigned short infoflag;
  10619   unsigned char  temp;
  10620
  10621   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  10622
  10623      if(ModeNo <= 0x13) {
  10624         infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
  10625      } else if(SiS_Pr->UseCustomMode) {
  10626         infoflag = SiS_Pr->CInfoFlag;
  10627      } else {
  10628         infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
  10629      }
  10630
  10631      if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
  10632         infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */
  10633      }
  10634
  10635      infoflag &= 0xc0;
  10636
  10637      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  10638         temp = (infoflag >> 6) | 0x0c;
  10639         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
  10640	    temp ^= 0x04;
  10641	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10;
  10642	 }
  10643         SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
  10644      } else {
  10645         temp = 0x30;
  10646         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20;
  10647         temp |= infoflag;
  10648         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
  10649         temp = 0;
  10650         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
  10651	    if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80;
  10652	 }
  10653         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
  10654      }
  10655
  10656   }
  10657}
  10658
  10659static void
  10660SetPanelParms661(struct SiS_Private *SiS_Pr)
  10661{
  10662   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  10663   unsigned short romptr, temp1, temp2;
  10664
  10665   if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) {
  10666      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f);
  10667   }
  10668
  10669   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
  10670      if(SiS_Pr->LVDSHL != -1) {
  10671         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
  10672      }
  10673   }
  10674
  10675   if(SiS_Pr->SiS_ROMNew) {
  10676
  10677      if((romptr = GetLCDStructPtr661_2(SiS_Pr))) {
  10678         if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
  10679            temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
  10680	    temp2 = 0xfc;
  10681	    if(SiS_Pr->LVDSHL != -1) {
  10682	      temp1 &= 0xfc;
  10683	      temp2 = 0xf3;
  10684	    }
  10685	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
  10686         }
  10687	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  10688            temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
  10689            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
  10690	 }
  10691      }
  10692
  10693   }
  10694}
  10695
  10696static void
  10697SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI)
  10698{
  10699   if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) {
  10700      SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
  10701      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  10702         SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
  10703         SetPanelParms661(SiS_Pr);
  10704      }
  10705   } else {
  10706      SetDelayComp(SiS_Pr,ModeNo);
  10707   }
  10708
  10709   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
  10710      SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex);
  10711      SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex);
  10712      SetYFilter(SiS_Pr,ModeNo,ModeIdIndex);
  10713      if(SiS_Pr->SiS_VBType & VB_SIS301) {
  10714         SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex);
  10715      }
  10716   }
  10717}
  10718
  10719static void
  10720SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
  10721			unsigned short ModeIdIndex, unsigned short RRTI)
  10722{
  10723   if(SiS_Pr->SiS_VBType & VB_SISVB) {
  10724
  10725      SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI);
  10726
  10727      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  10728         SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI);
  10729         SetPanelParms661(SiS_Pr);
  10730      }
  10731
  10732      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  10733         SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex);
  10734         SetYFilter(SiS_Pr, ModeNo, ModeIdIndex);
  10735         SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex);
  10736         if(SiS_Pr->SiS_VBType & VB_SIS301) {
  10737            SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex);
  10738         }
  10739      }
  10740   }
  10741}
  10742
  10743/* FinalizeLCD
  10744 * This finalizes some CRT2 registers for the very panel used.
  10745 * If we have a backup if these registers, we use it; otherwise
  10746 * we set the register according to most BIOSes. However, this
  10747 * function looks quite different in every BIOS, so you better
  10748 * pray that we have a backup...
  10749 */
  10750static void
  10751SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  10752{
  10753  unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
  10754  unsigned short resinfo,modeflag;
  10755
  10756  if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return;
  10757  if(SiS_Pr->SiS_ROMNew) return;
  10758
  10759  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  10760     if(SiS_Pr->LVDSHL != -1) {
  10761        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
  10762     }
  10763  }
  10764
  10765  if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
  10766  if(SiS_Pr->UseCustomMode) return;
  10767
  10768  switch(SiS_Pr->SiS_CustomT) {
  10769  case CUT_COMPAQ1280:
  10770  case CUT_COMPAQ12802:
  10771  case CUT_CLEVO1400:
  10772  case CUT_CLEVO14002:
  10773     return;
  10774  }
  10775
  10776  if(ModeNo <= 0x13) {
  10777     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
  10778     modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  10779  } else {
  10780     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  10781     modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  10782  }
  10783
  10784  if(IS_SIS650) {
  10785     if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
  10786        if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
  10787	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
  10788	} else {
  10789           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
  10790	}
  10791     }
  10792  }
  10793
  10794  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
  10795     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
  10796        /* Maybe all panels? */
  10797        if(SiS_Pr->LVDSHL == -1) {
  10798           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
  10799	}
  10800	return;
  10801     }
  10802  }
  10803
  10804  if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
  10805     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  10806        if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
  10807	   if(SiS_Pr->LVDSHL == -1) {
  10808	      /* Maybe all panels? */
  10809              SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
  10810	   }
  10811	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  10812	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
  10813	      if(tempch == 3) {
  10814	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
  10815	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
  10816	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
  10817	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
  10818	      }
  10819	   }
  10820	   return;
  10821	}
  10822     }
  10823  }
  10824
  10825  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
  10826     if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
  10827	if(SiS_Pr->SiS_VBType & VB_SISEMI) {
  10828	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
  10829#ifdef SET_EMI
  10830	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
  10831#endif
  10832	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
  10833	}
  10834     } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
  10835        if(SiS_Pr->LVDSHL == -1) {
  10836           /* Maybe ACER only? */
  10837           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
  10838	}
  10839     }
  10840     tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
  10841     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
  10842	if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
  10843	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
  10844	} else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
  10845	   if(tempch == 0x03) {
  10846	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
  10847	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
  10848	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
  10849	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
  10850	   }
  10851	   if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
  10852	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
  10853	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
  10854	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
  10855	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
  10856	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
  10857	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
  10858	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
  10859	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
  10860	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
  10861	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
  10862	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
  10863	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
  10864	      if(ModeNo <= 0x13) {
  10865	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
  10866		 if((resinfo == 0) || (resinfo == 2)) return;
  10867		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
  10868		 if((resinfo == 1) || (resinfo == 3)) return;
  10869	      }
  10870	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
  10871	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
  10872	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
  10873#if 0
  10874	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
  10875		 tempbx--;
  10876		 temp = tempbx & 0xff;
  10877		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
  10878		 temp = (tempbx >> 8) & 0x03;
  10879		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
  10880#endif
  10881	      }
  10882	   } else if(ModeNo <= 0x13) {
  10883	      if(ModeNo <= 1) {
  10884		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
  10885		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
  10886		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
  10887		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
  10888	      }
  10889	      if(!(modeflag & HalfDCLK)) {
  10890		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
  10891		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
  10892		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
  10893		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
  10894		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
  10895		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
  10896		 if(ModeNo == 0x12) {
  10897		    switch(tempch) {
  10898		       case 0:
  10899			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
  10900			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
  10901			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
  10902			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
  10903			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
  10904			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
  10905			  break;
  10906		       case 2:
  10907			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
  10908			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
  10909			  break;
  10910		       case 3:
  10911			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
  10912			  break;
  10913		    }
  10914		 }
  10915	      }
  10916	   }
  10917	}
  10918     } else {
  10919        tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
  10920	tempcl &= 0x0f;
  10921	tempbh &= 0x70;
  10922	tempbh >>= 4;
  10923	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
  10924	tempbx = (tempbh << 8) | tempbl;
  10925	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
  10926	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
  10927	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
  10928	      	 tempbx = 770;
  10929	      } else {
  10930	         if(tempbx > 770) tempbx = 770;
  10931		 if(SiS_Pr->SiS_VGAVDE < 600) {
  10932		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
  10933		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
  10934		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
  10935		    tempbx -= tempax;
  10936		 }
  10937	      }
  10938	   } else return;
  10939	}
  10940	temp = tempbx & 0xff;
  10941	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
  10942	temp = ((tempbx & 0xff00) >> 4) | tempcl;
  10943	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
  10944     }
  10945  }
  10946}
  10947
  10948#endif
  10949
  10950/*  =================  SiS 300 O.E.M. ================== */
  10951
  10952#ifdef CONFIG_FB_SIS_300
  10953
  10954static void
  10955SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
  10956		unsigned short RefTabIndex)
  10957{
  10958  unsigned short crt2crtc=0, modeflag, myindex=0;
  10959  unsigned char  temp;
  10960  int i;
  10961
  10962  if(ModeNo <= 0x13) {
  10963     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
  10964     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
  10965  } else {
  10966     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
  10967     crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
  10968  }
  10969
  10970  crt2crtc &= 0x3f;
  10971
  10972  if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
  10973     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
  10974  }
  10975
  10976  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
  10977     if(modeflag & HalfDCLK) myindex = 1;
  10978
  10979     if(SiS_Pr->SiS_SetFlag & LowModeTests) {
  10980        for(i=0; i<7; i++) {
  10981           if(barco_p1[myindex][crt2crtc][i][0]) {
  10982	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
  10983	                      barco_p1[myindex][crt2crtc][i][0],
  10984	   	   	      barco_p1[myindex][crt2crtc][i][2],
  10985			      barco_p1[myindex][crt2crtc][i][1]);
  10986	   }
  10987        }
  10988     }
  10989     temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
  10990     if(temp & 0x80) {
  10991        temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
  10992        temp++;
  10993        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
  10994     }
  10995  }
  10996}
  10997
  10998static unsigned short
  10999GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag)
  11000{
  11001  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  11002  unsigned short tempbx=0,romptr=0;
  11003  static const unsigned char customtable300[] = {
  11004	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  11005	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
  11006  };
  11007  static const unsigned char customtable630[] = {
  11008	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  11009	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
  11010  };
  11011
  11012  if(SiS_Pr->ChipType == SIS_300) {
  11013
  11014    tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f;
  11015    if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07;
  11016    tempbx -= 2;
  11017    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
  11018    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
  11019       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
  11020    }
  11021    if(SiS_Pr->SiS_UseROM) {
  11022       if(ROMAddr[0x235] & 0x80) {
  11023          tempbx = SiS_Pr->SiS_LCDTypeInfo;
  11024          if(Flag) {
  11025	     romptr = SISGETROMW(0x255);
  11026	     if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
  11027	     else       tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
  11028             if(tempbx == 0xFF) return 0xFFFF;
  11029          }
  11030	  tempbx <<= 1;
  11031	  if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
  11032       }
  11033    }
  11034
  11035  } else {
  11036
  11037    if(Flag) {
  11038       if(SiS_Pr->SiS_UseROM) {
  11039          romptr = SISGETROMW(0x255);
  11040	  if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
  11041	  else 	     tempbx = 0xff;
  11042       } else {
  11043          tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
  11044       }
  11045       if(tempbx == 0xFF) return 0xFFFF;
  11046       tempbx <<= 2;
  11047       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
  11048       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
  11049       return tempbx;
  11050    }
  11051    tempbx = SiS_Pr->SiS_LCDTypeInfo << 2;
  11052    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2;
  11053    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
  11054
  11055  }
  11056
  11057  return tempbx;
  11058}
  11059
  11060static void
  11061SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
  11062{
  11063  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  11064  unsigned short index,temp,romptr=0;
  11065
  11066  if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
  11067
  11068  if(SiS_Pr->SiS_UseROM) {
  11069     if(!(ROMAddr[0x237] & 0x01)) return;
  11070     if(!(ROMAddr[0x237] & 0x02)) return;
  11071     romptr = SISGETROMW(0x24b);
  11072  }
  11073
  11074  /* The Panel Compensation Delay should be set according to tables
  11075   * here. Unfortunately, various BIOS versions don't care about
  11076   * a uniform way using eg. ROM byte 0x220, but use different
  11077   * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
  11078   * Thus we don't set this if the user selected a custom pdc or if
  11079   * we otherwise detected a valid pdc.
  11080   */
  11081  if(SiS_Pr->PDC != -1) return;
  11082
  11083  temp = GetOEMLCDPtr(SiS_Pr, 0);
  11084
  11085  if(SiS_Pr->UseCustomMode)
  11086     index = 0;
  11087  else
  11088     index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
  11089
  11090  if(SiS_Pr->ChipType != SIS_300) {
  11091     if(romptr) {
  11092	romptr += (temp * 2);
  11093	romptr = SISGETROMW(romptr);
  11094	romptr += index;
  11095	temp = ROMAddr[romptr];
  11096     } else {
  11097	if(SiS_Pr->SiS_VBType & VB_SISVB) {
  11098    	   temp = SiS300_OEMLCDDelay2[temp][index];
  11099	} else {
  11100           temp = SiS300_OEMLCDDelay3[temp][index];
  11101        }
  11102     }
  11103  } else {
  11104     if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
  11105	if(romptr) {
  11106	   romptr += (temp * 2);
  11107	   romptr = SISGETROMW(romptr);
  11108	   romptr += index;
  11109	   temp = ROMAddr[romptr];
  11110	} else {
  11111	   temp = SiS300_OEMLCDDelay5[temp][index];
  11112	}
  11113     } else {
  11114        if(SiS_Pr->SiS_UseROM) {
  11115	   romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
  11116	   if(romptr) {
  11117	      romptr += (temp * 2);
  11118	      romptr = SISGETROMW(romptr);
  11119	      romptr += index;
  11120	      temp = ROMAddr[romptr];
  11121	   } else {
  11122	      temp = SiS300_OEMLCDDelay4[temp][index];
  11123	   }
  11124	} else {
  11125	   temp = SiS300_OEMLCDDelay4[temp][index];
  11126	}
  11127     }
  11128  }
  11129  temp &= 0x3c;
  11130  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);  /* index 0A D[6:4] */
  11131}
  11132
  11133static void
  11134SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  11135{
  11136#if 0  /* Unfinished; Data table missing */
  11137  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  11138  unsigned short index,temp;
  11139
  11140  if((SiS_Pr->SiS_UseROM) {
  11141     if(!(ROMAddr[0x237] & 0x01)) return;
  11142     if(!(ROMAddr[0x237] & 0x04)) return;
  11143     /* No rom pointer in BIOS header! */
  11144  }
  11145
  11146  temp = GetOEMLCDPtr(SiS_Pr, 1);
  11147  if(temp == 0xFFFF) return;
  11148
  11149  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
  11150  for(i=0x14, j=0; i<=0x17; i++, j++) {
  11151      SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
  11152  }
  11153  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
  11154
  11155  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
  11156  SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
  11157  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
  11158  SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
  11159  for(i=0x1b, j=3; i<=0x1d; i++, j++) {
  11160      SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
  11161  }
  11162#endif
  11163}
  11164
  11165static unsigned short
  11166GetOEMTVPtr(struct SiS_Private *SiS_Pr)
  11167{
  11168  unsigned short index;
  11169
  11170  index = 0;
  11171  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  index += 4;
  11172  if(SiS_Pr->SiS_VBType & VB_SISVB) {
  11173     if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)  index += 2;
  11174     else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3;
  11175     else if(SiS_Pr->SiS_TVMode & TVSetPAL)   index += 1;
  11176  } else {
  11177     if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2;
  11178     if(SiS_Pr->SiS_TVMode & TVSetPAL)        index += 1;
  11179  }
  11180  return index;
  11181}
  11182
  11183static void
  11184SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  11185{
  11186  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  11187  unsigned short index,temp,romptr=0;
  11188
  11189  if(SiS_Pr->SiS_UseROM) {
  11190     if(!(ROMAddr[0x238] & 0x01)) return;
  11191     if(!(ROMAddr[0x238] & 0x02)) return;
  11192     romptr = SISGETROMW(0x241);
  11193  }
  11194
  11195  temp = GetOEMTVPtr(SiS_Pr);
  11196
  11197  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex;
  11198
  11199  if(romptr) {
  11200     romptr += (temp * 2);
  11201     romptr = SISGETROMW(romptr);
  11202     romptr += index;
  11203     temp = ROMAddr[romptr];
  11204  } else {
  11205     if(SiS_Pr->SiS_VBType & VB_SISVB) {
  11206        temp = SiS300_OEMTVDelay301[temp][index];
  11207     } else {
  11208        temp = SiS300_OEMTVDelayLVDS[temp][index];
  11209     }
  11210  }
  11211  temp &= 0x3c;
  11212  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
  11213}
  11214
  11215static void
  11216SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  11217{
  11218  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  11219  unsigned short index,temp,romptr=0;
  11220
  11221  if(SiS_Pr->SiS_UseROM) {
  11222     if(!(ROMAddr[0x238] & 0x01)) return;
  11223     if(!(ROMAddr[0x238] & 0x04)) return;
  11224     romptr = SISGETROMW(0x243);
  11225  }
  11226
  11227  temp = GetOEMTVPtr(SiS_Pr);
  11228
  11229  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex;
  11230
  11231  if(romptr) {
  11232     romptr += (temp * 2);
  11233     romptr = SISGETROMW(romptr);
  11234     romptr += index;
  11235     temp = ROMAddr[romptr];
  11236  } else {
  11237     temp = SiS300_OEMTVFlicker[temp][index];
  11238  }
  11239  temp &= 0x70;
  11240  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
  11241}
  11242
  11243static void
  11244SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex)
  11245{
  11246  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  11247  unsigned short index,i,j,temp,romptr=0;
  11248
  11249  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return;
  11250
  11251  if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
  11252
  11253  if(SiS_Pr->SiS_UseROM) {
  11254     if(!(ROMAddr[0x238] & 0x01)) return;
  11255     if(!(ROMAddr[0x238] & 0x08)) return;
  11256     romptr = SISGETROMW(0x245);
  11257  }
  11258
  11259  temp = GetOEMTVPtr(SiS_Pr);
  11260
  11261  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex;
  11262
  11263  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  11264     for(i=0x31, j=0; i<=0x34; i++, j++) {
  11265        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
  11266     }
  11267  } else {
  11268     if(romptr) {
  11269        romptr += (temp * 2);
  11270	romptr = SISGETROMW(romptr);
  11271	romptr += (index * 4);
  11272        for(i=0x31, j=0; i<=0x34; i++, j++) {
  11273	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
  11274	}
  11275     } else {
  11276        for(i=0x31, j=0; i<=0x34; i++, j++) {
  11277           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
  11278	}
  11279     }
  11280  }
  11281}
  11282
  11283static void
  11284SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
  11285{
  11286  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  11287  unsigned short index,temp,i,j,romptr=0;
  11288
  11289  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
  11290
  11291  if(SiS_Pr->SiS_UseROM) {
  11292     if(!(ROMAddr[0x238] & 0x01)) return;
  11293     if(!(ROMAddr[0x238] & 0x10)) return;
  11294     romptr = SISGETROMW(0x247);
  11295  }
  11296
  11297  temp = GetOEMTVPtr(SiS_Pr);
  11298
  11299  if(SiS_Pr->SiS_TVMode & TVSetPALM)      temp = 8;
  11300  else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9;
  11301  /* NTSCJ uses NTSC filters */
  11302
  11303  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
  11304
  11305  if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
  11306      for(i=0x35, j=0; i<=0x38; i++, j++) {
  11307       	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
  11308      }
  11309      for(i=0x48; i<=0x4A; i++, j++) {
  11310     	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
  11311      }
  11312  } else {
  11313      if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
  11314         romptr += (temp * 2);
  11315	 romptr = SISGETROMW(romptr);
  11316	 romptr += (index * 4);
  11317	 for(i=0x35, j=0; i<=0x38; i++, j++) {
  11318       	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
  11319         }
  11320      } else {
  11321         for(i=0x35, j=0; i<=0x38; i++, j++) {
  11322       	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
  11323         }
  11324      }
  11325  }
  11326}
  11327
  11328static unsigned short
  11329SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo)
  11330{
  11331   unsigned short ModeIdIndex;
  11332   unsigned char  VGAINFO = SiS_Pr->SiS_VGAINFO;
  11333
  11334   if(*ModeNo <= 5) *ModeNo |= 1;
  11335
  11336   for(ModeIdIndex=0; ; ModeIdIndex++) {
  11337      if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
  11338      if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
  11339   }
  11340
  11341   if(*ModeNo != 0x07) {
  11342      if(*ModeNo > 0x03) return ModeIdIndex;
  11343      if(VGAINFO & 0x80) return ModeIdIndex;
  11344      ModeIdIndex++;
  11345   }
  11346
  11347   if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
  11348	                               /* else 350 lines */
  11349   return ModeIdIndex;
  11350}
  11351
  11352static void
  11353SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
  11354		  unsigned short RefTableIndex)
  11355{
  11356  unsigned short OEMModeIdIndex = 0;
  11357
  11358  if(!SiS_Pr->UseCustomMode) {
  11359     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
  11360     if(!(OEMModeIdIndex)) return;
  11361  }
  11362
  11363  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
  11364     SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex);
  11365     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
  11366        SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex);
  11367     }
  11368  }
  11369  if(SiS_Pr->UseCustomMode) return;
  11370  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
  11371     SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex);
  11372     if(SiS_Pr->SiS_VBType & VB_SISVB) {
  11373        SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex);
  11374    	SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex);
  11375       	SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex);
  11376     }
  11377  }
  11378}
  11379#endif
  11380