/* $XFree86$ */
/* $XdotOrg$ */
/*
 * Mode initializing code (CRT2 section)
 * for SiS 300/305/540/630/730,
 *     SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX],
 *     XGI V3XT/V5/V8, Z7
 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x)
 *
 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
 *
 * If distributed as part of the Linux kernel, the following license terms
 * apply:
 *
 * * This program is free software; you can redistribute it and/or modify
 * * it under the terms of the GNU General Public License as published by
 * * the Free Software Foundation; either version 2 of the named License,
 * * or any later version.
 * *
 * * This program is distributed in the hope that it will be useful,
 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * * GNU General Public License for more details.
 * *
 * * You should have received a copy of the GNU General Public License
 * * along with this program; if not, write to the Free Software
 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
 *
 * Otherwise, the following license terms apply:
 *
 * * Redistribution and use in source and binary forms, with or without
 * * modification, are permitted provided that the following conditions
 * * are met:
 * * 1) Redistributions of source code must retain the above copyright
 * *    notice, this list of conditions and the following disclaimer.
 * * 2) Redistributions in binary form must reproduce the above copyright
 * *    notice, this list of conditions and the following disclaimer in the
 * *    documentation and/or other materials provided with the distribution.
 * * 3) The name of the author may not be used to endorse or promote products
 * *    derived from this software without specific prior written permission.
 * *
 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
 *
 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
 * Used by permission.
 *
 */

#if 1
#define SET_EMI		/* 302LV/ELV: Set EMI values */
#endif

#if 1
#define SET_PWD		/* 301/302LV: Set PWD */
#endif

#define COMPAL_HACK	/* Needed for Compal 1400x1050 (EMI) */
#define COMPAQ_HACK	/* Needed for Inventec/Compaq 1280x1024 (EMI) */
#define ASUS_HACK	/* Needed for Asus A2H 1024x768 (EMI) */

#include "init301.h"

#ifdef CONFIG_FB_SIS_300
#include "oem300.h"
#endif

#ifdef CONFIG_FB_SIS_315
#include "oem310.h"
#endif

#define SiS_I2CDELAY      1000
#define SiS_I2CDELAYSHORT  150

static const unsigned char SiS_YPbPrTable[3][64] = {
  {
    0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
    0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
    0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
    0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
    0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
    0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
  },
  {
    0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
    0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
    0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
    0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
    0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e,
    0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
  },
  {
#if 0 /* OK, but sticks to left edge */
    0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
    0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
    0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
    0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
    0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
    0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
#endif
#if 1 /* Perfect */
    0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
    0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
    0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
    0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
    0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
    0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
    0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73,
    0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
#endif
  }
};

static const unsigned char SiS_TVPhase[] =
{
	0x21,0xED,0xBA,0x08,	/* 0x00 SiS_NTSCPhase */
	0x2A,0x05,0xE3,0x00,	/* 0x01 SiS_PALPhase */
	0x21,0xE4,0x2E,0x9B,	/* 0x02 SiS_PALMPhase */
	0x21,0xF4,0x3E,0xBA,	/* 0x03 SiS_PALNPhase */
	0x1E,0x8B,0xA2,0xA7,
	0x1E,0x83,0x0A,0xE0,	/* 0x05 SiS_SpecialPhaseM */
	0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,
	0x21,0xF0,0x7B,0xD6,	/* 0x08 SiS_NTSCPhase2 */
	0x2A,0x09,0x86,0xE9,	/* 0x09 SiS_PALPhase2 */
	0x21,0xE6,0xEF,0xA4,	/* 0x0a SiS_PALMPhase2 */
	0x21,0xF6,0x94,0x46,	/* 0x0b SiS_PALNPhase2 */
	0x1E,0x8B,0xA2,0xA7,
	0x1E,0x83,0x0A,0xE0,	/* 0x0d SiS_SpecialPhaseM */
	0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,
	0x1e,0x8c,0x5c,0x7a,	/* 0x10 SiS_SpecialPhase */
	0x25,0xd4,0xfd,0x5e	/* 0x11 SiS_SpecialPhaseJ */
};

static const unsigned char SiS_HiTVGroup3_1[] = {
    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
    0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6,
    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
    0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10,
    0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80,
    0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0,
    0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e,
    0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01
};

static const unsigned char SiS_HiTVGroup3_2[] = {
    0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
    0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6,
    0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20,
    0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10,
    0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80,
    0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94,
    0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
    0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
};

/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */

static const unsigned char SiS_Part2CLVX_1[] = {
    0x00,0x00,
    0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
    0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
    0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
    0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
};

static const unsigned char SiS_Part2CLVX_2[] = {
    0x00,0x00,
    0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E,
    0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C,
    0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C,
    0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E
};

static const unsigned char SiS_Part2CLVX_3[] = {  /* NTSC, 525i, 525p */
    0xE0,0x01,
    0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D,
    0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C,
    0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E,
    0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02,
    0x58,0x02,
    0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E,
    0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F,
    0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03,
    0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06,
    0x00,0x03,
    0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01,
    0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03,
    0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06,
    0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08,
    0xFF,0xFF
};

static const unsigned char SiS_Part2CLVX_4[] = {   /* PAL */
    0x58,0x02,
    0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
    0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
    0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
    0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
    0x00,0x03,
    0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F,
    0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01,
    0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04,
    0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07,
    0x40,0x02,
    0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
    0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
    0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
    0xFF,0xFF
};

static const unsigned char SiS_Part2CLVX_5[] = {   /* 750p */
    0x00,0x03,
    0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D,
    0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D,
    0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E,
    0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04,
    0xFF,0xFF
};

static const unsigned char SiS_Part2CLVX_6[] = {   /* 1080i */
    0x00,0x04,
    0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
    0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
    0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
    0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
    0xFF,0xFF,
};

#ifdef CONFIG_FB_SIS_315
/* 661 et al LCD data structure (2.03.00) */
static const unsigned char SiS_LCDStruct661[] = {
    /* 1024x768 */
/*  type|CR37|   HDE   |   VDE   |    HT   |    VT   |   hss    | hse   */
    0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
    0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
    /*  | vss     |    vse  |clck|  clock  |CRT2DataP|CRT2DataP|idx     */
    /*					      VESA    non-VESA  noscale */
    /* 1280x1024 */
    0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
    /* 1400x1050 */
    0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
    0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
    /* 1600x1200 */
    0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
    0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A,
    /* 1280x768 (_2) */
    0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70,
    0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06,
    /* 1280x720 */
    0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20,
    0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
    /* 1280x800 (_2) */
    0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70,
    0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09,
    /* 1680x1050 */
    0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
    0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
    /* 1280x800_3 */
    0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50,
    0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07,
    /* 800x600 */
    0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80,
    0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00,
    /* 1280x854 */
    0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70,
    0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08
};
#endif

#ifdef CONFIG_FB_SIS_300
static unsigned char SiS300_TrumpionData[14][80] = {
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
    0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
    0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
    0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
    0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
    0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
  /* variant 2 */
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23,
    0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05,
    0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
    0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
    0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
    0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
    0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
    0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
    0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
    0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
    0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
    0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
    0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 },
  { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
    0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
    0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
    0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
    0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }
};
#endif

#ifdef CONFIG_FB_SIS_315
static void	SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
static void	SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
static void	SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
static void	SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr);
#endif /* 315 */

#ifdef CONFIG_FB_SIS_300
static  bool	SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
#endif

static unsigned short	SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
				int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
				bool checkcr32, unsigned int VBFlags2);
static unsigned short	SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
				unsigned char *buffer);
static void		SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_SetStart(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_SetStop(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_SetSCLKLow(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax);
static unsigned short	SiS_CheckACK(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_WriteDABDDC(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr);
static unsigned short	SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
static void		SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
static unsigned short	SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);

#ifdef CONFIG_FB_SIS_300
static void		SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
				unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
static void		SetOEMLCDData2(struct SiS_Private *SiS_Pr,
				unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
#endif
#ifdef CONFIG_FB_SIS_315
static void		SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
static void		SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
				unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
static void		SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short);
#endif

static unsigned short	SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
static void		SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);

/*********************************************/
/*         HELPER: Lock/Unlock CRT2          */
/*********************************************/

void
SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
{
   if(SiS_Pr->ChipType == XGI_20)
      return;
   else if(SiS_Pr->ChipType >= SIS_315H)
      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
   else
      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
}

static
void
SiS_LockCRT2(struct SiS_Private *SiS_Pr)
{
   if(SiS_Pr->ChipType == XGI_20)
      return;
   else if(SiS_Pr->ChipType >= SIS_315H)
      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
   else
      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
}

/*********************************************/
/*            HELPER: Write SR11             */
/*********************************************/

static void
SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR)
{
   if(SiS_Pr->ChipType >= SIS_661) {
      DataAND &= 0x0f;
      DataOR  &= 0x0f;
   }
   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
}

/*********************************************/
/*    HELPER: Get Pointer to LCD structure   */
/*********************************************/

#ifdef CONFIG_FB_SIS_315
static unsigned char *
GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
{
   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned char  *myptr = NULL;
   unsigned short romindex = 0, reg = 0, idx = 0;

   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
    * due to the variaty of panels the BIOS doesn't know about.
    * Exception: If the BIOS has better knowledge (such as in case
    * of machines with a 301C and a panel that does not support DDC)
    * use the BIOS data as well.
    */

   if((SiS_Pr->SiS_ROMNew) &&
      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {

      if(SiS_Pr->ChipType < SIS_661) reg = 0x3c;
      else                           reg = 0x7d;

      idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26;

      if(idx < (8*26)) {
         myptr = (unsigned char *)&SiS_LCDStruct661[idx];
      }
      romindex = SISGETROMW(0x100);
      if(romindex) {
         romindex += idx;
         myptr = &ROMAddr[romindex];
      }
   }
   return myptr;
}

static unsigned short
GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
{
   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned short romptr = 0;

   /* Use the BIOS tables only for LVDS panels; TMDS is unreliable
    * due to the variaty of panels the BIOS doesn't know about.
    * Exception: If the BIOS has better knowledge (such as in case
    * of machines with a 301C and a panel that does not support DDC)
    * use the BIOS data as well.
    */

   if((SiS_Pr->SiS_ROMNew) &&
      ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) {
      romptr = SISGETROMW(0x102);
      romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
   }

   return romptr;
}
#endif

/*********************************************/
/*           Adjust Rate for CRT2            */
/*********************************************/

static bool
SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
		unsigned short RRTI, unsigned short *i)
{
   unsigned short checkmask=0, modeid, infoflag;

   modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID;

   if(SiS_Pr->SiS_VBType & VB_SISVB) {

      if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {

	 checkmask |= SupportRAMDAC2;
	 if(SiS_Pr->ChipType >= SIS_315H) {
	    checkmask |= SupportRAMDAC2_135;
	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
	       checkmask |= SupportRAMDAC2_162;
	       if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) {
		  checkmask |= SupportRAMDAC2_202;
	       }
	    }
	 }

      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {

	 checkmask |= SupportLCD;
	 if(SiS_Pr->ChipType >= SIS_315H) {
	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
	       if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
	          if(modeid == 0x2e) checkmask |= Support64048060Hz;
	       }
	    }
	 }

      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {

	 checkmask |= SupportHiVision;

      } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {

	 checkmask |= SupportTV;
	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
	    checkmask |= SupportTV1024;
	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
	       if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
	          checkmask |= SupportYPbPr750p;
	       }
	    }
	 }

      }

   } else {	/* LVDS */

      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
	    checkmask |= SupportCHTV;
	 }
      }

      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
	 checkmask |= SupportLCD;
      }

   }

   /* Look backwards in table for matching CRT2 mode */
   for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
      infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
      if(infoflag & checkmask) return true;
      if((*i) == 0) break;
   }

   /* Look through the whole mode-section of the table from the beginning
    * for a matching CRT2 mode if no mode was found yet.
    */
   for((*i) = 0; ; (*i)++) {
      if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
      infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
      if(infoflag & checkmask) return true;
   }
   return false;
}

/*********************************************/
/*              Get rate index               */
/*********************************************/

unsigned short
SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
   unsigned short RRTI,i,backup_i;
   unsigned short modeflag,index,temp,backupindex;
   static const unsigned short LCDRefreshIndex[] = {
		0x00, 0x00, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01,
		0x01, 0x01, 0x01, 0x01,
		0x00, 0x00, 0x00, 0x00
   };

   /* Do NOT check for UseCustomMode here, will skrew up FIFO */
   if(ModeNo == 0xfe) return 0;

   if(ModeNo <= 0x13) {
      modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }

   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
	 if(modeflag & HalfDCLK) return 0;
      }
   }

   if(ModeNo < 0x14) return 0xFFFF;

   index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
   backupindex = index;

   if(index > 0) index--;

   if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
      if(SiS_Pr->SiS_VBType & VB_SISVB) {
	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
	    if(SiS_Pr->SiS_VBType & VB_NoLCD)		 index = 0;
	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0;
	 }
	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
	    if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
	       temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
	       if(index > temp) index = temp;
	    }
	 }
      } else {
	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0;
	 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0;
	 }
      }
   }

   RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
   ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID;

   if(SiS_Pr->ChipType >= SIS_315H) {
      if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
	 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
	     (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
	    if(backupindex <= 1) RRTI++;
	 }
      }
   }

   i = 0;
   do {
      if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break;
      temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag;
      temp &= ModeTypeMask;
      if(temp < SiS_Pr->SiS_ModeType) break;
      i++;
      index--;
   } while(index != 0xFFFF);

   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
	 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag;
	 if(temp & InterlaceMode) i++;
      }
   }

   i--;

   if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
      backup_i = i;
      if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) {
	 i = backup_i;
      }
   }

   return (RRTI + i);
}

/*********************************************/
/*            STORE CRT2 INFO in CR34        */
/*********************************************/

static void
SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
   unsigned short temp1, temp2;

   /* Store CRT1 ModeNo in CR34 */
   SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
   temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
   temp2 = ~(SetInSlaveMode >> 8);
   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
}

/*********************************************/
/*    HELPER: GET SOME DATA FROM BIOS ROM    */
/*********************************************/

#ifdef CONFIG_FB_SIS_300
static bool
SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
{
   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned short temp,temp1;

   if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
	 temp1 = SISGETROMW(0x23b);
	 if(temp1 & temp) return true;
      }
   }
   return false;
}

static bool
SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
{
   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned short temp,temp1;

   if(SiS_Pr->SiS_UseROM) {
      if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
	 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
	 temp1 = SISGETROMW(0x23d);
	 if(temp1 & temp) return true;
      }
   }
   return false;
}
#endif

/*********************************************/
/*          HELPER: DELAY FUNCTIONS          */
/*********************************************/

void
SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
{
   while (delaytime-- > 0)
      SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
}

#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static void
SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
   SiS_DDC2Delay(SiS_Pr, delay * 36);
}
#endif

#ifdef CONFIG_FB_SIS_315
static void
SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
   while(delay--) {
      SiS_GenericDelay(SiS_Pr, 6623);
   }
}
#endif

#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static void
SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
   while(delay--) {
      SiS_GenericDelay(SiS_Pr, 66);
   }
}
#endif

static void
SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
{
#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned short PanelID, DelayIndex, Delay=0;
#endif

   if(SiS_Pr->ChipType < SIS_315H) {

#ifdef CONFIG_FB_SIS_300

      PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
      if(SiS_Pr->SiS_VBType & VB_SISVB) {
	 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7;
	 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12;
      }
      DelayIndex = PanelID >> 4;
      if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
	 Delay = 3;
      } else {
	 if(DelayTime >= 2) DelayTime -= 2;
	 if(!(DelayTime & 0x01)) {
	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
	 } else {
	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
	 }
	 if(SiS_Pr->SiS_UseROM) {
	    if(ROMAddr[0x220] & 0x40) {
	       if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225];
	       else 	    	       Delay = (unsigned short)ROMAddr[0x226];
	    }
	 }
      }
      SiS_ShortDelay(SiS_Pr, Delay);

#endif  /* CONFIG_FB_SIS_300 */

   } else {

#ifdef CONFIG_FB_SIS_315

      if((SiS_Pr->ChipType >= SIS_661)    ||
	 (SiS_Pr->ChipType <= SIS_315PRO) ||
	 (SiS_Pr->ChipType == SIS_330)    ||
	 (SiS_Pr->SiS_ROMNew)) {

	 if(!(DelayTime & 0x01)) {
	    SiS_DDC2Delay(SiS_Pr, 0x1000);
	 } else {
	    SiS_DDC2Delay(SiS_Pr, 0x4000);
	 }

      } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS; Special */

	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
	    PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
	    if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12;
	    }
	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
	       DelayIndex = PanelID & 0x0f;
	    } else {
	       DelayIndex = PanelID >> 4;
	    }
	    if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
	       Delay = 3;
	    } else {
	       if(DelayTime >= 2) DelayTime -= 2;
	       if(!(DelayTime & 0x01)) {
		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
		} else {
		  Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
	       }
	       if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
		  if(ROMAddr[0x13c] & 0x40) {
		     if(!(DelayTime & 0x01)) {
			Delay = (unsigned short)ROMAddr[0x17e];
		     } else {
			Delay = (unsigned short)ROMAddr[0x17f];
		     }
		  }
	       }
	    }
	    SiS_ShortDelay(SiS_Pr, Delay);
	 }

      } else if(SiS_Pr->SiS_VBType & VB_SISVB) {			/* 315 series, all bridges */

	 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
	 if(!(DelayTime & 0x01)) {
	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
	 } else {
	    Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
	 }
	 Delay <<= 8;
	 SiS_DDC2Delay(SiS_Pr, Delay);

      }

#endif /* CONFIG_FB_SIS_315 */

   }
}

#ifdef CONFIG_FB_SIS_315
static void
SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
{
   int i;
   for(i = 0; i < DelayLoop; i++) {
      SiS_PanelDelay(SiS_Pr, DelayTime);
   }
}
#endif

/*********************************************/
/*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
/*********************************************/

void
SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
{
   unsigned short watchdog;

   if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
   if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;

   watchdog = 65535;
   while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
   watchdog = 65535;
   while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
}

#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static void
SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
{
   unsigned short watchdog;

   watchdog = 65535;
   while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
   watchdog = 65535;
   while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
}
#endif

static void
SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
{
   if(SiS_Pr->ChipType < SIS_315H) {
#ifdef CONFIG_FB_SIS_300
      if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
	 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
      }
      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
	 SiS_WaitRetrace1(SiS_Pr);
      } else {
	 SiS_WaitRetrace2(SiS_Pr, 0x25);
      }
#endif
   } else {
#ifdef CONFIG_FB_SIS_315
      if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
	 SiS_WaitRetrace1(SiS_Pr);
      } else {
	 SiS_WaitRetrace2(SiS_Pr, 0x30);
      }
#endif
   }
}

static void
SiS_VBWait(struct SiS_Private *SiS_Pr)
{
   unsigned short tempal,temp,i,j;

   temp = 0;
   for(i = 0; i < 3; i++) {
     for(j = 0; j < 100; j++) {
        tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
        if(temp & 0x01) {
	   if((tempal & 0x08))  continue;
	   else break;
        } else {
	   if(!(tempal & 0x08)) continue;
	   else break;
        }
     }
     temp ^= 0x01;
   }
}

static void
SiS_VBLongWait(struct SiS_Private *SiS_Pr)
{
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      SiS_VBWait(SiS_Pr);
   } else {
      SiS_WaitRetrace1(SiS_Pr);
   }
}

/*********************************************/
/*               HELPER: MISC                */
/*********************************************/

#ifdef CONFIG_FB_SIS_300
static bool
SiS_Is301B(struct SiS_Private *SiS_Pr)
{
   if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
   return false;
}
#endif

static bool
SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
{
   if(SiS_Pr->ChipType == SIS_730) {
      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
   }
   if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
   return false;
}

bool
SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
{
#ifdef CONFIG_FB_SIS_315
   if(SiS_Pr->ChipType >= SIS_315H) {
      if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
      }
   }
#endif
   return false;
}

bool
SiS_IsVAMode(struct SiS_Private *SiS_Pr)
{
#ifdef CONFIG_FB_SIS_315
   unsigned short flag;

   if(SiS_Pr->ChipType >= SIS_315H) {
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
      if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
   }
#endif
   return false;
}

#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
{
   if(SiS_IsVAMode(SiS_Pr))  return true;
   if(SiS_CRT2IsLCD(SiS_Pr)) return true;
   return false;
}
#endif

static bool
SiS_IsDualLink(struct SiS_Private *SiS_Pr)
{
#ifdef CONFIG_FB_SIS_315
   if(SiS_Pr->ChipType >= SIS_315H) {
      if((SiS_CRT2IsLCD(SiS_Pr)) ||
         (SiS_IsVAMode(SiS_Pr))) {
	 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
      }
   }
#endif
   return false;
}

#ifdef CONFIG_FB_SIS_315
static bool
SiS_TVEnabled(struct SiS_Private *SiS_Pr)
{
   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
   if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
      if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
   }
   return false;
}
#endif

#ifdef CONFIG_FB_SIS_315
static bool
SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
{
   if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
   return false;
}
#endif

#ifdef CONFIG_FB_SIS_315
static bool
SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
{
   if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
   }
   return false;
}
#endif

#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
{
   unsigned short flag;

   if(SiS_Pr->ChipType == SIS_650) {
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
      /* Check for revision != A0 only */
      if((flag == 0xe0) || (flag == 0xc0) ||
         (flag == 0xb0) || (flag == 0x90)) return false;
   } else if(SiS_Pr->ChipType >= SIS_661) return false;
   return true;
}
#endif

#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
{
   if(SiS_Pr->ChipType >= SIS_315H) {
      /* YPrPb = 0x08 */
      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
   }
   return false;
}
#endif

#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsChScart(struct SiS_Private *SiS_Pr)
{
   if(SiS_Pr->ChipType >= SIS_315H) {
      /* Scart = 0x04 */
      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
   }
   return false;
}
#endif

#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
{
   unsigned short flag;

   if(SiS_Pr->ChipType >= SIS_315H) {
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
      if(flag & SetCRT2ToTV)        return true;
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
      if(flag & EnableCHYPbPr)      return true;  /* = YPrPb = 0x08 */
      if(flag & EnableCHScart)      return true;  /* = Scart = 0x04 - TW */
   } else {
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
      if(flag & SetCRT2ToTV)        return true;
   }
   return false;
}
#endif

#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
{
   unsigned short flag;

   if(SiS_Pr->ChipType >= SIS_315H) {
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
      if(flag & SetCRT2ToLCD) return true;
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
      if(flag & SetToLCDA)    return true;
   } else {
      flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
      if(flag & SetCRT2ToLCD) return true;
   }
   return false;
}
#endif

static bool
SiS_HaveBridge(struct SiS_Private *SiS_Pr)
{
   unsigned short flag;

   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
      return true;
   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
      flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
      if((flag == 1) || (flag == 2)) return true;
   }
   return false;
}

static bool
SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
{
   unsigned short flag;

   if(SiS_HaveBridge(SiS_Pr)) {
      flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
      if(SiS_Pr->ChipType < SIS_315H) {
	flag &= 0xa0;
	if((flag == 0x80) || (flag == 0x20)) return true;
      } else {
	flag &= 0x50;
	if((flag == 0x40) || (flag == 0x10)) return true;
      }
   }
   return false;
}

static bool
SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
{
   unsigned short flag1;

   flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
   if(flag1 & (SetInSlaveMode >> 8)) return true;
   return false;
}

/*********************************************/
/*       GET VIDEO BRIDGE CONFIG INFO        */
/*********************************************/

/* Setup general purpose IO for Chrontel communication */
#ifdef CONFIG_FB_SIS_300
void
SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
{
   unsigned int   acpibase;
   unsigned short temp;

   if(!(SiS_Pr->SiS_ChSW)) return;

   acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
   acpibase &= 0xFFFF;
   if(!acpibase) return;
   temp = SiS_GetRegShort((acpibase + 0x3c));	/* ACPI register 0x3c: GP Event 1 I/O mode select */
   temp &= 0xFEFF;
   SiS_SetRegShort((acpibase + 0x3c), temp);
   temp = SiS_GetRegShort((acpibase + 0x3c));
   temp = SiS_GetRegShort((acpibase + 0x3a));	/* ACPI register 0x3a: GP Pin Level (low/high) */
   temp &= 0xFEFF;
   if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100;
   SiS_SetRegShort((acpibase + 0x3a), temp);
   temp = SiS_GetRegShort((acpibase + 0x3a));
}
#endif

void
SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
		unsigned short ModeIdIndex, int checkcrt2mode)
{
   unsigned short tempax, tempbx, temp;
   unsigned short modeflag, resinfo = 0;

   SiS_Pr->SiS_SetFlag = 0;

   modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);

   SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask;

   if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }

   tempbx = 0;

   if(SiS_HaveBridge(SiS_Pr)) {

	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
	tempbx |= temp;
	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
	tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
	tempbx |= tempax;

#ifdef CONFIG_FB_SIS_315
	if(SiS_Pr->ChipType >= SIS_315H) {
	   if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
	      if(ModeNo == 0x03) {
		 /* Mode 0x03 is never in driver mode */
		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
	      }
	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
		 /* Reset LCDA setting if not driver mode */
		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
	      }
	      if(IS_SIS650) {
		 if(SiS_Pr->SiS_UseLCDA) {
		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
			  SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
		       }
		    }
		 }
	      }
	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
		 tempbx |= SetCRT2ToLCDA;
	      }
	   }

	   if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */
	      tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
	      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) {
		 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0;
		 if(temp == 0x60) tempbx |= SetCRT2ToHiVision;
		 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
		    tempbx |= SetCRT2ToYPbPr525750;
		 }
	      }
	   }

	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
	      if(temp & SetToLCDA) {
		 tempbx |= SetCRT2ToLCDA;
	      }
	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
		 if(temp & EnableCHYPbPr) {
		    tempbx |= SetCRT2ToCHYPbPr;
		 }
	      }
	   }
	}

#endif  /* CONFIG_FB_SIS_315 */

        if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
	   tempbx &= ~(SetCRT2ToRAMDAC);
	}

	if(SiS_Pr->SiS_VBType & VB_SISVB) {
	   temp = SetCRT2ToSVIDEO   |
		  SetCRT2ToAVIDEO   |
		  SetCRT2ToSCART    |
		  SetCRT2ToLCDA     |
		  SetCRT2ToLCD      |
		  SetCRT2ToRAMDAC   |
		  SetCRT2ToHiVision |
		  SetCRT2ToYPbPr525750;
	} else {
	   if(SiS_Pr->ChipType >= SIS_315H) {
	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
		 temp = SetCRT2ToAVIDEO |
		        SetCRT2ToSVIDEO |
		        SetCRT2ToSCART  |
		        SetCRT2ToLCDA   |
		        SetCRT2ToLCD    |
		        SetCRT2ToCHYPbPr;
	      } else {
		 temp = SetCRT2ToLCDA   |
		        SetCRT2ToLCD;
	      }
	   } else {
	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
		 temp = SetCRT2ToTV | SetCRT2ToLCD;
	      } else {
		 temp = SetCRT2ToLCD;
	      }
	   }
	}

	if(!(tempbx & temp)) {
	   tempax = DisableCRT2Display;
	   tempbx = 0;
	}

	if(SiS_Pr->SiS_VBType & VB_SISVB) {

	   unsigned short clearmask = ( DriverMode |
				DisableCRT2Display |
				LoadDACFlag 	   |
				SetNotSimuMode 	   |
				SetInSlaveMode 	   |
				SetPALTV 	   |
				SwitchCRT2	   |
				SetSimuScanMode );

	   if(tempbx & SetCRT2ToLCDA)        tempbx &= (clearmask | SetCRT2ToLCDA);
	   if(tempbx & SetCRT2ToRAMDAC)      tempbx &= (clearmask | SetCRT2ToRAMDAC);
	   if(tempbx & SetCRT2ToLCD)         tempbx &= (clearmask | SetCRT2ToLCD);
	   if(tempbx & SetCRT2ToSCART)       tempbx &= (clearmask | SetCRT2ToSCART);
	   if(tempbx & SetCRT2ToHiVision)    tempbx &= (clearmask | SetCRT2ToHiVision);
	   if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);

	} else {

	   if(SiS_Pr->ChipType >= SIS_315H) {
	      if(tempbx & SetCRT2ToLCDA) {
		 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
	      }
	   }
	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
	      if(tempbx & SetCRT2ToTV) {
		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
	      }
	   }
	   if(tempbx & SetCRT2ToLCD) {
	      tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
	   }
	   if(SiS_Pr->ChipType >= SIS_315H) {
	      if(tempbx & SetCRT2ToLCDA) {
	         tempbx |= SetCRT2ToLCD;
	      }
	   }

	}

	if(tempax & DisableCRT2Display) {
	   if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
	      tempbx = SetSimuScanMode | DisableCRT2Display;
	   }
	}

	if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;

	/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
	       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
	      modeflag &= (~CRT2Mode);
	   }
	}

	if(!(tempbx & SetSimuScanMode)) {
	   if(tempbx & SwitchCRT2) {
	      if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
		 if(resinfo != SIS_RI_1600x1200) {
		    tempbx |= SetSimuScanMode;
		 }
              }
	   } else {
	      if(SiS_BridgeIsEnabled(SiS_Pr)) {
		 if(!(tempbx & DriverMode)) {
		    if(SiS_BridgeInSlavemode(SiS_Pr)) {
		       tempbx |= SetSimuScanMode;
		    }
		 }
	      }
	   }
	}

	if(!(tempbx & DisableCRT2Display)) {
	   if(tempbx & DriverMode) {
	      if(tempbx & SetSimuScanMode) {
		 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
		    if(resinfo != SIS_RI_1600x1200) {
		       tempbx |= SetInSlaveMode;
		    }
		 }
	      }
	   } else {
	      tempbx |= SetInSlaveMode;
	   }
	}

   }

   SiS_Pr->SiS_VBInfo = tempbx;

#ifdef CONFIG_FB_SIS_300
   if(SiS_Pr->ChipType == SIS_630) {
      SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
   }
#endif

#if 0
   printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
#endif
}

/*********************************************/
/*           DETERMINE YPbPr MODE            */
/*********************************************/

void
SiS_SetYPbPr(struct SiS_Private *SiS_Pr)
{

   unsigned char temp;

   /* Note: This variable is only used on 30xLV systems.
    * CR38 has a different meaning on LVDS/CH7019 systems.
    * On 661 and later, these bits moved to CR35.
    *
    * On 301, 301B, only HiVision 1080i is supported.
    * On 30xLV, 301C, only YPbPr 1080i is supported.
    */

   SiS_Pr->SiS_YPbPr = 0;
   if(SiS_Pr->ChipType >= SIS_661) return;

   if(SiS_Pr->SiS_VBType) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
	 SiS_Pr->SiS_YPbPr = YPbPrHiVision;
      }
   }

   if(SiS_Pr->ChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
	 if(temp & 0x08) {
	    switch((temp >> 4)) {
	    case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i;     break;
	    case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p;     break;
	    case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p;     break;
	    case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break;
	    }
	 }
      }
   }

}

/*********************************************/
/*           DETERMINE TVMode flag           */
/*********************************************/

void
SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
   unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned short temp, temp1, resinfo = 0, romindex = 0;
   unsigned char  OutputSelect = *SiS_Pr->pSiS_OutputSelect;

   SiS_Pr->SiS_TVMode = 0;

   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
   if(SiS_Pr->UseCustomMode) return;

   if(ModeNo > 0x13) {
      resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }

   if(SiS_Pr->ChipType < SIS_661) {

      if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL;

      if(SiS_Pr->SiS_VBType & VB_SISVB) {
	 temp = 0;
	 if((SiS_Pr->ChipType == SIS_630) ||
	    (SiS_Pr->ChipType == SIS_730)) {
	    temp = 0x35;
	    romindex = 0xfe;
	 } else if(SiS_Pr->ChipType >= SIS_315H) {
	    temp = 0x38;
	    if(SiS_Pr->ChipType < XGI_20) {
	       romindex = 0xf3;
	       if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b;
	    }
	 }
	 if(temp) {
	    if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
	       OutputSelect = ROMAddr[romindex];
	       if(!(OutputSelect & EnablePALMN)) {
		  SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
	       }
	    }
	    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
	       if(temp1 & EnablePALM) {		/* 0x40 */
		  SiS_Pr->SiS_TVMode |= TVSetPALM;
		  SiS_Pr->SiS_TVMode &= ~TVSetPAL;
	       } else if(temp1 & EnablePALN) {	/* 0x80 */
		  SiS_Pr->SiS_TVMode |= TVSetPALN;
	       }
	    } else {
	       if(temp1 & EnableNTSCJ) {	/* 0x40 */
		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
	       }
	    }
	 }
	 /* Translate HiVision/YPbPr to our new flags */
	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
	    if(SiS_Pr->SiS_YPbPr == YPbPr750p)          SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
	    else if(SiS_Pr->SiS_YPbPr == YPbPr525p)     SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
	    else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision;
	    else				        SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
	    if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) {
	       SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision;
	       SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750;
	    } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
	       SiS_Pr->SiS_TVMode |= TVSetPAL;
	    }
	 }
      } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
	 if(SiS_Pr->SiS_CHOverScan) {
	    if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
	       if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
	       }
	    } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	       temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
	       if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
		  SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
	       }
	    }
	    if(SiS_Pr->SiS_CHSOverScan) {
	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
	    }
	 }
	 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
	    if(SiS_Pr->SiS_TVMode & TVSetPAL) {
	       if(temp & EnablePALM)      SiS_Pr->SiS_TVMode |= TVSetPALM;
	       else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN;
	    } else {
	       if(temp & EnableNTSCJ) {
		  SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
	       }
	    }
	 }
      }

   } else {  /* 661 and later */

      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
      if(temp1 & 0x01) {
	 SiS_Pr->SiS_TVMode |= TVSetPAL;
	 if(temp1 & 0x08) {
	    SiS_Pr->SiS_TVMode |= TVSetPALN;
	 } else if(temp1 & 0x04) {
	    if(SiS_Pr->SiS_VBType & VB_SISVB) {
	       SiS_Pr->SiS_TVMode &= ~TVSetPAL;
	    }
	    SiS_Pr->SiS_TVMode |= TVSetPALM;
	 }
      } else {
	 if(temp1 & 0x02) {
	    SiS_Pr->SiS_TVMode |= TVSetNTSCJ;
	 }
      }
      if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	 if(SiS_Pr->SiS_CHOverScan) {
	    if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) {
	       SiS_Pr->SiS_TVMode |= TVSetCHOverScan;
	    }
	 }
      }
      if(SiS_Pr->SiS_VBType & VB_SISVB) {
	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
	    temp1 &= 0xe0;
	    if(temp1 == 0x00)      SiS_Pr->SiS_TVMode |= TVSetYPbPr525i;
	    else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p;
	    else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p;
	 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
	    SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
	 }
	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
	    if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
	       SiS_Pr->SiS_TVMode |= TVAspect169;
	    } else {
	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
	       if(temp1 & 0x02) {
		  if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
		     SiS_Pr->SiS_TVMode |= TVAspect169;
		  } else {
		     SiS_Pr->SiS_TVMode |= TVAspect43LB;
		  }
	       } else {
		  SiS_Pr->SiS_TVMode |= TVAspect43;
	       }
	    }
	 }
      }
   }

   if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL;

   if(SiS_Pr->SiS_VBType & VB_SISVB) {

      if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
	 SiS_Pr->SiS_TVMode |= TVSetPAL;
	 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ);
      } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
	 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) {
	    SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN);
	 }
      }

      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
	 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
	    SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;
	 }
      }

      if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
	 if(resinfo == SIS_RI_1024x768) {
	    if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
	       SiS_Pr->SiS_TVMode |= TVSet525p1024;
	    } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) {
	       SiS_Pr->SiS_TVMode |= TVSetNTSC1024;
	    }
	 }
      }

      SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO;
      if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) &&
	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
      } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
	 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
      } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) {
	 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
	    SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO;
	 }
      }

   }

   SiS_Pr->SiS_VBInfo &= ~SetPALTV;
}

/*********************************************/
/*               GET LCD INFO                */
/*********************************************/

static unsigned short
SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
{
   unsigned short temp = SiS_Pr->SiS_LCDResInfo;
   /* Translate my LCDResInfo to BIOS value */
   switch(temp) {
   case Panel_1280x768_2: temp = Panel_1280x768;    break;
   case Panel_1280x800_2: temp = Panel_1280x800;    break;
   case Panel_1280x854:   temp = Panel661_1280x854; break;
   }
   return temp;
}

static void
SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
{
#ifdef CONFIG_FB_SIS_315
   unsigned char  *ROMAddr;
   unsigned short temp;

   if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
      if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
	 SiS_Pr->SiS_NeedRomModeData = true;
	 SiS_Pr->PanelHT  = temp;
      }
      if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
	 SiS_Pr->SiS_NeedRomModeData = true;
	 SiS_Pr->PanelVT  = temp;
      }
      SiS_Pr->PanelHRS = SISGETROMW(10);
      SiS_Pr->PanelHRE = SISGETROMW(12);
      SiS_Pr->PanelVRS = SISGETROMW(14);
      SiS_Pr->PanelVRE = SISGETROMW(16);
      SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]);
      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
      SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
	 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];

   }
#endif
}

static void
SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo,
			const unsigned char *nonscalingmodes)
{
   int i = 0;
   while(nonscalingmodes[i] != 0xff) {
      if(nonscalingmodes[i++] == resinfo) {
	 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ||
	    (SiS_Pr->UsePanelScaler == -1)) {
	    SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
	 }
	 break;
      }
   }
}

void
SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
  unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
  bool panelcanscale = false;
#ifdef CONFIG_FB_SIS_300
  unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
  static const unsigned char SiS300SeriesLCDRes[] =
          { 0,  1,  2,  3,  7,  4,  5,  8,
	    0,  0, 10,  0,  0,  0,  0, 15 };
#endif
#ifdef CONFIG_FB_SIS_315
  unsigned char   *myptr = NULL;
#endif

  SiS_Pr->SiS_LCDResInfo  = 0;
  SiS_Pr->SiS_LCDTypeInfo = 0;
  SiS_Pr->SiS_LCDInfo     = 0;
  SiS_Pr->PanelHRS        = 999; /* HSync start */
  SiS_Pr->PanelHRE        = 999; /* HSync end */
  SiS_Pr->PanelVRS        = 999; /* VSync start */
  SiS_Pr->PanelVRE        = 999; /* VSync end */
  SiS_Pr->SiS_NeedRomModeData = false;

  /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
  SiS_Pr->Alternate1600x1200 = false;

  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;

  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);

  if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) {
     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
     modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal;
     modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal;
  }

  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);

  /* For broken BIOSes: Assume 1024x768 */
  if(temp == 0) temp = 0x02;

  if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
     SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
  } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) {
     SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
  } else {
     SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
  }
  temp &= 0x0f;
#ifdef CONFIG_FB_SIS_300
  if(SiS_Pr->ChipType < SIS_315H) {
     /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
     if(SiS_Pr->SiS_VBType & VB_SIS301) {
        if(temp < 0x0f) temp &= 0x07;
     }
     /* Translate 300 series LCDRes to 315 series for unified usage */
     temp = SiS300SeriesLCDRes[temp];
  }
#endif

  /* Translate to our internal types */
#ifdef CONFIG_FB_SIS_315
  if(SiS_Pr->ChipType == SIS_550) {
     if     (temp == Panel310_1152x768)  temp = Panel_320x240_2; /* Verified working */
     else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
     else if(temp == Panel310_320x240_3) temp = Panel_320x240_3;
  } else if(SiS_Pr->ChipType >= SIS_661) {
     if(temp == Panel661_1280x854)       temp = Panel_1280x854;
  }
#endif

  if(SiS_Pr->SiS_VBType & VB_SISLVDS) {		/* SiS LVDS */
     if(temp == Panel310_1280x768) {
        temp = Panel_1280x768_2;
     }
     if(SiS_Pr->SiS_ROMNew) {
	if(temp == Panel661_1280x800) {
	   temp = Panel_1280x800_2;
	}
     }
  }

  SiS_Pr->SiS_LCDResInfo = temp;

#ifdef CONFIG_FB_SIS_300
  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
     if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
	SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
	SiS_Pr->SiS_LCDResInfo = Panel_848x480;
     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) {
	SiS_Pr->SiS_LCDResInfo = Panel_856x480;
     }
  }
#endif

  if(SiS_Pr->SiS_VBType & VB_SISVB) {
     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
  } else {
     if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
  }

  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
  SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
  /* Need temp below! */

  /* These must/can't scale no matter what */
  switch(SiS_Pr->SiS_LCDResInfo) {
  case Panel_320x240_1:
  case Panel_320x240_2:
  case Panel_320x240_3:
  case Panel_1280x960:
      SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
      break;
  case Panel_640x480:
      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
  }

  panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);

  if(!SiS_Pr->UsePanelScaler)          SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;

  /* Dual link, Pass 1:1 BIOS default, etc. */
#ifdef CONFIG_FB_SIS_315
  if(SiS_Pr->ChipType >= SIS_661) {
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
	if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
     }
     if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
	if(SiS_Pr->SiS_ROMNew) {
	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
	} else if((myptr = GetLCDStructPtr661(SiS_Pr))) {
	   if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
	}
     }
  } else if(SiS_Pr->ChipType >= SIS_315H) {
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
	if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
     }
     if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
	SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
	if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
	   if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
	}
     } else if(!(SiS_Pr->SiS_ROMNew)) {
	if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) {
	   if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
	      (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
	   }
	   if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
	      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
	      (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
	      (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
	      SiS_Pr->SiS_LCDInfo |= LCDDualLink;
	   }
	}
     }
  }
#endif

  /* Pass 1:1 */
  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
     /* Always center screen on LVDS (if scaling is disabled) */
     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
  } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
     if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	/* Always center screen on SiS LVDS (if scaling is disabled) */
	SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
     } else {
	/* By default, pass 1:1 on SiS TMDS (if scaling is supported) */
	if(panelcanscale)             SiS_Pr->SiS_LCDInfo |= LCDPass11;
	if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
     }
  }

  SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
  SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;

  switch(SiS_Pr->SiS_LCDResInfo) {
     case Panel_320x240_1:
     case Panel_320x240_2:
     case Panel_320x240_3:  SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
			    SiS_Pr->PanelVRS  =   24; SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
			    break;
     case Panel_640x480:    SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480;
						      SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx300 = VCLK28;
			    SiS_Pr->PanelVCLKIdx315 = VCLK28;
			    break;
     case Panel_800x600:    SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600;
     			    SiS_Pr->PanelHT   = 1056; SiS_Pr->PanelVT   =  628;
			    SiS_Pr->PanelHRS  =   40; SiS_Pr->PanelHRE  =  128;
			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    4;
			    SiS_Pr->PanelVCLKIdx300 = VCLK40;
			    SiS_Pr->PanelVCLKIdx315 = VCLK40;
			    break;
     case Panel_1024x600:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600;
			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  800;
			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
			    SiS_Pr->PanelVRS  =    2 /* 88 */ ; SiS_Pr->PanelVRE  =    6;
			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
			    break;
     case Panel_1024x768:   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
			    if(SiS_Pr->ChipType < SIS_315H) {
			       SiS_Pr->PanelHRS = 23;
						      SiS_Pr->PanelVRE  =    5;
			    }
			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1152x768:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768;
			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
			    SiS_Pr->PanelHRS  =   24; SiS_Pr->PanelHRE  =  136;
			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
			    if(SiS_Pr->ChipType < SIS_315H) {
			       SiS_Pr->PanelHRS = 23;
						      SiS_Pr->PanelVRE  =    5;
			    }
			    SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
			    SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
			    break;
     case Panel_1152x864:   SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864;
			    break;
     case Panel_1280x720:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  720;
			    SiS_Pr->PanelHT   = 1650; SiS_Pr->PanelVT   =  750;
			    SiS_Pr->PanelHRS  =  110; SiS_Pr->PanelHRE  =   40;
			    SiS_Pr->PanelVRS  =    5; SiS_Pr->PanelVRE  =    5;
			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
			    /* Data above for TMDS (projector); get from BIOS for LVDS */
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1280x768:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
			    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
			       SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  806;
			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */
			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
			    } else {
			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
			    }
			    break;
     case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768;
			    SiS_Pr->PanelHT   = 1660; SiS_Pr->PanelVT   =  806;
			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1280x800:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
			    SiS_Pr->PanelHT   = 1408; SiS_Pr->PanelVT   =  816;
			    SiS_Pr->PanelHRS   =  21; SiS_Pr->PanelHRE  =   24;
			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  800;
			    SiS_Pr->PanelHT   = 1552; SiS_Pr->PanelVT   =  812;
			    SiS_Pr->PanelHRS   =  48; SiS_Pr->PanelHRE  =  112;
			    SiS_Pr->PanelVRS   =   4; SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1280x854:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  854;
			    SiS_Pr->PanelHT   = 1664; SiS_Pr->PanelVT   =  861;
			    SiS_Pr->PanelHRS   =  16; SiS_Pr->PanelHRE  =  112;
			    SiS_Pr->PanelVRS   =   1; SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1280x960:   SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960;
			    SiS_Pr->PanelHT   = 1800; SiS_Pr->PanelVT   = 1000;
			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
			    SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
			    if(resinfo == SIS_RI_1280x1024) {
			       SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
			       SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
			    }
			    break;
     case Panel_1280x1024:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1400x1050:  SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
			    SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1600x1200:  SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
			    SiS_Pr->PanelHT   = 2160; SiS_Pr->PanelVT   = 1250;
			    SiS_Pr->PanelHRS  =   64; SiS_Pr->PanelHRE  =  192;
			    SiS_Pr->PanelVRS  =    1; SiS_Pr->PanelVRE  =    3;
			    SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
			    if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) {
			       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
				  SiS_Pr->PanelHT  = 1760; SiS_Pr->PanelVT  = 1235;
				  SiS_Pr->PanelHRS =   48; SiS_Pr->PanelHRE =   32;
				  SiS_Pr->PanelVRS =    2; SiS_Pr->PanelVRE =    4;
				  SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
				  SiS_Pr->Alternate1600x1200 = true;
			       }
			    } else if(SiS_Pr->SiS_IF_DEF_LVDS) {
			       SiS_Pr->PanelHT  = 2048; SiS_Pr->PanelVT  = 1320;
			       SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999;
			       SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999;
			    }
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_1680x1050:  SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
			    SiS_Pr->PanelHT   = 1900; SiS_Pr->PanelVT   = 1066;
			    SiS_Pr->PanelHRS  =   26; SiS_Pr->PanelHRE  =   76;
			    SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
			    SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
			    SiS_GetLCDInfoBIOS(SiS_Pr);
			    break;
     case Panel_Barco1366:  SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
			    SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   = 1066;
			    break;
     case Panel_848x480:    SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480;
			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
			    break;
     case Panel_856x480:    SiS_Pr->PanelXRes =  856; SiS_Pr->PanelYRes =  480;
			    SiS_Pr->PanelHT   = 1088; SiS_Pr->PanelVT   =  525;
			    break;
     case Panel_Custom:     SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
			    SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
			    SiS_Pr->PanelHT   = SiS_Pr->CHTotal;
			    SiS_Pr->PanelVT   = SiS_Pr->CVTotal;
			    if(SiS_Pr->CP_PreferredIndex != -1) {
			       SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelHT   = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelVT   = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelHRS  = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelHRE  = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelVRS  = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelVRE  = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
			       SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
			       SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
			       SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
			       SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
			       if(SiS_Pr->CP_PrefClock) {
				  int idx;
				  SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
				  SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300;
				  if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300;
				  else				   idx = VCLK_CUSTOM_315;
				  SiS_Pr->SiS_VCLKData[idx].CLOCK =
				     SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock;
				  SiS_Pr->SiS_VCLKData[idx].SR2B =
				     SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B;
				  SiS_Pr->SiS_VCLKData[idx].SR2C =
				     SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C;
			       }
			    }
			    break;
     default:		    SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768;
			    SiS_Pr->PanelHT   = 1344; SiS_Pr->PanelVT   =  806;
			    break;
  }

  /* Special cases */
  if( (SiS_Pr->SiS_IF_DEF_FSTN)              ||
      (SiS_Pr->SiS_IF_DEF_DSTN)              ||
      (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
     SiS_Pr->PanelHRS = 999;
     SiS_Pr->PanelHRE = 999;
  }

  if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
      (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
      (SiS_Pr->SiS_CustomT == CUT_PANEL848)  ||
      (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
     SiS_Pr->PanelVRS = 999;
     SiS_Pr->PanelVRE = 999;
  }

  /* DontExpand overrule */
  if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {

     if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) {
	/* No scaling for this mode on any panel (LCD=CRT2)*/
	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
     }

     switch(SiS_Pr->SiS_LCDResInfo) {

     case Panel_Custom:
     case Panel_1152x864:
     case Panel_1280x768:	/* TMDS only */
	SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
	break;

     case Panel_800x600: {
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	break;
     }
     case Panel_1024x768: {
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	break;
     }
     case Panel_1280x720: {
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	if(SiS_Pr->PanelHT == 1650) {
	   SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
	}
	break;
     }
     case Panel_1280x768_2: {  /* LVDS only */
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   SIS_RI_1152x768,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	switch(resinfo) {
	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
			       }
			       break;
	}
	break;
     }
     case Panel_1280x800: {  	/* SiS TMDS special (Averatec 6200 series) */
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	break;
     }
     case Panel_1280x800_2:  { 	/* SiS LVDS */
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   SIS_RI_1152x768,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	switch(resinfo) {
	case SIS_RI_1280x720:
	case SIS_RI_1280x768:  if(SiS_Pr->UsePanelScaler == -1) {
				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
			       }
			       break;
	}
	break;
     }
     case Panel_1280x854: {  	/* SiS LVDS */
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   SIS_RI_1152x768,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	switch(resinfo) {
	case SIS_RI_1280x720:
	case SIS_RI_1280x768:
	case SIS_RI_1280x800:  if(SiS_Pr->UsePanelScaler == -1) {
				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
			       }
			       break;
	}
	break;
     }
     case Panel_1280x960: {
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
	   SIS_RI_1280x854,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	break;
     }
     case Panel_1280x1024: {
	static const unsigned char nonscalingmodes[] = {
	   SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	   SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	   SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
	   SIS_RI_1280x854,SIS_RI_1280x960,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	break;
     }
     case Panel_1400x1050: {
	static const unsigned char nonscalingmodes[] = {
	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854,
	     SIS_RI_1280x960,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	switch(resinfo) {
	case SIS_RI_1280x720:  if(SiS_Pr->UsePanelScaler == -1) {
				  SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
			       }
			       break;
	case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
			       break;
	}
	break;
     }
     case Panel_1600x1200: {
	static const unsigned char nonscalingmodes[] = {
	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800,
	     SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	break;
     }
     case Panel_1680x1050: {
	static const unsigned char nonscalingmodes[] = {
	     SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480,
	     SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600,
	     SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,
	     SIS_RI_1360x1024,0xff
	};
	SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes);
	break;
     }
     }
  }

#ifdef CONFIG_FB_SIS_300
  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
     if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
	SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg h/v sync, RGB24(D0 = 0) */
     }
  }

  if(SiS_Pr->ChipType < SIS_315H) {
     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
	if(SiS_Pr->SiS_UseROM) {
	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
	      if(!(ROMAddr[0x235] & 0x02)) {
		 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
	      }
	   }
	}
     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
	   SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
	}
     }
  }
#endif

  /* Special cases */

  if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) {
     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
  }

  if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
  }

  switch(SiS_Pr->SiS_LCDResInfo) {
  case Panel_640x480:
     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
     break;
  case Panel_1280x800:
     /* Don't pass 1:1 by default (TMDS special) */
     if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
     break;
  case Panel_1280x960:
     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
     break;
  case Panel_Custom:
     if((!SiS_Pr->CP_PrefClock) ||
        (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) {
        SiS_Pr->SiS_LCDInfo |= LCDPass11;
     }
     break;
  }

  if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) {
     SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
  }

  /* (In)validate LCDPass11 flag */
  if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
     SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
  }

  /* LVDS DDA */
  if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {

     if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
	   if(ModeNo == 0x12) {
	      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
		 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
	      }
	   } else if(ModeNo > 0x13) {
	      if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
		    if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
		       SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
		    }
		 }
	      }
	   }
	}
     }

     if(modeflag & HalfDCLK) {
	if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
	} else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
	   SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
	} else if(ModeNo > 0x13) {
	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
	      if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
	   } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
	      if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
	   }
	}
     }

  }

  /* VESA timing */
  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
     if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
     }
  } else {
     SiS_Pr->SiS_SetFlag |= LCDVESATiming;
  }

#if 0
  printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
#endif
}

/*********************************************/
/*                 GET VCLK                  */
/*********************************************/

unsigned short
SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
		unsigned short RefreshRateTableIndex)
{
  unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0;
  unsigned short resinfo, tempbx;
  const unsigned char *CHTVVCLKPtr = NULL;

  if(ModeNo <= 0x13) {
     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
     CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
     VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
     VCLKIndexGENCRT = VCLKIndexGEN;
  } else {
     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
     CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
     VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
     VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex,
		(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide);
  }

  if(SiS_Pr->SiS_VBType & VB_SISVB) {    /* 30x/B/LV */

     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {

	CRT2Index >>= 6;
	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      	/*  LCD */

	   if(SiS_Pr->ChipType < SIS_315H) {
	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
		 VCLKIndex = VCLKIndexGEN;
	      }
	   } else {
	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
	      if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
		 switch(resinfo) {
		 /* Correct those whose IndexGEN doesn't match VBVCLK array */
		 case SIS_RI_720x480:  VCLKIndex = VCLK_720x480;  break;
		 case SIS_RI_720x576:  VCLKIndex = VCLK_720x576;  break;
		 case SIS_RI_768x576:  VCLKIndex = VCLK_768x576;  break;
		 case SIS_RI_848x480:  VCLKIndex = VCLK_848x480;  break;
		 case SIS_RI_856x480:  VCLKIndex = VCLK_856x480;  break;
		 case SIS_RI_800x480:  VCLKIndex = VCLK_800x480;  break;
		 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
		 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
		 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break;
		 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
		 default:              VCLKIndex = VCLKIndexGEN;
		 }

		 if(ModeNo <= 0x13) {
		    if(SiS_Pr->ChipType <= SIS_315PRO) {
		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
		    } else {
		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
		    }
		 }
		 if(SiS_Pr->ChipType <= SIS_315PRO) {
		    if(VCLKIndex == 0) VCLKIndex = 0x41;
		    if(VCLKIndex == 1) VCLKIndex = 0x43;
		    if(VCLKIndex == 4) VCLKIndex = 0x44;
		 }
	      }
	   }

	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 	/*  TV */

	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
	      if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) 	   VCLKIndex = HiTVVCLKDIV2;
	      else                                  	   VCLKIndex = HiTVVCLK;
	      if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)     VCLKIndex = HiTVSimuVCLK;
	   } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)  VCLKIndex = YPbPr750pVCLK;
	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)    VCLKIndex = TVVCLKDIV2;
	   else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO)      VCLKIndex = TVVCLKDIV2;
	   else						   VCLKIndex = TVVCLK;

	   if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
	   else				   VCLKIndex += TVCLKBASE_315;

	} else {							/* VGA2 */

	   VCLKIndex = VCLKIndexGENCRT;
	   if(SiS_Pr->ChipType < SIS_315H) {
	      if(ModeNo > 0x13) {
		 if( (SiS_Pr->ChipType == SIS_630) &&
		     (SiS_Pr->ChipRevision >= 0x30)) {
		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
		 }
		 /* Better VGA2 clock for 1280x1024@75 */
		 if(VCLKIndex == 0x17) VCLKIndex = 0x45;
	      }
	   }
	}

     } else {   /* If not programming CRT2 */

	VCLKIndex = VCLKIndexGENCRT;
	if(SiS_Pr->ChipType < SIS_315H) {
	   if(ModeNo > 0x13) {
	      if( (SiS_Pr->ChipType != SIS_630) &&
		  (SiS_Pr->ChipType != SIS_300) ) {
		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
	      }
	   }
	}
     }

  } else {       /*   LVDS  */

     VCLKIndex = CRT2Index;

     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {

	if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {

	   VCLKIndex &= 0x1f;
	   tempbx = 0;
	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
	   if(SiS_Pr->SiS_TVMode & TVSetPAL) {
	      tempbx += 2;
	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
	      }
	      if(SiS_Pr->SiS_TVMode & TVSetPALM) {
		 tempbx = 4;
		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
	      } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
		 tempbx = 6;
		 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
	      }
	   }
	   switch(tempbx) {
	     case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
	     case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
	     case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
	     case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
	     case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
	     case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
	     case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
	   }
	   VCLKIndex = CHTVVCLKPtr[VCLKIndex];

	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {

	   if(SiS_Pr->ChipType < SIS_315H) {
	      VCLKIndex = SiS_Pr->PanelVCLKIdx300;
	   } else {
	      VCLKIndex = SiS_Pr->PanelVCLKIdx315;
	   }

#ifdef CONFIG_FB_SIS_300
	   /* Special Timing: Barco iQ Pro R series */
	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;

	   /* Special Timing: 848x480 and 856x480 parallel lvds panels */
	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
	      if(SiS_Pr->ChipType < SIS_315H) {
		 VCLKIndex = VCLK34_300;
		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
	      } else {
		 VCLKIndex = VCLK34_315;
		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
	      }
	   }
#endif

	} else {

	   VCLKIndex = VCLKIndexGENCRT;
	   if(SiS_Pr->ChipType < SIS_315H) {
	      if(ModeNo > 0x13) {
		 if( (SiS_Pr->ChipType == SIS_630) &&
		     (SiS_Pr->ChipRevision >= 0x30) ) {
		    if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
		 }
	      }
	   }
	}

     } else {  /* if not programming CRT2 */

	VCLKIndex = VCLKIndexGENCRT;
	if(SiS_Pr->ChipType < SIS_315H) {
	   if(ModeNo > 0x13) {
	      if( (SiS_Pr->ChipType != SIS_630) &&
		  (SiS_Pr->ChipType != SIS_300) ) {
		 if(VCLKIndex == 0x1b) VCLKIndex = 0x48;
	      }
#if 0
	      if(SiS_Pr->ChipType == SIS_730) {
		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
	      }
#endif
	   }
        }

     }

  }

  return VCLKIndex;
}

/*********************************************/
/*        SET CRT2 MODE TYPE REGISTERS       */
/*********************************************/

static void
SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
  unsigned short i, j, modeflag, tempah=0;
  short tempcl;
#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
  unsigned short tempbl;
#endif
#ifdef CONFIG_FB_SIS_315
  unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
  unsigned short tempah2, tempbl2;
#endif

  modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);

  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {

     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40);
     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);

  } else {

     for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
     if(SiS_Pr->ChipType >= SIS_315H) {
        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
     }

     tempcl = SiS_Pr->SiS_ModeType;

     if(SiS_Pr->ChipType < SIS_315H) {

#ifdef CONFIG_FB_SIS_300    /* ---- 300 series ---- */

	/* For 301BDH: (with LCD via LVDS) */
	if(SiS_Pr->SiS_VBType & VB_NoLCD) {
	   tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
	   tempbl &= 0xef;
	   tempbl |= 0x02;
	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
	      tempbl |= 0x10;
	      tempbl &= 0xfd;
	   }
	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
	}

	if(ModeNo > 0x13) {
	   tempcl -= ModeVGA;
	   if(tempcl >= 0) {
	      tempah = ((0x10 >> tempcl) | 0x80);
	   }
	} else tempah = 0x80;

	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;

#endif  /* CONFIG_FB_SIS_300 */

     } else {

#ifdef CONFIG_FB_SIS_315    /* ------- 315/330 series ------ */

	if(ModeNo > 0x13) {
	   tempcl -= ModeVGA;
	   if(tempcl >= 0) {
	      tempah = (0x08 >> tempcl);
	      if (tempah == 0) tempah = 1;
	      tempah |= 0x40;
	   }
	} else tempah = 0x40;

	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;

#endif  /* CONFIG_FB_SIS_315 */

     }

     if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;

     if(SiS_Pr->ChipType < SIS_315H) {
	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
     } else {
#ifdef CONFIG_FB_SIS_315
	if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
	} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
	   if(IS_SIS740) {
	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
	   } else {
	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
	   }
	}
#endif
     }

     if(SiS_Pr->SiS_VBType & VB_SISVB) {

	tempah = 0x01;
	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
	   tempah |= 0x02;
	}
	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
	   tempah ^= 0x05;
	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
	      tempah ^= 0x01;
	   }
	}

	if(SiS_Pr->ChipType < SIS_315H) {

	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;

	   tempah = (tempah << 5) & 0xFF;
	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
	   tempah = (tempah >> 5) & 0xFF;

	} else {

	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0x08;
	   else if(!(SiS_IsDualEdge(SiS_Pr)))           tempah |= 0x08;
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah);
	   tempah &= ~0x08;

	}

	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
	   tempah |= 0x10;
	}

	tempah |= 0x80;
	if(SiS_Pr->SiS_VBType & VB_SIS301) {
	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80;
	}

	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
	   if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) {
	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
		 tempah |= 0x20;
	      }
	   }
	}

	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);

	tempah = 0x80;
	if(SiS_Pr->SiS_VBType & VB_SIS301) {
	   if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0;
	}

	if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40;

	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
	   if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) {
	      tempah |= 0x40;
	   }
	}

	SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);

     } else {  /* LVDS */

	if(SiS_Pr->ChipType >= SIS_315H) {

#ifdef CONFIG_FB_SIS_315
	   /* LVDS can only be slave in 8bpp modes */
	   tempah = 0x80;
	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
	         tempah |= 0x02;
	      }
	   }

	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))  tempah |= 0x02;

	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)        tempah ^= 0x01;

	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1;

	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
#endif

	} else {

#ifdef CONFIG_FB_SIS_300
	   tempah = 0;
	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
	      tempah |= 0x02;
	   }
	   tempah <<= 5;

	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0;

	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
#endif

	}

     }

  }  /* LCDA */

  if(SiS_Pr->SiS_VBType & VB_SISVB) {

     if(SiS_Pr->ChipType >= SIS_315H) {

#ifdef CONFIG_FB_SIS_315
	/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */

	/* The following is nearly unpreditable and varies from machine
	 * to machine. Especially the 301DH seems to be a real trouble
	 * maker. Some BIOSes simply set the registers (like in the
	 * NoLCD-if-statements here), some set them according to the
	 * LCDA stuff. It is very likely that some machines are not
	 * treated correctly in the following, very case-orientated
	 * code. What do I do then...?
	 */

	/* 740 variants match for 30xB, 301B-DH, 30xLV */

	if(!(IS_SIS740)) {
	   tempah = 0x04;						   /* For all bridges */
	   tempbl = 0xfb;
	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
	      tempah = 0x00;
	      if(SiS_IsDualEdge(SiS_Pr)) {
	         tempbl = 0xff;
	      }
	   }
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
	}

	/* The following two are responsible for eventually wrong colors
	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
	 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version
	 * in a 650 box (Jake). What is the criteria?
	 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same
	 * treatment like the 651+301B-DH(b0) case. Seems more to be the
	 * chipset than the bridge revision.
	 */

	if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
	   tempah = 0x30;
	   tempbl = 0xc0;
	   if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
	      ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
	      tempah = 0x00;
	      tempbl = 0x00;
	   }
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah);
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl);
	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
	   /* Fixes "TV-blue-bug" on 315+301 */
	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf);	/* For 301   */
	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
	} else if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);	/* For 30xLV */
	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0);
	} else if(SiS_Pr->SiS_VBType & VB_NoLCD) {		/* For 301B-DH */
	   tempah = 0x30; tempah2 = 0xc0;
	   tempbl = 0xcf; tempbl2 = 0x3f;
	   if(SiS_Pr->SiS_TVBlue == 0) {
	         tempah = tempah2 = 0x00;
	   } else if(SiS_Pr->SiS_TVBlue == -1) {
	      /* Set on 651/M650, clear on 315/650 */
	      if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ {
	         tempah = tempah2 = 0x00;
	      }
	   }
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
	} else {
	   tempah = 0x30; tempah2 = 0xc0;		       /* For 30xB, 301C */
	   tempbl = 0xcf; tempbl2 = 0x3f;
	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
	      tempah = tempah2 = 0x00;
	      if(SiS_IsDualEdge(SiS_Pr)) {
		 tempbl = tempbl2 = 0xff;
	      }
	   }
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2);
	}

	if(IS_SIS740) {
	   tempah = 0x80;
	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
	} else {
	   tempah = 0x00;
	   tempbl = 0x7f;
	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
	      tempbl = 0xff;
	      if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80;
	   }
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
	}

#endif /* CONFIG_FB_SIS_315 */

     } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {

#ifdef CONFIG_FB_SIS_300
	SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);

	if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
	   ((SiS_Pr->SiS_VBType & VB_NoLCD) &&
	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
	} else {
	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
	}
#endif

     }

     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80);
	if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) {
	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0);
        }
     }

  } else {  /* LVDS */

#ifdef CONFIG_FB_SIS_315
     if(SiS_Pr->ChipType >= SIS_315H) {

	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {

	   tempah = 0x04;
	   tempbl = 0xfb;
	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
	      tempah = 0x00;
	      if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff;
	   }
	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);

	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
	   }

	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);

	} else if(SiS_Pr->ChipType == SIS_550) {

	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30);

	}

     }
#endif

  }

}

/*********************************************/
/*            GET RESOLUTION DATA            */
/*********************************************/

unsigned short
SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
   if(ModeNo <= 0x13)
      return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
   else
      return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
}

static void
SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
   unsigned short xres, yres, modeflag=0, resindex;

   if(SiS_Pr->UseCustomMode) {
      xres = SiS_Pr->CHDisplay;
      if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1;
      SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
      /* DoubleScanMode-check done in CheckCalcCustomMode()! */
      SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
      return;
   }

   resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);

   if(ModeNo <= 0x13) {
      xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
      yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
   } else {
      xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
      yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
      modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }

   if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {

      if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
	 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
	    if(yres == 350) yres = 400;
	 }
	 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
	    if(ModeNo == 0x12) yres = 400;
	 }
      }

      if(modeflag & HalfDCLK)       xres <<= 1;
      if(modeflag & DoubleScanMode) yres <<= 1;

   }

   if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {

      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
	 switch(SiS_Pr->SiS_LCDResInfo) {
	   case Panel_1024x768:
	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
		 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
		    if(yres == 350) yres = 357;
		    if(yres == 400) yres = 420;
		    if(yres == 480) yres = 525;
		 }
	      }
	      break;
	   case Panel_1280x1024:
	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
		 /* BIOS bug - does this regardless of scaling */
		 if(yres == 400) yres = 405;
	      }
	      if(yres == 350) yres = 360;
	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
		 if(yres == 360) yres = 375;
	      }
	      break;
	   case Panel_1600x1200:
	      if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
		 if(yres == 1024) yres = 1056;
	      }
	      break;
	 }
      }

   } else {

      if(SiS_Pr->SiS_VBType & VB_SISVB) {
	 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
	    if(xres == 720) xres = 640;
	 }
      } else if(xres == 720) xres = 640;

      if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
	 yres = 400;
	 if(SiS_Pr->ChipType >= SIS_315H) {
	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
	 } else {
	    if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
	 }
	 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
      }

   }
   SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
   SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
}

/*********************************************/
/*           GET CRT2 TIMING DATA            */
/*********************************************/

static void
SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
	       unsigned short RefreshRateTableIndex, unsigned short *CRT2Index,
	       unsigned short *ResIndex)
{
  unsigned short tempbx=0, tempal=0, resinfo=0;

  if(ModeNo <= 0x13) {
     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
  } else {
     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
  }

  if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) {

     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */

	tempbx = SiS_Pr->SiS_LCDResInfo;
	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;

	/* patch index */
	if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
	   if     (resinfo == SIS_RI_1280x800)  tempal =  9;
	   else if(resinfo == SIS_RI_1400x1050) tempal = 11;
	} else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) ||
		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) ||
		  (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) {
	   if     (resinfo == SIS_RI_1280x768)  tempal =  9;
	}

	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
	   /* Pass 1:1 only (center-screen handled outside) */
	   /* This is never called for the panel's native resolution */
	   /* since Pass1:1 will not be set in this case */
	   tempbx = 100;
	   if(ModeNo >= 0x13) {
	      tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
	   }
	}

#ifdef CONFIG_FB_SIS_315
	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
	   if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
		 tempbx = 200;
		 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
	      }
	   }
	}
#endif

     } else {						  	/* TV */

	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
	   /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */
	   tempbx = 2;
	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
	      tempbx = 13;
	      if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14;
	   }
	} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
	   if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempbx = 7;
	   else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempbx = 6;
	   else						tempbx = 5;
	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
	} else {
	   if(SiS_Pr->SiS_TVMode & TVSetPAL)		tempbx = 3;
	   else						tempbx = 4;
	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)	tempbx += 5;
	}

     }

     tempal &= 0x3F;

     if(ModeNo > 0x13) {
        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) {
	   switch(resinfo) {
	   case SIS_RI_720x480:
	      tempal = 6;
	      if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN))	tempal = 9;
	      break;
	   case SIS_RI_720x576:
	   case SIS_RI_768x576:
	   case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */
	      tempal = 6;
	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 8;
	      }
	      break;
	   case SIS_RI_800x480:
	      tempal = 4;
	      break;
	   case SIS_RI_512x384:
	   case SIS_RI_1024x768:
	      tempal = 7;
	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)	tempal = 8;
	      }
	      break;
	   case SIS_RI_1280x720:
	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
		 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)	tempal = 9;
	      }
	      break;
	   }
	}
     }

     *CRT2Index = tempbx;
     *ResIndex = tempal;

  } else {   /* LVDS, 301B-DH (if running on LCD) */

     tempbx = 0;
     if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {

	tempbx = 90;
	if(SiS_Pr->SiS_TVMode & TVSetPAL) {
	   tempbx = 92;
	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
	   }
	   if(SiS_Pr->SiS_TVMode & TVSetPALM)      tempbx = 94;
	   else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96;
	}
	if(tempbx != 99) {
	   if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
	}

     } else {

	switch(SiS_Pr->SiS_LCDResInfo) {
	case Panel_640x480:   tempbx = 12; break;
	case Panel_320x240_1: tempbx = 10; break;
	case Panel_320x240_2:
	case Panel_320x240_3: tempbx = 14; break;
	case Panel_800x600:   tempbx = 16; break;
	case Panel_1024x600:  tempbx = 18; break;
	case Panel_1152x768:
	case Panel_1024x768:  tempbx = 20; break;
	case Panel_1280x768:  tempbx = 22; break;
	case Panel_1280x1024: tempbx = 24; break;
	case Panel_1400x1050: tempbx = 26; break;
	case Panel_1600x1200: tempbx = 28; break;
#ifdef CONFIG_FB_SIS_300
	case Panel_Barco1366: tempbx = 80; break;
#endif
	}

	switch(SiS_Pr->SiS_LCDResInfo) {
	case Panel_320x240_1:
	case Panel_320x240_2:
	case Panel_320x240_3:
	case Panel_640x480:
	   break;
	default:
	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
	}

	if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;

#ifdef CONFIG_FB_SIS_300
	if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
	   tempbx = 82;
	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
	} else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
	   tempbx = 84;
	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
	}
#endif

     }

     (*CRT2Index) = tempbx;
     (*ResIndex) = tempal & 0x1F;
  }
}

static void
SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
		unsigned short RefreshRateTableIndex)
{
  unsigned short tempax=0, tempbx=0, index, dotclock;
  unsigned short temp1=0, modeflag=0, tempcx=0;

  SiS_Pr->SiS_RVBHCMAX  = 1;
  SiS_Pr->SiS_RVBHCFACT = 1;

  if(ModeNo <= 0x13) {

     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
     index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);

     tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
     tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
     temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];

     dotclock = (modeflag & Charx8Dot) ? 8 : 9;

  } else {

     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2);

     tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
     tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
     tempax &= 0x03FF;
     tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
     tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
     tempcx &= 0x0100;
     tempcx <<= 2;
     tempbx |= tempcx;
     temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];

     dotclock = 8;

  }

  if(temp1 & 0x01) tempbx |= 0x0100;
  if(temp1 & 0x20) tempbx |= 0x0200;

  tempax += 5;
  tempax *= dotclock;
  if(modeflag & HalfDCLK) tempax <<= 1;

  tempbx++;

  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
}

static void
SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
		unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex)
{
   unsigned short ResIndex;

   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
	 if(SiS_Pr->UseCustomMode) {
	    ResIndex = SiS_Pr->CHTotal;
	    if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1;
	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex;
	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
	 } else {
	    if(ModeNo < 0x13) {
	       ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
	    } else {
	       ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
	    }
	    if(ResIndex == 0x09) {
	       if(SiS_Pr->Alternate1600x1200)        ResIndex = 0x20; /* 1600x1200 LCDA */
	       else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */
	    }
	    SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
	    SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
	    SiS_Pr->SiS_HT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
	    SiS_Pr->SiS_VT    = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
	 }
      } else {
	 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
	 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
      }
   } else {
      /* This handles custom modes and custom panels */
      SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
      SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
      SiS_Pr->SiS_HT  = SiS_Pr->PanelHT;
      SiS_Pr->SiS_VT  = SiS_Pr->PanelVT;
      SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
      SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
   }
}

static void
SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
                    unsigned short RefreshRateTableIndex)
{
   unsigned short CRT2Index, ResIndex, backup;
   const struct SiS_LVDSData *LVDSData = NULL;

   SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex);

   if(SiS_Pr->SiS_VBType & VB_SISVB) {
      SiS_Pr->SiS_RVBHCMAX  = 1;
      SiS_Pr->SiS_RVBHCFACT = 1;
      SiS_Pr->SiS_NewFlickerMode = 0;
      SiS_Pr->SiS_RVBHRS = 50;
      SiS_Pr->SiS_RY1COE = 0;
      SiS_Pr->SiS_RY2COE = 0;
      SiS_Pr->SiS_RY3COE = 0;
      SiS_Pr->SiS_RY4COE = 0;
      SiS_Pr->SiS_RVBHRS2 = 0;
   }

   if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {

#ifdef CONFIG_FB_SIS_315
      SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
#endif

   } else {

      /* 301BDH needs LVDS Data */
      backup = SiS_Pr->SiS_IF_DEF_LVDS;
      if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
	 SiS_Pr->SiS_IF_DEF_LVDS = 1;
      }

      SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
                     		            &CRT2Index, &ResIndex);

      SiS_Pr->SiS_IF_DEF_LVDS = backup;

      switch(CRT2Index) {
	 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1;    break;
	 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2;    break;
	 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1;    break;
	 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1;    break;
	 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1;   break;
	 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
#ifdef CONFIG_FB_SIS_300
	 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
	 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
	 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
	 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
	 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
#endif
	 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData;        break;
	 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData;        break;
	 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData;         break;
	 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData;         break;
	 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
	 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
	 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
	 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
	 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;
      }

      if(LVDSData) {
	 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
	 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
	 SiS_Pr->SiS_HT    = (LVDSData+ResIndex)->LCDHT;
	 SiS_Pr->SiS_VT    = (LVDSData+ResIndex)->LCDVT;
      } else {
	 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      }

      if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) &&
	  (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
	  (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
	 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ||
	     (SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
	    SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
            SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
#ifdef CONFIG_FB_SIS_300
	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
	       if(ResIndex < 0x08) {
		  SiS_Pr->SiS_HDE = 1280;
		  SiS_Pr->SiS_VDE = 1024;
	       }
	    }
#endif
         }
      }
   }
}

static void
SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
		unsigned short RefreshRateTableIndex)
{
  unsigned char  *ROMAddr = NULL;
  unsigned short tempax, tempbx, modeflag, romptr=0;
  unsigned short resinfo, CRT2Index, ResIndex;
  const struct SiS_LCDData *LCDPtr = NULL;
  const struct SiS_TVData  *TVPtr  = NULL;
#ifdef CONFIG_FB_SIS_315
  short resinfo661;
#endif

  if(ModeNo <= 0x13) {
     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
  } else if(SiS_Pr->UseCustomMode) {
     modeflag = SiS_Pr->CModeFlag;
     resinfo = 0;
  } else {
     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
#ifdef CONFIG_FB_SIS_315
     resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
     if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)   &&
	 (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
	 (resinfo661 >= 0)                     &&
	 (SiS_Pr->SiS_NeedRomModeData) ) {
	if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
	   if((romptr = (SISGETROMW(21)))) {
	      romptr += (resinfo661 * 10);
	      ROMAddr = SiS_Pr->VirtualRomBase;
	   }
	}
     }
#endif
  }

  SiS_Pr->SiS_NewFlickerMode = 0;
  SiS_Pr->SiS_RVBHRS = 50;
  SiS_Pr->SiS_RY1COE = 0;
  SiS_Pr->SiS_RY2COE = 0;
  SiS_Pr->SiS_RY3COE = 0;
  SiS_Pr->SiS_RY4COE = 0;
  SiS_Pr->SiS_RVBHRS2 = 0;

  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex);

  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {

     if(SiS_Pr->UseCustomMode) {

	SiS_Pr->SiS_RVBHCMAX  = 1;
	SiS_Pr->SiS_RVBHCFACT = 1;
	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
	SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;

	tempax = SiS_Pr->CHTotal;
	if(modeflag & HalfDCLK) tempax <<= 1;
	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;

     } else {

	SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);

     }

  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {

     SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
		    &CRT2Index,&ResIndex);

     switch(CRT2Index) {
	case  2: TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
	case  3: TVPtr = SiS_Pr->SiS_ExtPALData;    break;
	case  4: TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
	case  5: TVPtr = SiS_Pr->SiS_Ext525iData;   break;
	case  6: TVPtr = SiS_Pr->SiS_Ext525pData;   break;
	case  7: TVPtr = SiS_Pr->SiS_Ext750pData;   break;
	case  8: TVPtr = SiS_Pr->SiS_StPALData;     break;
	case  9: TVPtr = SiS_Pr->SiS_StNTSCData;    break;
	case 10: TVPtr = SiS_Pr->SiS_St525iData;    break;
	case 11: TVPtr = SiS_Pr->SiS_St525pData;    break;
	case 12: TVPtr = SiS_Pr->SiS_St750pData;    break;
	case 13: TVPtr = SiS_Pr->SiS_St1HiTVData;   break;
	case 14: TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
	default: TVPtr = SiS_Pr->SiS_StPALData;     break;
     }

     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
     SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT;
     SiS_Pr->SiS_VGAHT     = (TVPtr+ResIndex)->VGAHT;
     SiS_Pr->SiS_VGAVT     = (TVPtr+ResIndex)->VGAVT;
     SiS_Pr->SiS_HDE       = (TVPtr+ResIndex)->TVHDE;
     SiS_Pr->SiS_VDE       = (TVPtr+ResIndex)->TVVDE;
     SiS_Pr->SiS_RVBHRS2   = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff;
     if(modeflag & HalfDCLK) {
	SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
	if(SiS_Pr->SiS_RVBHRS2) {
	   SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
	   tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07;
	   if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax;
	   else                                   SiS_Pr->SiS_RVBHRS2 += tempax;
	}
     } else {
	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
     }
     SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7;

     if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {

	if((resinfo == SIS_RI_960x600)   ||
	   (resinfo == SIS_RI_1024x768)  ||
	   (resinfo == SIS_RI_1280x1024) ||
	   (resinfo == SIS_RI_1280x720)) {
	   SiS_Pr->SiS_NewFlickerMode = 0x40;
	}

	if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode;

	SiS_Pr->SiS_HT = ExtHiTVHT;
	SiS_Pr->SiS_VT = ExtHiTVVT;
	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
	   if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
	      SiS_Pr->SiS_HT = StHiTVHT;
	      SiS_Pr->SiS_VT = StHiTVVT;
	   }
	}

     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {

	if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
	   SiS_Pr->SiS_HT = 1650;
	   SiS_Pr->SiS_VT = 750;
	} else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
	   SiS_Pr->SiS_HT = NTSCHT;
	   if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT;
	   SiS_Pr->SiS_VT = NTSCVT;
	} else {
	   SiS_Pr->SiS_HT = NTSCHT;
	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
	   SiS_Pr->SiS_VT = NTSCVT;
	}

     } else {

	SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
	SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
	SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
	SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;

	if(modeflag & HalfDCLK) {
	   SiS_Pr->SiS_RY1COE = 0x00;
	   SiS_Pr->SiS_RY2COE = 0xf4;
	   SiS_Pr->SiS_RY3COE = 0x10;
	   SiS_Pr->SiS_RY4COE = 0x38;
	}

	if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
	   SiS_Pr->SiS_HT = NTSCHT;
	   if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT;
	   SiS_Pr->SiS_VT = NTSCVT;
	} else {
	   SiS_Pr->SiS_HT = PALHT;
	   SiS_Pr->SiS_VT = PALVT;
	}

     }

  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {

     SiS_Pr->SiS_RVBHCMAX  = 1;
     SiS_Pr->SiS_RVBHCFACT = 1;

     if(SiS_Pr->UseCustomMode) {

	SiS_Pr->SiS_HDE   = SiS_Pr->SiS_VGAHDE;
	SiS_Pr->SiS_VDE   = SiS_Pr->SiS_VGAVDE;

	tempax = SiS_Pr->CHTotal;
	if(modeflag & HalfDCLK) tempax <<= 1;
	SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
	SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;

     } else {

	bool gotit = false;

	if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {

	   SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
	   SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
	   SiS_Pr->SiS_HT    = SiS_Pr->PanelHT;
	   SiS_Pr->SiS_VT    = SiS_Pr->PanelVT;
	   gotit = true;

	} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {

#ifdef CONFIG_FB_SIS_315
	   SiS_Pr->SiS_RVBHCMAX  = ROMAddr[romptr];
	   SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
	   SiS_Pr->SiS_VGAHT     = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
	   SiS_Pr->SiS_VGAVT     = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4);
	   SiS_Pr->SiS_HT        = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
	   SiS_Pr->SiS_VT        = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4);
	   SiS_Pr->SiS_RVBHRS2   = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8);
	   if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) {
	      SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3;
	      tempax = (ROMAddr[romptr+9] >> 4) & 0x07;
	      if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
	      else                         SiS_Pr->SiS_RVBHRS2 += tempax;
	   }
	   if(SiS_Pr->SiS_VGAHT) gotit = true;
	   else {
	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
	      SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
	      SiS_Pr->SiS_RVBHCMAX  = 1;
	      SiS_Pr->SiS_RVBHCFACT = 1;
	      SiS_Pr->SiS_VGAHT   = SiS_Pr->PanelHT;
	      SiS_Pr->SiS_VGAVT   = SiS_Pr->PanelVT;
	      SiS_Pr->SiS_HT      = SiS_Pr->PanelHT;
	      SiS_Pr->SiS_VT      = SiS_Pr->PanelVT;
	      SiS_Pr->SiS_RVBHRS2 = 0;
	      gotit = true;
	   }
#endif

	}

	if(!gotit) {

	   SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
			  &CRT2Index,&ResIndex);

	   switch(CRT2Index) {
	      case Panel_1024x768      : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
	      case Panel_1024x768  + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;   break;
	      case Panel_1280x720      :
	      case Panel_1280x720  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data;      break;
	      case Panel_1280x768_2    : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
	      case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data;  break;
	      case Panel_1280x800      :
	      case Panel_1280x800  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data;      break;
	      case Panel_1280x800_2    :
	      case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data;    break;
	      case Panel_1280x854      :
	      case Panel_1280x854  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data;      break;
	      case Panel_1280x960      :
	      case Panel_1280x960  + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;      break;
	      case Panel_1280x1024     : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;  break;
	      case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
	      case Panel_1400x1050     : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;  break;
	      case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;   break;
	      case Panel_1600x1200     : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;  break;
	      case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;   break;
	      case Panel_1680x1050     :
	      case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data;     break;
	      case 100		       : LCDPtr = SiS_Pr->SiS_NoScaleData;	    break;
#ifdef CONFIG_FB_SIS_315
	      case 200                 : LCDPtr = SiS310_ExtCompaq1280x1024Data;    break;
	      case 201                 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;  break;
#endif
	      default                  : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;   break;
	   }

	   SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
	   SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
	   SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
	   SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
	   SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
	   SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;

        }

	tempax = SiS_Pr->PanelXRes;
	tempbx = SiS_Pr->PanelYRes;

	switch(SiS_Pr->SiS_LCDResInfo) {
	case Panel_1024x768:
	   if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
	      if(SiS_Pr->ChipType < SIS_315H) {
		 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
		 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
	      }
	   } else {
	      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
	      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
	      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
	      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
	      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
	      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
	   }
	   break;
	case Panel_1280x960:
	   if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
	   else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
	   else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
	   break;
	case Panel_1280x1024:
	   if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
	   else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
	   else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
	   break;
	case Panel_1600x1200:
	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
	      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
	      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
	   }
	   break;
	}

	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
	   tempax = SiS_Pr->SiS_VGAHDE;
	   tempbx = SiS_Pr->SiS_VGAVDE;
	}

	SiS_Pr->SiS_HDE = tempax;
	SiS_Pr->SiS_VDE = tempbx;
     }
  }
}

static void
SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
                unsigned short RefreshRateTableIndex)
{

   if(SiS_Pr->SiS_VBType & VB_SISVB) {

      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
         SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
      } else {
	 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
	    /* Need LVDS Data for LCD on 301B-DH */
	    SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
	 } else {
	    SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
	 }
      }

   } else {

      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);

   }
}

/*********************************************/
/*         GET LVDS DES (SKEW) DATA          */
/*********************************************/

static const struct SiS_LVDSDes *
SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
{
   const struct SiS_LVDSDes *PanelDesPtr = NULL;

#ifdef CONFIG_FB_SIS_300
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {

      if(SiS_Pr->ChipType < SIS_315H) {
	 if(SiS_Pr->SiS_LCDTypeInfo == 4) {
	    if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1a;
	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2a;
	       }
            } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
	       PanelDesPtr = SiS_Pr->SiS_PanelType04_1b;
	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
		  PanelDesPtr = SiS_Pr->SiS_PanelType04_2b;
	       }
	    }
	 }
      }
   }
#endif
   return PanelDesPtr;
}

static void
SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
                   unsigned short RefreshRateTableIndex)
{
  unsigned short modeflag, ResIndex;
  const struct SiS_LVDSDes *PanelDesPtr = NULL;

  SiS_Pr->SiS_LCDHDES = 0;
  SiS_Pr->SiS_LCDVDES = 0;

  /* Some special cases */
  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {

     /* Trumpion */
     if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
	if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
	   if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	   }
	}
	return;
     }

     /* 640x480 on LVDS */
     if(SiS_Pr->ChipType < SIS_315H) {
	if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) {
	   SiS_Pr->SiS_LCDHDES = 8;
	   if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
	   else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
	   else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
	   return;
	}
     }

  } /* LCD */

  if( (SiS_Pr->UseCustomMode) 		         ||
      (SiS_Pr->SiS_LCDResInfo == Panel_Custom)   ||
      (SiS_Pr->SiS_CustomT == CUT_PANEL848)      ||
      (SiS_Pr->SiS_CustomT == CUT_PANEL856)      ||
      (SiS_Pr->SiS_LCDInfo & LCDPass11) ) {
     return;
  }

  if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
  else               ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;

  if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {

#ifdef CONFIG_FB_SIS_315
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
	/* non-pass 1:1 only, see above */
	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
	}
	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
	}
     }
     if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
	switch(SiS_Pr->SiS_CustomT) {
	case CUT_UNIWILL1024:
	case CUT_UNIWILL10242:
	case CUT_CLEVO1400:
	   if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	   }
	   break;
	}
	switch(SiS_Pr->SiS_LCDResInfo) {
	case Panel_1280x1024:
	   if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	   }
	   break;
	case Panel_1280x800:	/* Verified for Averatec 6240 */
	case Panel_1280x800_2:	/* Verified for Asus A4L */
	case Panel_1280x854:    /* Not verified yet FIXME */
	   SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	   break;
	}
     }
#endif

  } else {

     if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {

	if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) {
	   if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256;
	}

     } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) {

	SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
	SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;

     } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {

	if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
	   SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
	}
	if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
	   SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
	} else {
	   if(SiS_Pr->ChipType < SIS_315H) {
	      SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	   } else {
	      switch(SiS_Pr->SiS_LCDResInfo) {
	      case Panel_800x600:
	      case Panel_1024x768:
	      case Panel_1280x1024:
		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
		 break;
	      case Panel_1400x1050:
		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
		 break;
	      }
	   }
	}

     } else {

        if(SiS_Pr->ChipType < SIS_315H) {
#ifdef CONFIG_FB_SIS_300
	   switch(SiS_Pr->SiS_LCDResInfo) {
	   case Panel_800x600:
	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	      } else {
		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3;
		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT;
		 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2;
		 else                          SiS_Pr->SiS_LCDVDES -= 4;
	      }
	      break;
	   case Panel_1024x768:
	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	      } else {
		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
		 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8;
		 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12;
	      }
	      break;
	   case Panel_1024x600:
	   default:
	      if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) &&
		  (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) {
		 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	      } else {
		 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1;
	      }
	      break;
	   }

	   switch(SiS_Pr->SiS_LCDTypeInfo) {
	   case 1:
	      SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
	      break;
	   case 3: /* 640x480 only? */
	      SiS_Pr->SiS_LCDHDES = 8;
	      if     (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512;
	      else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436;
	      else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440;
	      break;
	   }
#endif
        } else {
#ifdef CONFIG_FB_SIS_315
	   switch(SiS_Pr->SiS_LCDResInfo) {
	   case Panel_1024x768:
	   case Panel_1280x1024:
	      if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
	         SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
	      }
	      break;
	   case Panel_320x240_1:
	   case Panel_320x240_2:
	   case Panel_320x240_3:
	      SiS_Pr->SiS_LCDVDES = 524;
	      break;
	   }
#endif
	}
     }

     if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
	if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
	   if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
	} else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
	   if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
	      if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
	         if(SiS_Pr->ChipType < SIS_315H) {
	            if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
	         } else {
#ifdef CONFIG_FB_SIS_315
		    if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768)  SiS_Pr->SiS_LCDHDES = 480;
		    if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
		    if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
		    if(!(modeflag & HalfDCLK)) {
		       SiS_Pr->SiS_LCDHDES = 320;
		       if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
		       if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
        	    }
#endif
		 }
	      }
	   }
	}
     }
  }
}

/*********************************************/
/*           DISABLE VIDEO BRIDGE            */
/*********************************************/

#ifdef CONFIG_FB_SIS_315
static int
SiS_HandlePWD(struct SiS_Private *SiS_Pr)
{
   int ret = 0;
#ifdef SET_PWD
   unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
   unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
   unsigned char  drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40;
   unsigned short temp;

   if( (SiS_Pr->SiS_VBType & VB_SISPWD) &&
       (romptr)				&&
       (SiS_Pr->SiS_PWDOffset) ) {
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]);
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]);
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]);
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]);
      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]);
      temp = 0x00;
      if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) {
         temp = 0x80;
	 ret = 1;
      }
      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
   }
#endif
   return ret;
}
#endif

/* NEVER use any variables (VBInfo), this will be called
 * from outside the context of modeswitch!
 * MUST call getVBType before calling this
 */
void
SiS_DisableBridge(struct SiS_Private *SiS_Pr)
{
#ifdef CONFIG_FB_SIS_315
  unsigned short tempah, pushax=0, modenum;
#endif
  unsigned short temp=0;

  if(SiS_Pr->SiS_VBType & VB_SISVB) {

     if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ===== For 30xB/C/LV ===== */

	if(SiS_Pr->ChipType < SIS_315H) {

#ifdef CONFIG_FB_SIS_300	   /* 300 series */

	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
	      } else {
		 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
	      }
	      SiS_PanelDelay(SiS_Pr, 3);
	   }
	   if(SiS_Is301B(SiS_Pr)) {
	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
	      SiS_ShortDelay(SiS_Pr,1);
	   }
	   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
	   SiS_DisplayOff(SiS_Pr);
	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
	   SiS_UnLockCRT2(SiS_Pr);
	   if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) {
	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
	   }
	   if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
	       (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
	      SiS_PanelDelay(SiS_Pr, 2);
	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
	      } else {
		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
	      }
	   }

#endif  /* CONFIG_FB_SIS_300 */

        } else {

#ifdef CONFIG_FB_SIS_315	   /* 315 series */

	   int didpwd = 0;
	   bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
	                  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);

	   modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;

	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {

#ifdef SET_EMI
	      if(SiS_Pr->SiS_VBType & VB_SISEMI) {
		 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
		 }
	      }
#endif

	      didpwd = SiS_HandlePWD(SiS_Pr);

	      if( (modenum <= 0x13)           ||
		  (SiS_IsVAMode(SiS_Pr))      ||
		  (!(SiS_IsDualEdge(SiS_Pr))) ) {
		 if(!didpwd) {
		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe);
		    if(custom1) SiS_PanelDelay(SiS_Pr, 3);
		 } else {
		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc);
		 }
	      }

	      if(!custom1) {
		 SiS_DDC2Delay(SiS_Pr,0xff00);
		 SiS_DDC2Delay(SiS_Pr,0xe000);
		 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
		 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
		 if(IS_SIS740) {
		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
		 }
	         SiS_PanelDelay(SiS_Pr, 3);
	      }

	   }

	   if(!(SiS_IsNotM650orLater(SiS_Pr))) {
	      /* if(SiS_Pr->ChipType < SIS_340) {*/
		 tempah = 0xef;
		 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7;
		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
	      /*}*/
	   }

	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
	   }

	   tempah = 0x3f;
	   if(SiS_IsDualEdge(SiS_Pr)) {
	      tempah = 0x7f;
	      if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf;
	   }
	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);

	   if((SiS_IsVAMode(SiS_Pr)) ||
	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {

	      SiS_DisplayOff(SiS_Pr);
	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
		 SiS_PanelDelay(SiS_Pr, 2);
	      }
	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);

	   }

	   if((!(SiS_IsVAMode(SiS_Pr))) ||
	      ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) {

	      if(!(SiS_IsDualEdge(SiS_Pr))) {
		 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
		 SiS_DisplayOff(SiS_Pr);
	      }
	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);

	      if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
		 SiS_PanelDelay(SiS_Pr, 2);
	      }

	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
	      temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);

	   }

	   if(SiS_IsNotM650orLater(SiS_Pr)) {
	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
	   }

	   if(SiS_Pr->SiS_VBType & VB_SISLVDS) {

	      if( (!(SiS_IsVAMode(SiS_Pr)))  &&
		  (!(SiS_CRT2IsLCD(SiS_Pr))) &&
		  (!(SiS_IsDualEdge(SiS_Pr))) ) {

		 if(custom1) SiS_PanelDelay(SiS_Pr, 2);
		 if(!didpwd) {
		    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
		 }
		 if(custom1) SiS_PanelDelay(SiS_Pr, 4);
	      }

	      if(!custom1) {
		 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
		 if(SiS_Pr->SiS_VBType & VB_SISEMI) {
		    if(SiS_IsVAorLCD(SiS_Pr)) {
		       SiS_PanelDelayLoop(SiS_Pr, 3, 20);
		    }
		 }
	      }

	   }

#endif /* CONFIG_FB_SIS_315 */

	}

     } else {     /* ============ For 301 ================ */

        if(SiS_Pr->ChipType < SIS_315H) {
#ifdef CONFIG_FB_SIS_300
	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
	      SiS_PanelDelay(SiS_Pr, 3);
	   }
#endif
	}

	SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
	SiS_DisplayOff(SiS_Pr);

	if(SiS_Pr->ChipType >= SIS_315H) {
	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
	}

	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */

	if(SiS_Pr->ChipType >= SIS_315H) {
	    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
	} else {
#ifdef CONFIG_FB_SIS_300
	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
	    if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
		(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
		SiS_PanelDelay(SiS_Pr, 2);
		SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
	    }
#endif
	}

      }

  } else {     /* ============ For LVDS =============*/

    if(SiS_Pr->ChipType < SIS_315H) {

#ifdef CONFIG_FB_SIS_300	/* 300 series */

	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
	   SiS_SetCH700x(SiS_Pr,0x0E,0x09);
	}

	if(SiS_Pr->ChipType == SIS_730) {
	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
	      SiS_WaitVBRetrace(SiS_Pr);
	   }
	   if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
	      SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
	      SiS_PanelDelay(SiS_Pr, 3);
	   }
	} else {
	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
		 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
		    SiS_WaitVBRetrace(SiS_Pr);
		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
		       SiS_DisplayOff(SiS_Pr);
		    }
		    SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
		    SiS_PanelDelay(SiS_Pr, 3);
		 }
	      }
	   }
	}

	SiS_DisplayOff(SiS_Pr);

	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);

	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
	SiS_UnLockCRT2(SiS_Pr);
	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);

	if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
	    (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
	   SiS_PanelDelay(SiS_Pr, 2);
	   SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
	}

#endif  /* CONFIG_FB_SIS_300 */

    } else {

#ifdef CONFIG_FB_SIS_315	/* 315 series */

	if(!(SiS_IsNotM650orLater(SiS_Pr))) {
	   /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
	   /* } */
	}

	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {

	   if(SiS_Pr->ChipType == SIS_740) {
	      temp = SiS_GetCH701x(SiS_Pr,0x61);
	      if(temp < 1) {
		 SiS_SetCH701x(SiS_Pr,0x76,0xac);
		 SiS_SetCH701x(SiS_Pr,0x66,0x00);
	      }

	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
		 SiS_SetCH701x(SiS_Pr,0x49,0x3e);
	      }
	   }

	   if( (!(SiS_IsDualEdge(SiS_Pr))) ||
	       (SiS_IsVAMode(SiS_Pr)) ) {
	      SiS_Chrontel701xBLOff(SiS_Pr);
	      SiS_Chrontel701xOff(SiS_Pr);
	   }

	   if(SiS_Pr->ChipType != SIS_740) {
	      if( (!(SiS_IsDualEdge(SiS_Pr))) ||
		  (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) {
		 SiS_SetCH701x(SiS_Pr,0x49,0x01);
	      }
	   }

	}

	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
	   SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
	   SiS_PanelDelay(SiS_Pr, 3);
	}

	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
	    (!(SiS_IsDualEdge(SiS_Pr))) ||
	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) {
	   SiS_DisplayOff(SiS_Pr);
	}

	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
	    (!(SiS_IsDualEdge(SiS_Pr))) ||
	    (!(SiS_IsVAMode(SiS_Pr))) ) {
	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
	}

	if(SiS_Pr->ChipType == SIS_740) {
	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
	}

	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);

	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
	    (!(SiS_IsDualEdge(SiS_Pr))) ||
	    (!(SiS_IsVAMode(SiS_Pr))) ) {
	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
	}

	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
	   if(SiS_CRT2IsLCD(SiS_Pr)) {
	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
	      if(SiS_Pr->ChipType == SIS_550) {
		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
	      }
	   }
	} else {
	   if(SiS_Pr->ChipType == SIS_740) {
	      if(SiS_IsLCDOrLCDA(SiS_Pr)) {
		 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
	      }
	   } else if(SiS_IsVAMode(SiS_Pr)) {
	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
	   }
	}

	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
	   if(SiS_IsDualEdge(SiS_Pr)) {
	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
	   } else {
	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
	   }
	}

	SiS_UnLockCRT2(SiS_Pr);

	if(SiS_Pr->ChipType == SIS_550) {
	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
		   (!(SiS_IsDualEdge(SiS_Pr))) ||
		   (!(SiS_IsVAMode(SiS_Pr))) ) {
	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
	}

        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
	   if(SiS_CRT2IsLCD(SiS_Pr)) {
	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
		 SiS_PanelDelay(SiS_Pr, 2);
		 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
	      }
	   }
        }

#endif  /* CONFIG_FB_SIS_315 */

    }  /* 315 series */

  }  /* LVDS */

}

/*********************************************/
/*            ENABLE VIDEO BRIDGE            */
/*********************************************/

/* NEVER use any variables (VBInfo), this will be called
 * from outside the context of a mode switch!
 * MUST call getVBType before calling this
 */
static
void
SiS_EnableBridge(struct SiS_Private *SiS_Pr)
{
  unsigned short temp=0, tempah;
#ifdef CONFIG_FB_SIS_315
  unsigned short temp1, pushax=0;
  bool delaylong = false;
#endif

  if(SiS_Pr->SiS_VBType & VB_SISVB) {

    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {		/* ====== For 301B et al  ====== */

      if(SiS_Pr->ChipType < SIS_315H) {

#ifdef CONFIG_FB_SIS_300     /* 300 series */

	 if(SiS_CRT2IsLCD(SiS_Pr)) {
	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
	       SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
	    }
	    if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) {
	       if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
		  SiS_PanelDelay(SiS_Pr, 0);
	       }
	    }
	 }

	 if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
	    (SiS_CRT2IsLCD(SiS_Pr))) {

	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   		/* Enable CRT2 */
	    SiS_DisplayOn(SiS_Pr);
	    SiS_UnLockCRT2(SiS_Pr);
	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
	    } else {
	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
	    }
	    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
		  if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
		     SiS_PanelDelay(SiS_Pr, 1);
		  }
		  SiS_WaitVBRetrace(SiS_Pr);
		  SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
	       }
	    }

	 } else {

	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
	       if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
	    }
	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
	    SiS_DisplayOn(SiS_Pr);
	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	       if(SiS_CRT2IsLCD(SiS_Pr)) {
		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
		     if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
		        SiS_PanelDelay(SiS_Pr, 1);
		     }
		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
		  }
	       }
	    }

	 }


#endif /* CONFIG_FB_SIS_300 */

      } else {

#ifdef CONFIG_FB_SIS_315    /* 315 series */

#ifdef SET_EMI
	 unsigned char   r30=0, r31=0, r32=0, r33=0, cr36=0;
	 int didpwd = 0;
	 /* unsigned short  emidelay=0; */
#endif

	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
#ifdef SET_EMI
	    if(SiS_Pr->SiS_VBType & VB_SISEMI) {
	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
	    }
#endif
	 }

	 if(!(SiS_IsNotM650orLater(SiS_Pr))) {
	    /*if(SiS_Pr->ChipType < SIS_340) { */
	       tempah = 0x10;
	       if(SiS_LCDAEnabled(SiS_Pr)) {
		  if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18;
		  else			    tempah = 0x08;
	       }
	       SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
	    /*}*/
	 }

	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {

	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
	    SiS_DisplayOff(SiS_Pr);
	    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
	    if(IS_SIS740) {
	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
	    }

	    didpwd = SiS_HandlePWD(SiS_Pr);

	    if(SiS_IsVAorLCD(SiS_Pr)) {
	       if(!didpwd) {
		  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
		     SiS_PanelDelayLoop(SiS_Pr, 3, 2);
		     if(SiS_Pr->SiS_VBType & VB_SISEMI) {
		        SiS_GenericDelay(SiS_Pr, 17664);
		     }
		  }
	       } else {
		  SiS_PanelDelayLoop(SiS_Pr, 3, 2);
		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
		     SiS_GenericDelay(SiS_Pr, 17664);
		  }
	       }
	    }

	    if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
	       SiS_PanelDelayLoop(SiS_Pr, 3, 10);
	       delaylong = true;
	    }

	 }

	 if(!(SiS_IsVAMode(SiS_Pr))) {

	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
	    if(SiS_BridgeInSlavemode(SiS_Pr)) {
	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
	       if(!(tempah & SetCRT2ToRAMDAC)) {
		  if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20;
	       }
	    }
	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);

	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */

	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);

	    if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
	       SiS_PanelDelay(SiS_Pr, 2);
	    }

	 } else {

	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);

	 }

	 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
	 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);

	 if(SiS_Pr->SiS_VBType & VB_SISPOWER) {
	    if( (SiS_LCDAEnabled(SiS_Pr)) ||
	        (SiS_CRT2IsLCD(SiS_Pr)) ) {
	       /* Enable "LVDS PLL power on" (even on 301C) */
	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);
	       /* Enable "LVDS Driver Power on" (even on 301C) */
	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f);
	    }
	 }

	 tempah = 0xc0;
	 if(SiS_IsDualEdge(SiS_Pr)) {
	    tempah = 0x80;
	    if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40;
	 }
	 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);

	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {

	    SiS_PanelDelay(SiS_Pr, 2);

	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);

	    if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
#ifdef SET_EMI
	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
		  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
		  SiS_GenericDelay(SiS_Pr, 2048);
	       }
#endif
	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);

	       if(SiS_Pr->SiS_VBType & VB_SISEMI) {
#ifdef SET_EMI
		  cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);

		  if(SiS_Pr->SiS_ROMNew) {
		     unsigned char  *ROMAddr = SiS_Pr->VirtualRomBase;
		     unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr);
		     if(romptr) {
			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
			SiS_Pr->EMI_30 = 0;
			SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0];
			SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1];
			SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
			if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
			/* emidelay = SISGETROMW((romptr + 0x22)); */
			SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
		     }
		  }

		  /*                                              (P4_30|0x40)  */
		  /* Compal 1400x1050: 0x05, 0x60, 0x00                YES  (1.10.7w;  CR36=69)      */
		  /* Compal 1400x1050: 0x0d, 0x70, 0x40                YES  (1.10.7x;  CR36=69)      */
		  /* Acer   1280x1024: 0x12, 0xd0, 0x6b                NO   (1.10.9k;  CR36=73)      */
		  /* Compaq 1280x1024: 0x0d, 0x70, 0x6b                YES  (1.12.04b; CR36=03)      */
		  /* Clevo   1024x768: 0x05, 0x60, 0x33                NO   (1.10.8e;  CR36=12, DL!) */
		  /* Clevo   1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES  (1.10.8y;  CR36=?2)      */
		  /* Clevo   1024x768: 0x05, 0x60, 0x33 (if type != 3) YES  (1.10.8y;  CR36=?2)      */
		  /* Asus    1024x768: ?                                ?   (1.10.8o;  CR36=?2)      */
		  /* Asus    1024x768: 0x08, 0x10, 0x3c (problematic)  YES  (1.10.8q;  CR36=22)      */

		  if(SiS_Pr->HaveEMI) {
		     r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
		     r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
		  } else {
		     r30 = 0;
		  }

		  /* EMI_30 is read at driver start; however, the BIOS sets this
		   * (if it is used) only if the LCD is in use. In case we caught
		   * the machine while on TV output, this bit is not set and we
		   * don't know if it should be set - hence our detection is wrong.
		   * Work-around this here:
		   */

		  if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
		     switch((cr36 & 0x0f)) {
		     case 2:
			r30 |= 0x40;
			if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
			if(!SiS_Pr->HaveEMI) {
			   r31 = 0x05; r32 = 0x60; r33 = 0x33;
			   if((cr36 & 0xf0) == 0x30) {
			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;
			   }
			}
			break;
		     case 3:  /* 1280x1024 */
			if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
			if(!SiS_Pr->HaveEMI) {
			   r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
			   if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
			      r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
			   }
			}
			break;
		     case 9:  /* 1400x1050 */
			r30 |= 0x40;
			if(!SiS_Pr->HaveEMI) {
			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
			   if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
			      r31 = 0x0d; r32 = 0x70; r33 = 0x40;  /* BIOS values */
			   }
			}
			break;
		     case 11: /* 1600x1200 - unknown */
			r30 |= 0x40;
			if(!SiS_Pr->HaveEMI) {
			   r31 = 0x05; r32 = 0x60; r33 = 0x00;
			}
		     }
                  }

		  /* BIOS values don't work so well sometimes */
		  if(!SiS_Pr->OverruleEMI) {
#ifdef COMPAL_HACK
		     if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
			if((cr36 & 0x0f) == 0x09) {
			   r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
			}
 		     }
#endif
#ifdef COMPAQ_HACK
		     if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
			if((cr36 & 0x0f) == 0x03) {
			   r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
			}
		     }
#endif
#ifdef ASUS_HACK
		     if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
			if((cr36 & 0x0f) == 0x02) {
			   /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 2 */
			   /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33;  */   /* rev 3 */
			   /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 4 */
			   /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40;  */   /* rev 5 */
			}
		     }
#endif
		  }

		  if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */
		     SiS_GenericDelay(SiS_Pr, 2048);
		  }
		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
#endif	/* SET_EMI */

		  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);

#ifdef SET_EMI
		  if( (SiS_LCDAEnabled(SiS_Pr)) ||
		      (SiS_CRT2IsLCD(SiS_Pr)) ) {
		     if(r30 & 0x40) {
			/*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/
			SiS_PanelDelayLoop(SiS_Pr, 3, 5);
			if(delaylong) {
			   SiS_PanelDelayLoop(SiS_Pr, 3, 5);
			   delaylong = false;
			}
			SiS_WaitVBRetrace(SiS_Pr);
			SiS_WaitVBRetrace(SiS_Pr);
			if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
			   SiS_GenericDelay(SiS_Pr, 1280);
			}
			SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);   /* Enable */
			/*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/
		     }
		  }
#endif
	       }
	    }

	    if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
	       if(SiS_IsVAorLCD(SiS_Pr)) {
		  SiS_PanelDelayLoop(SiS_Pr, 3, 10);
		  if(delaylong) {
		     SiS_PanelDelayLoop(SiS_Pr, 3, 10);
		  }
		  SiS_WaitVBRetrace(SiS_Pr);
		  if(SiS_Pr->SiS_VBType & VB_SISEMI) {
		     SiS_GenericDelay(SiS_Pr, 2048);
		     SiS_WaitVBRetrace(SiS_Pr);
		  }
		  if(!didpwd) {
		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
		  } else {
		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03);
		  }
	       }
	    }

	    SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
	    SiS_DisplayOn(SiS_Pr);
	    SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);

	 }

	 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
	 }

#endif /* CONFIG_FB_SIS_315 */

      }

    } else {	/* ============  For 301 ================ */

       if(SiS_Pr->ChipType < SIS_315H) {
	  if(SiS_CRT2IsLCD(SiS_Pr)) {
	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
	     SiS_PanelDelay(SiS_Pr, 0);
	  }
       }

       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
       if(SiS_BridgeInSlavemode(SiS_Pr)) {
	  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
	  if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
       }
       SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);

       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */

       if(SiS_Pr->ChipType >= SIS_315H) {
	  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
	  if(!(temp & 0x80)) {
	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
	  }
       }

       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */

       SiS_VBLongWait(SiS_Pr);
       SiS_DisplayOn(SiS_Pr);
       if(SiS_Pr->ChipType >= SIS_315H) {
	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
       }
       SiS_VBLongWait(SiS_Pr);

       if(SiS_Pr->ChipType < SIS_315H) {
	  if(SiS_CRT2IsLCD(SiS_Pr)) {
	     SiS_PanelDelay(SiS_Pr, 1);
	     SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
	  }
       }

    }

  } else {   /* =================== For LVDS ================== */

    if(SiS_Pr->ChipType < SIS_315H) {

#ifdef CONFIG_FB_SIS_300    /* 300 series */

       if(SiS_CRT2IsLCD(SiS_Pr)) {
	  if(SiS_Pr->ChipType == SIS_730) {
	     SiS_PanelDelay(SiS_Pr, 1);
	     SiS_PanelDelay(SiS_Pr, 1);
	     SiS_PanelDelay(SiS_Pr, 1);
	  }
	  SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
	  if(!(SiS_CR36BIOSWord23d(SiS_Pr))) {
	     SiS_PanelDelay(SiS_Pr, 0);
	  }
       }

       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
       SiS_DisplayOn(SiS_Pr);
       SiS_UnLockCRT2(SiS_Pr);
       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
       if(SiS_BridgeInSlavemode(SiS_Pr)) {
	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
       } else {
	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
       }

       if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
	  if(!(SiS_CRT2IsLCD(SiS_Pr))) {
	     SiS_WaitVBRetrace(SiS_Pr);
	     SiS_SetCH700x(SiS_Pr,0x0E,0x0B);
	  }
       }

       if(SiS_CRT2IsLCD(SiS_Pr)) {
	  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
	     if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
		if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
		   SiS_PanelDelay(SiS_Pr, 1);
		   SiS_PanelDelay(SiS_Pr, 1);
		}
		SiS_WaitVBRetrace(SiS_Pr);
		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
	     }
	  }
       }

#endif  /* CONFIG_FB_SIS_300 */

    } else {

#ifdef CONFIG_FB_SIS_315    /* 315 series */

       if(!(SiS_IsNotM650orLater(SiS_Pr))) {
	  /*if(SiS_Pr->ChipType < SIS_340) {*/  /* XGI needs this */
	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
	  /*}*/
       }

       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
	  if(SiS_CRT2IsLCD(SiS_Pr)) {
	     SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00);
	     SiS_PanelDelay(SiS_Pr, 0);
	  }
       }

       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
       SiS_UnLockCRT2(SiS_Pr);

       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);

       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	  temp = SiS_GetCH701x(SiS_Pr,0x66);
	  temp &= 0x20;
	  SiS_Chrontel701xBLOff(SiS_Pr);
       }

       if(SiS_Pr->ChipType != SIS_550) {
	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
       }

       if(SiS_Pr->ChipType == SIS_740) {
	  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	     if(SiS_IsLCDOrLCDA(SiS_Pr)) {
		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
	     }
	  }
       }

       temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
       if(!(temp1 & 0x80)) {
	  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
       }

       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	  if(temp) {
	     SiS_Chrontel701xBLOn(SiS_Pr);
	  }
       }

       if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
	  if(SiS_CRT2IsLCD(SiS_Pr)) {
	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
	     if(SiS_Pr->ChipType == SIS_550) {
		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
	     }
	  }
       } else if(SiS_IsVAMode(SiS_Pr)) {
	  if(SiS_Pr->ChipType != SIS_740) {
	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
	  }
       }

       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
       }

       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) {
	     SiS_Chrontel701xOn(SiS_Pr);
	  }
	  if( (SiS_IsVAMode(SiS_Pr)) ||
	      (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
	     SiS_ChrontelDoSomething1(SiS_Pr);
	  }
       }

       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
	     if( (SiS_IsVAMode(SiS_Pr)) ||
		 (SiS_IsLCDOrLCDA(SiS_Pr)) ) {
		SiS_Chrontel701xBLOn(SiS_Pr);
		SiS_ChrontelInitTVVSync(SiS_Pr);
	     }
	  }
       } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) {
	     if(SiS_CRT2IsLCD(SiS_Pr)) {
		SiS_PanelDelay(SiS_Pr, 1);
		SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00);
	     }
	  }
       }

#endif  /* CONFIG_FB_SIS_315 */

    } /* 310 series */

  }  /* LVDS */

}

/*********************************************/
/*         SET PART 1 REGISTER GROUP         */
/*********************************************/

/* Set CRT2 OFFSET / PITCH */
static void
SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
		unsigned short RRTI)
{
   unsigned short offset;
   unsigned char  temp;

   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;

   offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI);

   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));

   temp = (unsigned char)(((offset >> 3) & 0xFF) + 1);
   if(offset & 0x07) temp++;
   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
}

/* Set CRT2 sync and PanelLink mode */
static void
SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex)
{
   unsigned short tempah=0, tempbl, infoflag;

   tempbl = 0xC0;

   if(SiS_Pr->UseCustomMode) {
      infoflag = SiS_Pr->CInfoFlag;
   } else {
      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
   }

   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */

      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
	 tempah = 0;
      } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
	 tempah = SiS_Pr->SiS_LCDInfo;
      } else tempah = infoflag >> 8;
      tempah &= 0xC0;
      tempah |= 0x20;
      if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
	 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
	    (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
	    tempah |= 0xf0;
	 }
	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
	     (SiS_Pr->SiS_IF_DEF_DSTN) ||
	     (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
	     (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
	     (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) {
	    tempah |= 0x30;
	 }
	 if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
	     (SiS_Pr->SiS_IF_DEF_DSTN) ) {
	    tempah &= ~0xc0;
	 }
      }
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
	 if(SiS_Pr->ChipType >= SIS_315H) {
	    tempah >>= 3;
	    tempah &= 0x18;
	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
	    /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
	 } else {
	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
	 }
      } else {
	 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
      }

   } else if(SiS_Pr->SiS_VBType & VB_SISVB) {

      if(SiS_Pr->ChipType < SIS_315H) {

#ifdef CONFIG_FB_SIS_300  /* ---- 300 series --- */

	 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {			/* 630 - 301B(-DH) */

	    tempah = infoflag >> 8;
	    tempbl = 0;
	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
		  tempah = SiS_Pr->SiS_LCDInfo;
		  tempbl = (tempah >> 6) & 0x03;
	       }
	    }
	    tempah &= 0xC0;
	    tempah |= 0x20;
	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
	    tempah |= 0xc0;
	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
	    if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
	    }

	 } else {							/* 630 - 301 */

	    tempah = ((infoflag >> 8) & 0xc0) | 0x20;
	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);

	 }

#endif /* CONFIG_FB_SIS_300 */

      } else {

#ifdef CONFIG_FB_SIS_315  /* ------- 315 series ------ */

	 if(SiS_Pr->SiS_VBType & VB_SISLVDS) {	  		/* 315 - LVDS */

	    tempbl = 0;
	    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
	       (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
	       tempah = infoflag >> 8;
	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
		 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
	       }
	    } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400)  &&
		      (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
	       tempah = infoflag >> 8;
	       tempbl = 0x03;
	    } else {
	       tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
	       tempbl = (tempah >> 6) & 0x03;
	       tempbl |= 0x08;
	       if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
	    }
	    tempah &= 0xC0;
	    tempah |= 0x20;
	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)   tempah |= 0xc0;
	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
	    if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
		  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
	       }
	    }

	 } else {							/* 315 - TMDS */

	    tempah = tempbl = infoflag >> 8;
	    if(!SiS_Pr->UseCustomMode) {
	       tempbl = 0;
	       if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
		  if(ModeNo <= 0x13) {
		     tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
		  }
	       }
	       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
		  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
		    if(SiS_Pr->SiS_LCDInfo & LCDSync) {
		       tempah = SiS_Pr->SiS_LCDInfo;
		       tempbl = (tempah >> 6) & 0x03;
		    }
		  }
	       }
	    }
	    tempah &= 0xC0;
	    tempah |= 0x20;
	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {
	       /* Imitate BIOS bug */
	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)  tempah |= 0xc0;
	    }
	    if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
	       tempah >>= 3;
	       tempah &= 0x18;
	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
	    } else {
	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
	       if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
		  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
		     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
		  }
	       }
	    }

         }
#endif  /* CONFIG_FB_SIS_315 */
      }
   }
}

/* Set CRT2 FIFO on 300/540/630/730 */
#ifdef CONFIG_FB_SIS_300
static void
SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
{
  unsigned char  *ROMAddr  = SiS_Pr->VirtualRomBase;
  unsigned short temp, index, modeidindex, refreshratetableindex;
  unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0;
  unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup;
  unsigned int   data, pci50, pciA0;
  static const unsigned char colortharray[] = {
  	1, 1, 2, 2, 3, 4
  };

  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;

  if(!SiS_Pr->CRT1UsesCustomMode) {

     CRT1ModeNo = SiS_Pr