11381 lines
351 KiB
C
11381 lines
351 KiB
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) */
|
|
|
|
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 |