Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/video/fbdev/sis/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 351 kB image not shown  

Quelle  init301.c   Sprache: C

 
/* $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) */
#ifdef CONFIG_FB_SIS_315
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,
};

/* 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 shortunsigned 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:
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=93 H=98 G=95

¤ Dauer der Verarbeitung: 0.22 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.