init301.c (359653B)
1/* $XFree86$ */ 2/* $XdotOrg$ */ 3/* 4 * Mode initializing code (CRT2 section) 5 * for SiS 300/305/540/630/730, 6 * SiS 315/550/[M]650/651/[M]661[FGM]X/[M]74x[GX]/330/[M]76x[GX], 7 * XGI V3XT/V5/V8, Z7 8 * (Universal module for Linux kernel framebuffer and X.org/XFree86 4.x) 9 * 10 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 11 * 12 * If distributed as part of the Linux kernel, the following license terms 13 * apply: 14 * 15 * * This program is free software; you can redistribute it and/or modify 16 * * it under the terms of the GNU General Public License as published by 17 * * the Free Software Foundation; either version 2 of the named License, 18 * * or any later version. 19 * * 20 * * This program is distributed in the hope that it will be useful, 21 * * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * * GNU General Public License for more details. 24 * * 25 * * You should have received a copy of the GNU General Public License 26 * * along with this program; if not, write to the Free Software 27 * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA 28 * 29 * Otherwise, the following license terms apply: 30 * 31 * * Redistribution and use in source and binary forms, with or without 32 * * modification, are permitted provided that the following conditions 33 * * are met: 34 * * 1) Redistributions of source code must retain the above copyright 35 * * notice, this list of conditions and the following disclaimer. 36 * * 2) Redistributions in binary form must reproduce the above copyright 37 * * notice, this list of conditions and the following disclaimer in the 38 * * documentation and/or other materials provided with the distribution. 39 * * 3) The name of the author may not be used to endorse or promote products 40 * * derived from this software without specific prior written permission. 41 * * 42 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 43 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 44 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 46 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 48 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 49 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 50 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 51 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 * 53 * Author: Thomas Winischhofer <thomas@winischhofer.net> 54 * 55 * Formerly based on non-functional code-fragements for 300 series by SiS, Inc. 56 * Used by permission. 57 * 58 */ 59 60#if 1 61#define SET_EMI /* 302LV/ELV: Set EMI values */ 62#endif 63 64#if 1 65#define SET_PWD /* 301/302LV: Set PWD */ 66#endif 67 68#define COMPAL_HACK /* Needed for Compal 1400x1050 (EMI) */ 69#define COMPAQ_HACK /* Needed for Inventec/Compaq 1280x1024 (EMI) */ 70#define ASUS_HACK /* Needed for Asus A2H 1024x768 (EMI) */ 71 72#include "init301.h" 73 74#ifdef CONFIG_FB_SIS_300 75#include "oem300.h" 76#endif 77 78#ifdef CONFIG_FB_SIS_315 79#include "oem310.h" 80#endif 81 82#define SiS_I2CDELAY 1000 83#define SiS_I2CDELAYSHORT 150 84 85static const unsigned char SiS_YPbPrTable[3][64] = { 86 { 87 0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c, 88 0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a, 89 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b, 90 0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17, 91 0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02, 92 0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40, 93 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/, 94 0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00 95 }, 96 { 97 0x33,0x06,0x06,0x09,0x0b,0x0c,0x0c,0x0c, 98 0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a, 99 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f, 100 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13, 101 0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8, 102 0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40, 103 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4e, 104 0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00 105 }, 106 { 107#if 0 /* OK, but sticks to left edge */ 108 0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c, 109 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a, 110 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f, 111 0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13, 112 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0, 113 0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40, 114 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27, 115 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00 116#endif 117#if 1 /* Perfect */ 118 0x23,0x2d,0xe8,0x09,0x09,0xed,0x0c,0x0c, 119 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a, 120 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f, 121 0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13, 122 0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0, 123 0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40, 124 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x73, 125 0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00 126#endif 127 } 128}; 129 130static const unsigned char SiS_TVPhase[] = 131{ 132 0x21,0xED,0xBA,0x08, /* 0x00 SiS_NTSCPhase */ 133 0x2A,0x05,0xE3,0x00, /* 0x01 SiS_PALPhase */ 134 0x21,0xE4,0x2E,0x9B, /* 0x02 SiS_PALMPhase */ 135 0x21,0xF4,0x3E,0xBA, /* 0x03 SiS_PALNPhase */ 136 0x1E,0x8B,0xA2,0xA7, 137 0x1E,0x83,0x0A,0xE0, /* 0x05 SiS_SpecialPhaseM */ 138 0x00,0x00,0x00,0x00, 139 0x00,0x00,0x00,0x00, 140 0x21,0xF0,0x7B,0xD6, /* 0x08 SiS_NTSCPhase2 */ 141 0x2A,0x09,0x86,0xE9, /* 0x09 SiS_PALPhase2 */ 142 0x21,0xE6,0xEF,0xA4, /* 0x0a SiS_PALMPhase2 */ 143 0x21,0xF6,0x94,0x46, /* 0x0b SiS_PALNPhase2 */ 144 0x1E,0x8B,0xA2,0xA7, 145 0x1E,0x83,0x0A,0xE0, /* 0x0d SiS_SpecialPhaseM */ 146 0x00,0x00,0x00,0x00, 147 0x00,0x00,0x00,0x00, 148 0x1e,0x8c,0x5c,0x7a, /* 0x10 SiS_SpecialPhase */ 149 0x25,0xd4,0xfd,0x5e /* 0x11 SiS_SpecialPhaseJ */ 150}; 151 152static const unsigned char SiS_HiTVGroup3_1[] = { 153 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13, 154 0xb1, 0x41, 0x62, 0x62, 0xff, 0xf4, 0x45, 0xa6, 155 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20, 156 0xac, 0xda, 0x60, 0xfe, 0x6a, 0x9a, 0x06, 0x10, 157 0xd1, 0x04, 0x18, 0x0a, 0xff, 0x80, 0x00, 0x80, 158 0x3b, 0x77, 0x00, 0xef, 0xe0, 0x10, 0xb0, 0xe0, 159 0x10, 0x4f, 0x0f, 0x0f, 0x05, 0x0f, 0x08, 0x6e, 160 0x1a, 0x1f, 0x25, 0x2a, 0x4c, 0xaa, 0x01 161}; 162 163static const unsigned char SiS_HiTVGroup3_2[] = { 164 0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a, 165 0x54, 0x41, 0xe7, 0xe7, 0xff, 0xf4, 0x45, 0xa6, 166 0x25, 0x2f, 0x67, 0xf6, 0xbf, 0xff, 0x8e, 0x20, 167 0xac, 0x6a, 0x60, 0x2b, 0x52, 0xcd, 0x61, 0x10, 168 0x51, 0x04, 0x18, 0x0a, 0x1f, 0x80, 0x00, 0x80, 169 0xff, 0xa4, 0x04, 0x2b, 0x94, 0x21, 0x72, 0x94, 170 0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64, 171 0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01 172}; 173 174/* 301C / 302ELV extended Part2 TV registers (4 tap scaler) */ 175 176static const unsigned char SiS_Part2CLVX_1[] = { 177 0x00,0x00, 178 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, 179 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, 180 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, 181 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E 182}; 183 184static const unsigned char SiS_Part2CLVX_2[] = { 185 0x00,0x00, 186 0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F,0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, 187 0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E,0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, 188 0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C,0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, 189 0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C,0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E 190}; 191 192static const unsigned char SiS_Part2CLVX_3[] = { /* NTSC, 525i, 525p */ 193 0xE0,0x01, 194 0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D,0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, 195 0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C,0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, 196 0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E, 197 0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00,0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02, 198 0x58,0x02, 199 0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D,0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E, 200 0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F,0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F, 201 0x00,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01,0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03, 202 0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04,0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06, 203 0x00,0x03, 204 0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00,0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01, 205 0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02,0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03, 206 0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05,0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06, 207 0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07,0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08, 208 0xFF,0xFF 209}; 210 211static const unsigned char SiS_Part2CLVX_4[] = { /* PAL */ 212 0x58,0x02, 213 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, 214 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, 215 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E, 216 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04, 217 0x00,0x03, 218 0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E,0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F, 219 0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00,0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01, 220 0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02,0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04, 221 0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05,0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07, 222 0x40,0x02, 223 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D, 224 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C, 225 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F, 226 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02, 227 0xFF,0xFF 228}; 229 230static const unsigned char SiS_Part2CLVX_5[] = { /* 750p */ 231 0x00,0x03, 232 0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E,0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, 233 0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C,0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, 234 0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E,0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E, 235 0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01,0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04, 236 0xFF,0xFF 237}; 238 239static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */ 240 0x00,0x04, 241 0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D, 242 0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C, 243 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F, 244 0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02, 245 0xFF,0xFF, 246}; 247 248#ifdef CONFIG_FB_SIS_315 249/* 661 et al LCD data structure (2.03.00) */ 250static const unsigned char SiS_LCDStruct661[] = { 251 /* 1024x768 */ 252/* type|CR37| HDE | VDE | HT | VT | hss | hse */ 253 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88, 254 0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04, 255 /* | vss | vse |clck| clock |CRT2DataP|CRT2DataP|idx */ 256 /* VESA non-VESA noscale */ 257 /* 1280x1024 */ 258 0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70, 259 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08, 260 /* 1400x1050 */ 261 0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38, 262 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09, 263 /* 1600x1200 */ 264 0x0B,0xE0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0, 265 0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0A, 266 /* 1280x768 (_2) */ 267 0x0A,0xE0,0x00,0x05,0x00,0x03,0x7C,0x06,0x26,0x03,0x30,0x00,0x70, 268 0x00,0x03,0x00,0x06,0x00,0x4D,0xC8,0x48,0x00,0x00,0x00,0x00,0x06, 269 /* 1280x720 */ 270 0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x20, 271 0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05, 272 /* 1280x800 (_2) */ 273 0x0C,0xE0,0x00,0x05,0x20,0x03,0x10,0x06,0x2C,0x03,0x30,0x00,0x70, 274 0x00,0x04,0x00,0x03,0x00,0x49,0xCE,0x1E,0x00,0x00,0x00,0x00,0x09, 275 /* 1680x1050 */ 276 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C, 277 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06, 278 /* 1280x800_3 */ 279 0x0C,0xE0,0x00,0x05,0x20,0x03,0xAA,0x05,0x2E,0x03,0x30,0x00,0x50, 280 0x00,0x04,0x00,0x03,0x00,0x47,0xA9,0x10,0x00,0x00,0x00,0x00,0x07, 281 /* 800x600 */ 282 0x01,0xC0,0x20,0x03,0x58,0x02,0x20,0x04,0x74,0x02,0x2A,0x00,0x80, 283 0x00,0x06,0x00,0x04,0x00,0x28,0x63,0x4B,0x00,0x00,0x00,0x00,0x00, 284 /* 1280x854 */ 285 0x08,0xE0,0x00,0x05,0x56,0x03,0x80,0x06,0x5d,0x03,0x10,0x00,0x70, 286 0x00,0x01,0x00,0x03,0x00,0x54,0x75,0x13,0x00,0x00,0x00,0x00,0x08 287}; 288#endif 289 290#ifdef CONFIG_FB_SIS_300 291static unsigned char SiS300_TrumpionData[14][80] = { 292 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, 293 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23, 294 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23, 295 0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05, 296 0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 }, 297 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02, 298 0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23, 299 0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23, 300 0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05, 301 0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 }, 302 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02, 303 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23, 304 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23, 305 0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05, 306 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 }, 307 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02, 308 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23, 309 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23, 310 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05, 311 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 }, 312 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, 313 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23, 314 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23, 315 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05, 316 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }, 317 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03, 318 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D, 319 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D, 320 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B, 321 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }, 322 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04, 323 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23, 324 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23, 325 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01, 326 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }, 327 /* variant 2 */ 328 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, 329 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23, 330 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23, 331 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05, 332 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 }, 333 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, 334 0x20,0x03,0x15,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x18,0x00,0x00,0x04,0x23, 335 0x00,0x01,0x03,0x44,0x03,0x28,0x06,0x08,0x40,0x18,0x00,0x18,0x04,0x23,0x00,0x23, 336 0x03,0x11,0x60,0xA6,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x13,0x04,0x04,0x05, 337 0x04,0x0C,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 }, 338 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02, 339 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23, 340 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23, 341 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05, 342 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 }, 343 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02, 344 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23, 345 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23, 346 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05, 347 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 }, 348 { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02, 349 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23, 350 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23, 351 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05, 352 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }, 353 { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03, 354 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D, 355 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D, 356 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B, 357 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 }, 358 { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x11,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04, 359 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23, 360 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23, 361 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01, 362 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEA,0x58,0x01,0xBE,0x01,0x00 } 363}; 364#endif 365 366#ifdef CONFIG_FB_SIS_315 367static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr); 368static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr); 369static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr); 370static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr); 371#endif /* 315 */ 372 373#ifdef CONFIG_FB_SIS_300 374static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr); 375#endif 376 377static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, 378 int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype, 379 bool checkcr32, unsigned int VBFlags2); 380static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr); 381static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, 382 unsigned char *buffer); 383static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr); 384static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr); 385static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr); 386static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr); 387static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr); 388static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr); 389static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax); 390static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr); 391static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr); 392static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr); 393static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr); 394static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno); 395static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr); 396 397#ifdef CONFIG_FB_SIS_300 398static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr, 399 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex); 400static void SetOEMLCDData2(struct SiS_Private *SiS_Pr, 401 unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex); 402#endif 403#ifdef CONFIG_FB_SIS_315 404static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr, 405 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI); 406static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr, 407 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI); 408static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short); 409#endif 410 411static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr); 412static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); 413 414/*********************************************/ 415/* HELPER: Lock/Unlock CRT2 */ 416/*********************************************/ 417 418void 419SiS_UnLockCRT2(struct SiS_Private *SiS_Pr) 420{ 421 if(SiS_Pr->ChipType == XGI_20) 422 return; 423 else if(SiS_Pr->ChipType >= SIS_315H) 424 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01); 425 else 426 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); 427} 428 429static 430void 431SiS_LockCRT2(struct SiS_Private *SiS_Pr) 432{ 433 if(SiS_Pr->ChipType == XGI_20) 434 return; 435 else if(SiS_Pr->ChipType >= SIS_315H) 436 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE); 437 else 438 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE); 439} 440 441/*********************************************/ 442/* HELPER: Write SR11 */ 443/*********************************************/ 444 445static void 446SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned short DataOR) 447{ 448 if(SiS_Pr->ChipType >= SIS_661) { 449 DataAND &= 0x0f; 450 DataOR &= 0x0f; 451 } 452 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR); 453} 454 455/*********************************************/ 456/* HELPER: Get Pointer to LCD structure */ 457/*********************************************/ 458 459#ifdef CONFIG_FB_SIS_315 460static unsigned char * 461GetLCDStructPtr661(struct SiS_Private *SiS_Pr) 462{ 463 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 464 unsigned char *myptr = NULL; 465 unsigned short romindex = 0, reg = 0, idx = 0; 466 467 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable 468 * due to the variaty of panels the BIOS doesn't know about. 469 * Exception: If the BIOS has better knowledge (such as in case 470 * of machines with a 301C and a panel that does not support DDC) 471 * use the BIOS data as well. 472 */ 473 474 if((SiS_Pr->SiS_ROMNew) && 475 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) { 476 477 if(SiS_Pr->ChipType < SIS_661) reg = 0x3c; 478 else reg = 0x7d; 479 480 idx = (SiS_GetReg(SiS_Pr->SiS_P3d4,reg) & 0x1f) * 26; 481 482 if(idx < (8*26)) { 483 myptr = (unsigned char *)&SiS_LCDStruct661[idx]; 484 } 485 romindex = SISGETROMW(0x100); 486 if(romindex) { 487 romindex += idx; 488 myptr = &ROMAddr[romindex]; 489 } 490 } 491 return myptr; 492} 493 494static unsigned short 495GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr) 496{ 497 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 498 unsigned short romptr = 0; 499 500 /* Use the BIOS tables only for LVDS panels; TMDS is unreliable 501 * due to the variaty of panels the BIOS doesn't know about. 502 * Exception: If the BIOS has better knowledge (such as in case 503 * of machines with a 301C and a panel that does not support DDC) 504 * use the BIOS data as well. 505 */ 506 507 if((SiS_Pr->SiS_ROMNew) && 508 ((SiS_Pr->SiS_VBType & VB_SISLVDS) || (!SiS_Pr->PanelSelfDetected))) { 509 romptr = SISGETROMW(0x102); 510 romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize); 511 } 512 513 return romptr; 514} 515#endif 516 517/*********************************************/ 518/* Adjust Rate for CRT2 */ 519/*********************************************/ 520 521static bool 522SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 523 unsigned short RRTI, unsigned short *i) 524{ 525 unsigned short checkmask=0, modeid, infoflag; 526 527 modeid = SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID; 528 529 if(SiS_Pr->SiS_VBType & VB_SISVB) { 530 531 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 532 533 checkmask |= SupportRAMDAC2; 534 if(SiS_Pr->ChipType >= SIS_315H) { 535 checkmask |= SupportRAMDAC2_135; 536 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 537 checkmask |= SupportRAMDAC2_162; 538 if(SiS_Pr->SiS_VBType & VB_SISRAMDAC202) { 539 checkmask |= SupportRAMDAC2_202; 540 } 541 } 542 } 543 544 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 545 546 checkmask |= SupportLCD; 547 if(SiS_Pr->ChipType >= SIS_315H) { 548 if(SiS_Pr->SiS_VBType & VB_SISVB) { 549 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 550 if(modeid == 0x2e) checkmask |= Support64048060Hz; 551 } 552 } 553 } 554 555 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 556 557 checkmask |= SupportHiVision; 558 559 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) { 560 561 checkmask |= SupportTV; 562 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 563 checkmask |= SupportTV1024; 564 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 565 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 566 checkmask |= SupportYPbPr750p; 567 } 568 } 569 } 570 571 } 572 573 } else { /* LVDS */ 574 575 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 576 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 577 checkmask |= SupportCHTV; 578 } 579 } 580 581 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 582 checkmask |= SupportLCD; 583 } 584 585 } 586 587 /* Look backwards in table for matching CRT2 mode */ 588 for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) { 589 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag; 590 if(infoflag & checkmask) return true; 591 if((*i) == 0) break; 592 } 593 594 /* Look through the whole mode-section of the table from the beginning 595 * for a matching CRT2 mode if no mode was found yet. 596 */ 597 for((*i) = 0; ; (*i)++) { 598 if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break; 599 infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag; 600 if(infoflag & checkmask) return true; 601 } 602 return false; 603} 604 605/*********************************************/ 606/* Get rate index */ 607/*********************************************/ 608 609unsigned short 610SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 611{ 612 unsigned short RRTI,i,backup_i; 613 unsigned short modeflag,index,temp,backupindex; 614 static const unsigned short LCDRefreshIndex[] = { 615 0x00, 0x00, 0x01, 0x01, 616 0x01, 0x01, 0x01, 0x01, 617 0x01, 0x01, 0x01, 0x01, 618 0x01, 0x01, 0x01, 0x01, 619 0x00, 0x00, 0x00, 0x00 620 }; 621 622 /* Do NOT check for UseCustomMode here, will skrew up FIFO */ 623 if(ModeNo == 0xfe) return 0; 624 625 if(ModeNo <= 0x13) { 626 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 627 } else { 628 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 629 } 630 631 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 632 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 633 if(modeflag & HalfDCLK) return 0; 634 } 635 } 636 637 if(ModeNo < 0x14) return 0xFFFF; 638 639 index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F; 640 backupindex = index; 641 642 if(index > 0) index--; 643 644 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 645 if(SiS_Pr->SiS_VBType & VB_SISVB) { 646 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 647 if(SiS_Pr->SiS_VBType & VB_NoLCD) index = 0; 648 else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index = backupindex = 0; 649 } 650 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 651 if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) { 652 temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)]; 653 if(index > temp) index = temp; 654 } 655 } 656 } else { 657 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) index = 0; 658 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 659 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) index = 0; 660 } 661 } 662 } 663 664 RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; 665 ModeNo = SiS_Pr->SiS_RefIndex[RRTI].ModeID; 666 667 if(SiS_Pr->ChipType >= SIS_315H) { 668 if(!(SiS_Pr->SiS_VBInfo & DriverMode)) { 669 if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) || 670 (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) { 671 if(backupindex <= 1) RRTI++; 672 } 673 } 674 } 675 676 i = 0; 677 do { 678 if(SiS_Pr->SiS_RefIndex[RRTI + i].ModeID != ModeNo) break; 679 temp = SiS_Pr->SiS_RefIndex[RRTI + i].Ext_InfoFlag; 680 temp &= ModeTypeMask; 681 if(temp < SiS_Pr->SiS_ModeType) break; 682 i++; 683 index--; 684 } while(index != 0xFFFF); 685 686 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 687 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 688 temp = SiS_Pr->SiS_RefIndex[RRTI + i - 1].Ext_InfoFlag; 689 if(temp & InterlaceMode) i++; 690 } 691 } 692 693 i--; 694 695 if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) { 696 backup_i = i; 697 if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RRTI, &i))) { 698 i = backup_i; 699 } 700 } 701 702 return (RRTI + i); 703} 704 705/*********************************************/ 706/* STORE CRT2 INFO in CR34 */ 707/*********************************************/ 708 709static void 710SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 711{ 712 unsigned short temp1, temp2; 713 714 /* Store CRT1 ModeNo in CR34 */ 715 SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo); 716 temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8; 717 temp2 = ~(SetInSlaveMode >> 8); 718 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1); 719} 720 721/*********************************************/ 722/* HELPER: GET SOME DATA FROM BIOS ROM */ 723/*********************************************/ 724 725#ifdef CONFIG_FB_SIS_300 726static bool 727SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr) 728{ 729 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 730 unsigned short temp,temp1; 731 732 if(SiS_Pr->SiS_UseROM) { 733 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 734 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f); 735 temp1 = SISGETROMW(0x23b); 736 if(temp1 & temp) return true; 737 } 738 } 739 return false; 740} 741 742static bool 743SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr) 744{ 745 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 746 unsigned short temp,temp1; 747 748 if(SiS_Pr->SiS_UseROM) { 749 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 750 temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f); 751 temp1 = SISGETROMW(0x23d); 752 if(temp1 & temp) return true; 753 } 754 } 755 return false; 756} 757#endif 758 759/*********************************************/ 760/* HELPER: DELAY FUNCTIONS */ 761/*********************************************/ 762 763void 764SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime) 765{ 766 while (delaytime-- > 0) 767 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05); 768} 769 770#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 771static void 772SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay) 773{ 774 SiS_DDC2Delay(SiS_Pr, delay * 36); 775} 776#endif 777 778#ifdef CONFIG_FB_SIS_315 779static void 780SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay) 781{ 782 while(delay--) { 783 SiS_GenericDelay(SiS_Pr, 6623); 784 } 785} 786#endif 787 788#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 789static void 790SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay) 791{ 792 while(delay--) { 793 SiS_GenericDelay(SiS_Pr, 66); 794 } 795} 796#endif 797 798static void 799SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime) 800{ 801#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 802 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 803 unsigned short PanelID, DelayIndex, Delay=0; 804#endif 805 806 if(SiS_Pr->ChipType < SIS_315H) { 807 808#ifdef CONFIG_FB_SIS_300 809 810 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 811 if(SiS_Pr->SiS_VBType & VB_SISVB) { 812 if(SiS_Pr->SiS_VBType & VB_SIS301) PanelID &= 0xf7; 813 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x18) & 0x10)) PanelID = 0x12; 814 } 815 DelayIndex = PanelID >> 4; 816 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { 817 Delay = 3; 818 } else { 819 if(DelayTime >= 2) DelayTime -= 2; 820 if(!(DelayTime & 0x01)) { 821 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; 822 } else { 823 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; 824 } 825 if(SiS_Pr->SiS_UseROM) { 826 if(ROMAddr[0x220] & 0x40) { 827 if(!(DelayTime & 0x01)) Delay = (unsigned short)ROMAddr[0x225]; 828 else Delay = (unsigned short)ROMAddr[0x226]; 829 } 830 } 831 } 832 SiS_ShortDelay(SiS_Pr, Delay); 833 834#endif /* CONFIG_FB_SIS_300 */ 835 836 } else { 837 838#ifdef CONFIG_FB_SIS_315 839 840 if((SiS_Pr->ChipType >= SIS_661) || 841 (SiS_Pr->ChipType <= SIS_315PRO) || 842 (SiS_Pr->ChipType == SIS_330) || 843 (SiS_Pr->SiS_ROMNew)) { 844 845 if(!(DelayTime & 0x01)) { 846 SiS_DDC2Delay(SiS_Pr, 0x1000); 847 } else { 848 SiS_DDC2Delay(SiS_Pr, 0x4000); 849 } 850 851 } else if (SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 315 series, LVDS; Special */ 852 853 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 854 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 855 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) { 856 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12; 857 } 858 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 859 DelayIndex = PanelID & 0x0f; 860 } else { 861 DelayIndex = PanelID >> 4; 862 } 863 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { 864 Delay = 3; 865 } else { 866 if(DelayTime >= 2) DelayTime -= 2; 867 if(!(DelayTime & 0x01)) { 868 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0]; 869 } else { 870 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1]; 871 } 872 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 873 if(ROMAddr[0x13c] & 0x40) { 874 if(!(DelayTime & 0x01)) { 875 Delay = (unsigned short)ROMAddr[0x17e]; 876 } else { 877 Delay = (unsigned short)ROMAddr[0x17f]; 878 } 879 } 880 } 881 } 882 SiS_ShortDelay(SiS_Pr, Delay); 883 } 884 885 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */ 886 887 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 888 if(!(DelayTime & 0x01)) { 889 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; 890 } else { 891 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; 892 } 893 Delay <<= 8; 894 SiS_DDC2Delay(SiS_Pr, Delay); 895 896 } 897 898#endif /* CONFIG_FB_SIS_315 */ 899 900 } 901} 902 903#ifdef CONFIG_FB_SIS_315 904static void 905SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop) 906{ 907 int i; 908 for(i = 0; i < DelayLoop; i++) { 909 SiS_PanelDelay(SiS_Pr, DelayTime); 910 } 911} 912#endif 913 914/*********************************************/ 915/* HELPER: WAIT-FOR-RETRACE FUNCTIONS */ 916/*********************************************/ 917 918void 919SiS_WaitRetrace1(struct SiS_Private *SiS_Pr) 920{ 921 unsigned short watchdog; 922 923 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return; 924 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return; 925 926 watchdog = 65535; 927 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog); 928 watchdog = 65535; 929 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); 930} 931 932#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 933static void 934SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg) 935{ 936 unsigned short watchdog; 937 938 watchdog = 65535; 939 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog); 940 watchdog = 65535; 941 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog); 942} 943#endif 944 945static void 946SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr) 947{ 948 if(SiS_Pr->ChipType < SIS_315H) { 949#ifdef CONFIG_FB_SIS_300 950 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 951 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return; 952 } 953 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) { 954 SiS_WaitRetrace1(SiS_Pr); 955 } else { 956 SiS_WaitRetrace2(SiS_Pr, 0x25); 957 } 958#endif 959 } else { 960#ifdef CONFIG_FB_SIS_315 961 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) { 962 SiS_WaitRetrace1(SiS_Pr); 963 } else { 964 SiS_WaitRetrace2(SiS_Pr, 0x30); 965 } 966#endif 967 } 968} 969 970static void 971SiS_VBWait(struct SiS_Private *SiS_Pr) 972{ 973 unsigned short tempal,temp,i,j; 974 975 temp = 0; 976 for(i = 0; i < 3; i++) { 977 for(j = 0; j < 100; j++) { 978 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da); 979 if(temp & 0x01) { 980 if((tempal & 0x08)) continue; 981 else break; 982 } else { 983 if(!(tempal & 0x08)) continue; 984 else break; 985 } 986 } 987 temp ^= 0x01; 988 } 989} 990 991static void 992SiS_VBLongWait(struct SiS_Private *SiS_Pr) 993{ 994 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 995 SiS_VBWait(SiS_Pr); 996 } else { 997 SiS_WaitRetrace1(SiS_Pr); 998 } 999} 1000 1001/*********************************************/ 1002/* HELPER: MISC */ 1003/*********************************************/ 1004 1005#ifdef CONFIG_FB_SIS_300 1006static bool 1007SiS_Is301B(struct SiS_Private *SiS_Pr) 1008{ 1009 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true; 1010 return false; 1011} 1012#endif 1013 1014static bool 1015SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr) 1016{ 1017 if(SiS_Pr->ChipType == SIS_730) { 1018 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true; 1019 } 1020 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true; 1021 return false; 1022} 1023 1024bool 1025SiS_IsDualEdge(struct SiS_Private *SiS_Pr) 1026{ 1027#ifdef CONFIG_FB_SIS_315 1028 if(SiS_Pr->ChipType >= SIS_315H) { 1029 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) { 1030 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true; 1031 } 1032 } 1033#endif 1034 return false; 1035} 1036 1037bool 1038SiS_IsVAMode(struct SiS_Private *SiS_Pr) 1039{ 1040#ifdef CONFIG_FB_SIS_315 1041 unsigned short flag; 1042 1043 if(SiS_Pr->ChipType >= SIS_315H) { 1044 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1045 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true; 1046 } 1047#endif 1048 return false; 1049} 1050 1051#ifdef CONFIG_FB_SIS_315 1052static bool 1053SiS_IsVAorLCD(struct SiS_Private *SiS_Pr) 1054{ 1055 if(SiS_IsVAMode(SiS_Pr)) return true; 1056 if(SiS_CRT2IsLCD(SiS_Pr)) return true; 1057 return false; 1058} 1059#endif 1060 1061static bool 1062SiS_IsDualLink(struct SiS_Private *SiS_Pr) 1063{ 1064#ifdef CONFIG_FB_SIS_315 1065 if(SiS_Pr->ChipType >= SIS_315H) { 1066 if((SiS_CRT2IsLCD(SiS_Pr)) || 1067 (SiS_IsVAMode(SiS_Pr))) { 1068 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true; 1069 } 1070 } 1071#endif 1072 return false; 1073} 1074 1075#ifdef CONFIG_FB_SIS_315 1076static bool 1077SiS_TVEnabled(struct SiS_Private *SiS_Pr) 1078{ 1079 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true; 1080 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1081 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true; 1082 } 1083 return false; 1084} 1085#endif 1086 1087#ifdef CONFIG_FB_SIS_315 1088static bool 1089SiS_LCDAEnabled(struct SiS_Private *SiS_Pr) 1090{ 1091 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true; 1092 return false; 1093} 1094#endif 1095 1096#ifdef CONFIG_FB_SIS_315 1097static bool 1098SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr) 1099{ 1100 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) { 1101 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true; 1102 } 1103 return false; 1104} 1105#endif 1106 1107#ifdef CONFIG_FB_SIS_315 1108static bool 1109SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr) 1110{ 1111 unsigned short flag; 1112 1113 if(SiS_Pr->ChipType == SIS_650) { 1114 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0; 1115 /* Check for revision != A0 only */ 1116 if((flag == 0xe0) || (flag == 0xc0) || 1117 (flag == 0xb0) || (flag == 0x90)) return false; 1118 } else if(SiS_Pr->ChipType >= SIS_661) return false; 1119 return true; 1120} 1121#endif 1122 1123#ifdef CONFIG_FB_SIS_315 1124static bool 1125SiS_IsYPbPr(struct SiS_Private *SiS_Pr) 1126{ 1127 if(SiS_Pr->ChipType >= SIS_315H) { 1128 /* YPrPb = 0x08 */ 1129 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true; 1130 } 1131 return false; 1132} 1133#endif 1134 1135#ifdef CONFIG_FB_SIS_315 1136static bool 1137SiS_IsChScart(struct SiS_Private *SiS_Pr) 1138{ 1139 if(SiS_Pr->ChipType >= SIS_315H) { 1140 /* Scart = 0x04 */ 1141 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true; 1142 } 1143 return false; 1144} 1145#endif 1146 1147#ifdef CONFIG_FB_SIS_315 1148static bool 1149SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr) 1150{ 1151 unsigned short flag; 1152 1153 if(SiS_Pr->ChipType >= SIS_315H) { 1154 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1155 if(flag & SetCRT2ToTV) return true; 1156 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1157 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */ 1158 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */ 1159 } else { 1160 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1161 if(flag & SetCRT2ToTV) return true; 1162 } 1163 return false; 1164} 1165#endif 1166 1167#ifdef CONFIG_FB_SIS_315 1168static bool 1169SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr) 1170{ 1171 unsigned short flag; 1172 1173 if(SiS_Pr->ChipType >= SIS_315H) { 1174 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1175 if(flag & SetCRT2ToLCD) return true; 1176 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1177 if(flag & SetToLCDA) return true; 1178 } else { 1179 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1180 if(flag & SetCRT2ToLCD) return true; 1181 } 1182 return false; 1183} 1184#endif 1185 1186static bool 1187SiS_HaveBridge(struct SiS_Private *SiS_Pr) 1188{ 1189 unsigned short flag; 1190 1191 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1192 return true; 1193 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 1194 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 1195 if((flag == 1) || (flag == 2)) return true; 1196 } 1197 return false; 1198} 1199 1200static bool 1201SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr) 1202{ 1203 unsigned short flag; 1204 1205 if(SiS_HaveBridge(SiS_Pr)) { 1206 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 1207 if(SiS_Pr->ChipType < SIS_315H) { 1208 flag &= 0xa0; 1209 if((flag == 0x80) || (flag == 0x20)) return true; 1210 } else { 1211 flag &= 0x50; 1212 if((flag == 0x40) || (flag == 0x10)) return true; 1213 } 1214 } 1215 return false; 1216} 1217 1218static bool 1219SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr) 1220{ 1221 unsigned short flag1; 1222 1223 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); 1224 if(flag1 & (SetInSlaveMode >> 8)) return true; 1225 return false; 1226} 1227 1228/*********************************************/ 1229/* GET VIDEO BRIDGE CONFIG INFO */ 1230/*********************************************/ 1231 1232/* Setup general purpose IO for Chrontel communication */ 1233#ifdef CONFIG_FB_SIS_300 1234void 1235SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo) 1236{ 1237 unsigned int acpibase; 1238 unsigned short temp; 1239 1240 if(!(SiS_Pr->SiS_ChSW)) return; 1241 1242 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74); 1243 acpibase &= 0xFFFF; 1244 if(!acpibase) return; 1245 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */ 1246 temp &= 0xFEFF; 1247 SiS_SetRegShort((acpibase + 0x3c), temp); 1248 temp = SiS_GetRegShort((acpibase + 0x3c)); 1249 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */ 1250 temp &= 0xFEFF; 1251 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100; 1252 SiS_SetRegShort((acpibase + 0x3a), temp); 1253 temp = SiS_GetRegShort((acpibase + 0x3a)); 1254} 1255#endif 1256 1257void 1258SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 1259 unsigned short ModeIdIndex, int checkcrt2mode) 1260{ 1261 unsigned short tempax, tempbx, temp; 1262 unsigned short modeflag, resinfo = 0; 1263 1264 SiS_Pr->SiS_SetFlag = 0; 1265 1266 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 1267 1268 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask; 1269 1270 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) { 1271 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1272 } 1273 1274 tempbx = 0; 1275 1276 if(SiS_HaveBridge(SiS_Pr)) { 1277 1278 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1279 tempbx |= temp; 1280 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8; 1281 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV); 1282 tempbx |= tempax; 1283 1284#ifdef CONFIG_FB_SIS_315 1285 if(SiS_Pr->ChipType >= SIS_315H) { 1286 if(SiS_Pr->SiS_VBType & VB_SISLCDA) { 1287 if(ModeNo == 0x03) { 1288 /* Mode 0x03 is never in driver mode */ 1289 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf); 1290 } 1291 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) { 1292 /* Reset LCDA setting if not driver mode */ 1293 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 1294 } 1295 if(IS_SIS650) { 1296 if(SiS_Pr->SiS_UseLCDA) { 1297 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) { 1298 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) { 1299 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); 1300 } 1301 } 1302 } 1303 } 1304 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1305 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) { 1306 tempbx |= SetCRT2ToLCDA; 1307 } 1308 } 1309 1310 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */ 1311 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision); 1312 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) { 1313 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0; 1314 if(temp == 0x60) tempbx |= SetCRT2ToHiVision; 1315 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1316 tempbx |= SetCRT2ToYPbPr525750; 1317 } 1318 } 1319 } 1320 1321 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1322 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1323 if(temp & SetToLCDA) { 1324 tempbx |= SetCRT2ToLCDA; 1325 } 1326 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1327 if(temp & EnableCHYPbPr) { 1328 tempbx |= SetCRT2ToCHYPbPr; 1329 } 1330 } 1331 } 1332 } 1333 1334#endif /* CONFIG_FB_SIS_315 */ 1335 1336 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) { 1337 tempbx &= ~(SetCRT2ToRAMDAC); 1338 } 1339 1340 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1341 temp = SetCRT2ToSVIDEO | 1342 SetCRT2ToAVIDEO | 1343 SetCRT2ToSCART | 1344 SetCRT2ToLCDA | 1345 SetCRT2ToLCD | 1346 SetCRT2ToRAMDAC | 1347 SetCRT2ToHiVision | 1348 SetCRT2ToYPbPr525750; 1349 } else { 1350 if(SiS_Pr->ChipType >= SIS_315H) { 1351 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1352 temp = SetCRT2ToAVIDEO | 1353 SetCRT2ToSVIDEO | 1354 SetCRT2ToSCART | 1355 SetCRT2ToLCDA | 1356 SetCRT2ToLCD | 1357 SetCRT2ToCHYPbPr; 1358 } else { 1359 temp = SetCRT2ToLCDA | 1360 SetCRT2ToLCD; 1361 } 1362 } else { 1363 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1364 temp = SetCRT2ToTV | SetCRT2ToLCD; 1365 } else { 1366 temp = SetCRT2ToLCD; 1367 } 1368 } 1369 } 1370 1371 if(!(tempbx & temp)) { 1372 tempax = DisableCRT2Display; 1373 tempbx = 0; 1374 } 1375 1376 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1377 1378 unsigned short clearmask = ( DriverMode | 1379 DisableCRT2Display | 1380 LoadDACFlag | 1381 SetNotSimuMode | 1382 SetInSlaveMode | 1383 SetPALTV | 1384 SwitchCRT2 | 1385 SetSimuScanMode ); 1386 1387 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA); 1388 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC); 1389 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD); 1390 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART); 1391 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision); 1392 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750); 1393 1394 } else { 1395 1396 if(SiS_Pr->ChipType >= SIS_315H) { 1397 if(tempbx & SetCRT2ToLCDA) { 1398 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode); 1399 } 1400 } 1401 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1402 if(tempbx & SetCRT2ToTV) { 1403 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode); 1404 } 1405 } 1406 if(tempbx & SetCRT2ToLCD) { 1407 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode); 1408 } 1409 if(SiS_Pr->ChipType >= SIS_315H) { 1410 if(tempbx & SetCRT2ToLCDA) { 1411 tempbx |= SetCRT2ToLCD; 1412 } 1413 } 1414 1415 } 1416 1417 if(tempax & DisableCRT2Display) { 1418 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { 1419 tempbx = SetSimuScanMode | DisableCRT2Display; 1420 } 1421 } 1422 1423 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode; 1424 1425 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */ 1426 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 1427 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 1428 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) { 1429 modeflag &= (~CRT2Mode); 1430 } 1431 } 1432 1433 if(!(tempbx & SetSimuScanMode)) { 1434 if(tempbx & SwitchCRT2) { 1435 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { 1436 if(resinfo != SIS_RI_1600x1200) { 1437 tempbx |= SetSimuScanMode; 1438 } 1439 } 1440 } else { 1441 if(SiS_BridgeIsEnabled(SiS_Pr)) { 1442 if(!(tempbx & DriverMode)) { 1443 if(SiS_BridgeInSlavemode(SiS_Pr)) { 1444 tempbx |= SetSimuScanMode; 1445 } 1446 } 1447 } 1448 } 1449 } 1450 1451 if(!(tempbx & DisableCRT2Display)) { 1452 if(tempbx & DriverMode) { 1453 if(tempbx & SetSimuScanMode) { 1454 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { 1455 if(resinfo != SIS_RI_1600x1200) { 1456 tempbx |= SetInSlaveMode; 1457 } 1458 } 1459 } 1460 } else { 1461 tempbx |= SetInSlaveMode; 1462 } 1463 } 1464 1465 } 1466 1467 SiS_Pr->SiS_VBInfo = tempbx; 1468 1469#ifdef CONFIG_FB_SIS_300 1470 if(SiS_Pr->ChipType == SIS_630) { 1471 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo); 1472 } 1473#endif 1474 1475#if 0 1476 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n", 1477 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); 1478#endif 1479} 1480 1481/*********************************************/ 1482/* DETERMINE YPbPr MODE */ 1483/*********************************************/ 1484 1485void 1486SiS_SetYPbPr(struct SiS_Private *SiS_Pr) 1487{ 1488 1489 unsigned char temp; 1490 1491 /* Note: This variable is only used on 30xLV systems. 1492 * CR38 has a different meaning on LVDS/CH7019 systems. 1493 * On 661 and later, these bits moved to CR35. 1494 * 1495 * On 301, 301B, only HiVision 1080i is supported. 1496 * On 30xLV, 301C, only YPbPr 1080i is supported. 1497 */ 1498 1499 SiS_Pr->SiS_YPbPr = 0; 1500 if(SiS_Pr->ChipType >= SIS_661) return; 1501 1502 if(SiS_Pr->SiS_VBType) { 1503 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1504 SiS_Pr->SiS_YPbPr = YPbPrHiVision; 1505 } 1506 } 1507 1508 if(SiS_Pr->ChipType >= SIS_315H) { 1509 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1510 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1511 if(temp & 0x08) { 1512 switch((temp >> 4)) { 1513 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break; 1514 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break; 1515 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break; 1516 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break; 1517 } 1518 } 1519 } 1520 } 1521 1522} 1523 1524/*********************************************/ 1525/* DETERMINE TVMode flag */ 1526/*********************************************/ 1527 1528void 1529SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 1530{ 1531 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 1532 unsigned short temp, temp1, resinfo = 0, romindex = 0; 1533 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect; 1534 1535 SiS_Pr->SiS_TVMode = 0; 1536 1537 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 1538 if(SiS_Pr->UseCustomMode) return; 1539 1540 if(ModeNo > 0x13) { 1541 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1542 } 1543 1544 if(SiS_Pr->ChipType < SIS_661) { 1545 1546 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL; 1547 1548 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1549 temp = 0; 1550 if((SiS_Pr->ChipType == SIS_630) || 1551 (SiS_Pr->ChipType == SIS_730)) { 1552 temp = 0x35; 1553 romindex = 0xfe; 1554 } else if(SiS_Pr->ChipType >= SIS_315H) { 1555 temp = 0x38; 1556 if(SiS_Pr->ChipType < XGI_20) { 1557 romindex = 0xf3; 1558 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b; 1559 } 1560 } 1561 if(temp) { 1562 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 1563 OutputSelect = ROMAddr[romindex]; 1564 if(!(OutputSelect & EnablePALMN)) { 1565 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F); 1566 } 1567 } 1568 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp); 1569 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1570 if(temp1 & EnablePALM) { /* 0x40 */ 1571 SiS_Pr->SiS_TVMode |= TVSetPALM; 1572 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1573 } else if(temp1 & EnablePALN) { /* 0x80 */ 1574 SiS_Pr->SiS_TVMode |= TVSetPALN; 1575 } 1576 } else { 1577 if(temp1 & EnableNTSCJ) { /* 0x40 */ 1578 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1579 } 1580 } 1581 } 1582 /* Translate HiVision/YPbPr to our new flags */ 1583 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1584 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1585 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1586 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision; 1587 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1588 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) { 1589 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision; 1590 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750; 1591 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) { 1592 SiS_Pr->SiS_TVMode |= TVSetPAL; 1593 } 1594 } 1595 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1596 if(SiS_Pr->SiS_CHOverScan) { 1597 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 1598 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1599 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) { 1600 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1601 } 1602 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1603 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79); 1604 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) { 1605 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1606 } 1607 } 1608 if(SiS_Pr->SiS_CHSOverScan) { 1609 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1610 } 1611 } 1612 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1613 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1614 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1615 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM; 1616 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN; 1617 } else { 1618 if(temp & EnableNTSCJ) { 1619 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1620 } 1621 } 1622 } 1623 } 1624 1625 } else { /* 661 and later */ 1626 1627 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1628 if(temp1 & 0x01) { 1629 SiS_Pr->SiS_TVMode |= TVSetPAL; 1630 if(temp1 & 0x08) { 1631 SiS_Pr->SiS_TVMode |= TVSetPALN; 1632 } else if(temp1 & 0x04) { 1633 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1634 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1635 } 1636 SiS_Pr->SiS_TVMode |= TVSetPALM; 1637 } 1638 } else { 1639 if(temp1 & 0x02) { 1640 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1641 } 1642 } 1643 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1644 if(SiS_Pr->SiS_CHOverScan) { 1645 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) { 1646 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1647 } 1648 } 1649 } 1650 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1651 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1652 temp1 &= 0xe0; 1653 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1654 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1655 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1656 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1657 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL); 1658 } 1659 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) { 1660 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) { 1661 SiS_Pr->SiS_TVMode |= TVAspect169; 1662 } else { 1663 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39); 1664 if(temp1 & 0x02) { 1665 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) { 1666 SiS_Pr->SiS_TVMode |= TVAspect169; 1667 } else { 1668 SiS_Pr->SiS_TVMode |= TVAspect43LB; 1669 } 1670 } else { 1671 SiS_Pr->SiS_TVMode |= TVAspect43; 1672 } 1673 } 1674 } 1675 } 1676 } 1677 1678 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL; 1679 1680 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1681 1682 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1683 SiS_Pr->SiS_TVMode |= TVSetPAL; 1684 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ); 1685 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1686 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) { 1687 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN); 1688 } 1689 } 1690 1691 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 1692 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 1693 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 1694 } 1695 } 1696 1697 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 1698 if(resinfo == SIS_RI_1024x768) { 1699 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 1700 SiS_Pr->SiS_TVMode |= TVSet525p1024; 1701 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) { 1702 SiS_Pr->SiS_TVMode |= TVSetNTSC1024; 1703 } 1704 } 1705 } 1706 1707 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO; 1708 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && 1709 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 1710 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1711 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) { 1712 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1713 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) { 1714 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 1715 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1716 } 1717 } 1718 1719 } 1720 1721 SiS_Pr->SiS_VBInfo &= ~SetPALTV; 1722} 1723 1724/*********************************************/ 1725/* GET LCD INFO */ 1726/*********************************************/ 1727 1728static unsigned short 1729SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr) 1730{ 1731 unsigned short temp = SiS_Pr->SiS_LCDResInfo; 1732 /* Translate my LCDResInfo to BIOS value */ 1733 switch(temp) { 1734 case Panel_1280x768_2: temp = Panel_1280x768; break; 1735 case Panel_1280x800_2: temp = Panel_1280x800; break; 1736 case Panel_1280x854: temp = Panel661_1280x854; break; 1737 } 1738 return temp; 1739} 1740 1741static void 1742SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) 1743{ 1744#ifdef CONFIG_FB_SIS_315 1745 unsigned char *ROMAddr; 1746 unsigned short temp; 1747 1748 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { 1749 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) { 1750 SiS_Pr->SiS_NeedRomModeData = true; 1751 SiS_Pr->PanelHT = temp; 1752 } 1753 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) { 1754 SiS_Pr->SiS_NeedRomModeData = true; 1755 SiS_Pr->PanelVT = temp; 1756 } 1757 SiS_Pr->PanelHRS = SISGETROMW(10); 1758 SiS_Pr->PanelHRE = SISGETROMW(12); 1759 SiS_Pr->PanelVRS = SISGETROMW(14); 1760 SiS_Pr->PanelVRE = SISGETROMW(16); 1761 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 1762 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK = 1763 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]); 1764 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B = 1765 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19]; 1766 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C = 1767 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20]; 1768 1769 } 1770#endif 1771} 1772 1773static void 1774SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo, 1775 const unsigned char *nonscalingmodes) 1776{ 1777 int i = 0; 1778 while(nonscalingmodes[i] != 0xff) { 1779 if(nonscalingmodes[i++] == resinfo) { 1780 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || 1781 (SiS_Pr->UsePanelScaler == -1)) { 1782 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1783 } 1784 break; 1785 } 1786 } 1787} 1788 1789void 1790SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 1791{ 1792 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0; 1793 bool panelcanscale = false; 1794#ifdef CONFIG_FB_SIS_300 1795 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 1796 static const unsigned char SiS300SeriesLCDRes[] = 1797 { 0, 1, 2, 3, 7, 4, 5, 8, 1798 0, 0, 10, 0, 0, 0, 0, 15 }; 1799#endif 1800#ifdef CONFIG_FB_SIS_315 1801 unsigned char *myptr = NULL; 1802#endif 1803 1804 SiS_Pr->SiS_LCDResInfo = 0; 1805 SiS_Pr->SiS_LCDTypeInfo = 0; 1806 SiS_Pr->SiS_LCDInfo = 0; 1807 SiS_Pr->PanelHRS = 999; /* HSync start */ 1808 SiS_Pr->PanelHRE = 999; /* HSync end */ 1809 SiS_Pr->PanelVRS = 999; /* VSync start */ 1810 SiS_Pr->PanelVRE = 999; /* VSync end */ 1811 SiS_Pr->SiS_NeedRomModeData = false; 1812 1813 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */ 1814 SiS_Pr->Alternate1600x1200 = false; 1815 1816 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return; 1817 1818 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 1819 1820 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) { 1821 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1822 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal; 1823 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal; 1824 } 1825 1826 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 1827 1828 /* For broken BIOSes: Assume 1024x768 */ 1829 if(temp == 0) temp = 0x02; 1830 1831 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 1832 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2; 1833 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) { 1834 SiS_Pr->SiS_LCDTypeInfo = temp >> 4; 1835 } else { 1836 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1; 1837 } 1838 temp &= 0x0f; 1839#ifdef CONFIG_FB_SIS_300 1840 if(SiS_Pr->ChipType < SIS_315H) { 1841 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */ 1842 if(SiS_Pr->SiS_VBType & VB_SIS301) { 1843 if(temp < 0x0f) temp &= 0x07; 1844 } 1845 /* Translate 300 series LCDRes to 315 series for unified usage */ 1846 temp = SiS300SeriesLCDRes[temp]; 1847 } 1848#endif 1849 1850 /* Translate to our internal types */ 1851#ifdef CONFIG_FB_SIS_315 1852 if(SiS_Pr->ChipType == SIS_550) { 1853 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */ 1854 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2; 1855 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3; 1856 } else if(SiS_Pr->ChipType >= SIS_661) { 1857 if(temp == Panel661_1280x854) temp = Panel_1280x854; 1858 } 1859#endif 1860 1861 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */ 1862 if(temp == Panel310_1280x768) { 1863 temp = Panel_1280x768_2; 1864 } 1865 if(SiS_Pr->SiS_ROMNew) { 1866 if(temp == Panel661_1280x800) { 1867 temp = Panel_1280x800_2; 1868 } 1869 } 1870 } 1871 1872 SiS_Pr->SiS_LCDResInfo = temp; 1873 1874#ifdef CONFIG_FB_SIS_300 1875 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1876 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 1877 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366; 1878 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { 1879 SiS_Pr->SiS_LCDResInfo = Panel_848x480; 1880 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) { 1881 SiS_Pr->SiS_LCDResInfo = Panel_856x480; 1882 } 1883 } 1884#endif 1885 1886 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1887 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301) 1888 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301; 1889 } else { 1890 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS) 1891 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS; 1892 } 1893 1894 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 1895 SiS_Pr->SiS_LCDInfo = temp & ~0x000e; 1896 /* Need temp below! */ 1897 1898 /* These must/can't scale no matter what */ 1899 switch(SiS_Pr->SiS_LCDResInfo) { 1900 case Panel_320x240_1: 1901 case Panel_320x240_2: 1902 case Panel_320x240_3: 1903 case Panel_1280x960: 1904 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; 1905 break; 1906 case Panel_640x480: 1907 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1908 } 1909 1910 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD); 1911 1912 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; 1913 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1914 1915 /* Dual link, Pass 1:1 BIOS default, etc. */ 1916#ifdef CONFIG_FB_SIS_315 1917 if(SiS_Pr->ChipType >= SIS_661) { 1918 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1919 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1920 } 1921 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1922 if(SiS_Pr->SiS_ROMNew) { 1923 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1924 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) { 1925 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1926 } 1927 } 1928 } else if(SiS_Pr->ChipType >= SIS_315H) { 1929 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1930 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1931 } 1932 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) { 1933 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit); 1934 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1935 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit; 1936 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1937 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1938 } 1939 } else if(!(SiS_Pr->SiS_ROMNew)) { 1940 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1941 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) && 1942 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) { 1943 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1944 } 1945 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 1946 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 1947 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 1948 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) { 1949 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1950 } 1951 } 1952 } 1953 } 1954#endif 1955 1956 /* Pass 1:1 */ 1957 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 1958 /* Always center screen on LVDS (if scaling is disabled) */ 1959 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1960 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 1961 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 1962 /* Always center screen on SiS LVDS (if scaling is disabled) */ 1963 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1964 } else { 1965 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */ 1966 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1967 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1968 } 1969 } 1970 1971 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1972 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1973 1974 switch(SiS_Pr->SiS_LCDResInfo) { 1975 case Panel_320x240_1: 1976 case Panel_320x240_2: 1977 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; 1978 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3; 1979 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1980 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1981 break; 1982 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; 1983 SiS_Pr->PanelVRE = 3; 1984 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1985 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1986 break; 1987 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600; 1988 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628; 1989 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128; 1990 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4; 1991 SiS_Pr->PanelVCLKIdx300 = VCLK40; 1992 SiS_Pr->PanelVCLKIdx315 = VCLK40; 1993 break; 1994 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600; 1995 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800; 1996 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 1997 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6; 1998 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1999 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 2000 break; 2001 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 2002 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 2003 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 2004 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2005 if(SiS_Pr->ChipType < SIS_315H) { 2006 SiS_Pr->PanelHRS = 23; 2007 SiS_Pr->PanelVRE = 5; 2008 } 2009 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 2010 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 2011 SiS_GetLCDInfoBIOS(SiS_Pr); 2012 break; 2013 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768; 2014 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 2015 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 2016 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2017 if(SiS_Pr->ChipType < SIS_315H) { 2018 SiS_Pr->PanelHRS = 23; 2019 SiS_Pr->PanelVRE = 5; 2020 } 2021 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 2022 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 2023 break; 2024 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864; 2025 break; 2026 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720; 2027 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750; 2028 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40; 2029 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5; 2030 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720; 2031 /* Data above for TMDS (projector); get from BIOS for LVDS */ 2032 SiS_GetLCDInfoBIOS(SiS_Pr); 2033 break; 2034 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 2035 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2036 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806; 2037 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */ 2038 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */ 2039 } else { 2040 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802; 2041 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2042 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2043 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; 2044 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; 2045 } 2046 break; 2047 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 2048 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806; 2049 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2050 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2051 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2; 2052 SiS_GetLCDInfoBIOS(SiS_Pr); 2053 break; 2054 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 2055 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816; 2056 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24; 2057 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 2058 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315; 2059 SiS_GetLCDInfoBIOS(SiS_Pr); 2060 break; 2061 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 2062 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812; 2063 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2064 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 2065 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2; 2066 SiS_GetLCDInfoBIOS(SiS_Pr); 2067 break; 2068 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854; 2069 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861; 2070 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112; 2071 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2072 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854; 2073 SiS_GetLCDInfoBIOS(SiS_Pr); 2074 break; 2075 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960; 2076 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000; 2077 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 2078 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315; 2079 if(resinfo == SIS_RI_1280x1024) { 2080 SiS_Pr->PanelVCLKIdx300 = VCLK100_300; 2081 SiS_Pr->PanelVCLKIdx315 = VCLK100_315; 2082 } 2083 break; 2084 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; 2085 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 2086 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2087 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2088 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 2089 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 2090 SiS_GetLCDInfoBIOS(SiS_Pr); 2091 break; 2092 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; 2093 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 2094 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2095 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2096 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 2097 SiS_GetLCDInfoBIOS(SiS_Pr); 2098 break; 2099 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; 2100 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250; 2101 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192; 2102 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2103 SiS_Pr->PanelVCLKIdx315 = VCLK162_315; 2104 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) { 2105 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 2106 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235; 2107 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32; 2108 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4; 2109 SiS_Pr->PanelVCLKIdx315 = VCLK130_315; 2110 SiS_Pr->Alternate1600x1200 = true; 2111 } 2112 } else if(SiS_Pr->SiS_IF_DEF_LVDS) { 2113 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320; 2114 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999; 2115 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999; 2116 } 2117 SiS_GetLCDInfoBIOS(SiS_Pr); 2118 break; 2119 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050; 2120 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066; 2121 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76; 2122 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2123 SiS_Pr->PanelVCLKIdx315 = VCLK121_315; 2124 SiS_GetLCDInfoBIOS(SiS_Pr); 2125 break; 2126 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; 2127 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 2128 break; 2129 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480; 2130 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525; 2131 break; 2132 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480; 2133 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525; 2134 break; 2135 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX; 2136 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY; 2137 SiS_Pr->PanelHT = SiS_Pr->CHTotal; 2138 SiS_Pr->PanelVT = SiS_Pr->CVTotal; 2139 if(SiS_Pr->CP_PreferredIndex != -1) { 2140 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex]; 2141 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex]; 2142 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex]; 2143 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex]; 2144 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex]; 2145 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex]; 2146 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex]; 2147 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex]; 2148 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes; 2149 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS; 2150 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes; 2151 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS; 2152 if(SiS_Pr->CP_PrefClock) { 2153 int idx; 2154 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 2155 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300; 2156 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300; 2157 else idx = VCLK_CUSTOM_315; 2158 SiS_Pr->SiS_VCLKData[idx].CLOCK = 2159 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock; 2160 SiS_Pr->SiS_VCLKData[idx].SR2B = 2161 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B; 2162 SiS_Pr->SiS_VCLKData[idx].SR2C = 2163 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C; 2164 } 2165 } 2166 break; 2167 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 2168 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 2169 break; 2170 } 2171 2172 /* Special cases */ 2173 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 2174 (SiS_Pr->SiS_IF_DEF_DSTN) || 2175 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 2176 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 2177 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 2178 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 2179 SiS_Pr->PanelHRS = 999; 2180 SiS_Pr->PanelHRE = 999; 2181 } 2182 2183 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 2184 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 2185 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 2186 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 2187 SiS_Pr->PanelVRS = 999; 2188 SiS_Pr->PanelVRE = 999; 2189 } 2190 2191 /* DontExpand overrule */ 2192 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 2193 2194 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) { 2195 /* No scaling for this mode on any panel (LCD=CRT2)*/ 2196 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2197 } 2198 2199 switch(SiS_Pr->SiS_LCDResInfo) { 2200 2201 case Panel_Custom: 2202 case Panel_1152x864: 2203 case Panel_1280x768: /* TMDS only */ 2204 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2205 break; 2206 2207 case Panel_800x600: { 2208 static const unsigned char nonscalingmodes[] = { 2209 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff 2210 }; 2211 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2212 break; 2213 } 2214 case Panel_1024x768: { 2215 static const unsigned char nonscalingmodes[] = { 2216 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2217 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2218 0xff 2219 }; 2220 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2221 break; 2222 } 2223 case Panel_1280x720: { 2224 static const unsigned char nonscalingmodes[] = { 2225 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2226 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2227 0xff 2228 }; 2229 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2230 if(SiS_Pr->PanelHT == 1650) { 2231 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2232 } 2233 break; 2234 } 2235 case Panel_1280x768_2: { /* LVDS only */ 2236 static const unsigned char nonscalingmodes[] = { 2237 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2238 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2239 SIS_RI_1152x768,0xff 2240 }; 2241 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2242 switch(resinfo) { 2243 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 2244 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2245 } 2246 break; 2247 } 2248 break; 2249 } 2250 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */ 2251 static const unsigned char nonscalingmodes[] = { 2252 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2253 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2254 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff 2255 }; 2256 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2257 break; 2258 } 2259 case Panel_1280x800_2: { /* SiS LVDS */ 2260 static const unsigned char nonscalingmodes[] = { 2261 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2262 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2263 SIS_RI_1152x768,0xff 2264 }; 2265 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2266 switch(resinfo) { 2267 case SIS_RI_1280x720: 2268 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) { 2269 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2270 } 2271 break; 2272 } 2273 break; 2274 } 2275 case Panel_1280x854: { /* SiS LVDS */ 2276 static const unsigned char nonscalingmodes[] = { 2277 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2278 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2279 SIS_RI_1152x768,0xff 2280 }; 2281 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2282 switch(resinfo) { 2283 case SIS_RI_1280x720: 2284 case SIS_RI_1280x768: 2285 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) { 2286 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2287 } 2288 break; 2289 } 2290 break; 2291 } 2292 case Panel_1280x960: { 2293 static const unsigned char nonscalingmodes[] = { 2294 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2295 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2296 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2297 SIS_RI_1280x854,0xff 2298 }; 2299 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2300 break; 2301 } 2302 case Panel_1280x1024: { 2303 static const unsigned char nonscalingmodes[] = { 2304 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2305 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2306 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2307 SIS_RI_1280x854,SIS_RI_1280x960,0xff 2308 }; 2309 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2310 break; 2311 } 2312 case Panel_1400x1050: { 2313 static const unsigned char nonscalingmodes[] = { 2314 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2315 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2316 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854, 2317 SIS_RI_1280x960,0xff 2318 }; 2319 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2320 switch(resinfo) { 2321 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 2322 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2323 } 2324 break; 2325 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2326 break; 2327 } 2328 break; 2329 } 2330 case Panel_1600x1200: { 2331 static const unsigned char nonscalingmodes[] = { 2332 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2333 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2334 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2335 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff 2336 }; 2337 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2338 break; 2339 } 2340 case Panel_1680x1050: { 2341 static const unsigned char nonscalingmodes[] = { 2342 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2343 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2344 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768, 2345 SIS_RI_1360x1024,0xff 2346 }; 2347 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2348 break; 2349 } 2350 } 2351 } 2352 2353#ifdef CONFIG_FB_SIS_300 2354 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2355 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 2356 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */ 2357 } 2358 } 2359 2360 if(SiS_Pr->ChipType < SIS_315H) { 2361 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2362 if(SiS_Pr->SiS_UseROM) { 2363 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 2364 if(!(ROMAddr[0x235] & 0x02)) { 2365 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2366 } 2367 } 2368 } 2369 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2370 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) { 2371 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2372 } 2373 } 2374 } 2375#endif 2376 2377 /* Special cases */ 2378 2379 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) { 2380 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2381 } 2382 2383 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 2384 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2385 } 2386 2387 switch(SiS_Pr->SiS_LCDResInfo) { 2388 case Panel_640x480: 2389 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2390 break; 2391 case Panel_1280x800: 2392 /* Don't pass 1:1 by default (TMDS special) */ 2393 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2394 break; 2395 case Panel_1280x960: 2396 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2397 break; 2398 case Panel_Custom: 2399 if((!SiS_Pr->CP_PrefClock) || 2400 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) { 2401 SiS_Pr->SiS_LCDInfo |= LCDPass11; 2402 } 2403 break; 2404 } 2405 2406 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) { 2407 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2408 } 2409 2410 /* (In)validate LCDPass11 flag */ 2411 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2412 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2413 } 2414 2415 /* LVDS DDA */ 2416 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) { 2417 2418 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 2419 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { 2420 if(ModeNo == 0x12) { 2421 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 2422 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2423 } 2424 } else if(ModeNo > 0x13) { 2425 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) { 2426 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2427 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) { 2428 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2429 } 2430 } 2431 } 2432 } 2433 } 2434 } 2435 2436 if(modeflag & HalfDCLK) { 2437 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) { 2438 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2439 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 2440 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2441 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) { 2442 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2443 } else if(ModeNo > 0x13) { 2444 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 2445 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2446 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) { 2447 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2448 } 2449 } 2450 } 2451 2452 } 2453 2454 /* VESA timing */ 2455 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2456 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) { 2457 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2458 } 2459 } else { 2460 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2461 } 2462 2463#if 0 2464 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n", 2465 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); 2466#endif 2467} 2468 2469/*********************************************/ 2470/* GET VCLK */ 2471/*********************************************/ 2472 2473unsigned short 2474SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 2475 unsigned short RefreshRateTableIndex) 2476{ 2477 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0; 2478 unsigned short resinfo, tempbx; 2479 const unsigned char *CHTVVCLKPtr = NULL; 2480 2481 if(ModeNo <= 0x13) { 2482 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 2483 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 2484 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03; 2485 VCLKIndexGENCRT = VCLKIndexGEN; 2486 } else { 2487 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2488 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 2489 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 2490 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, 2491 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide); 2492 } 2493 2494 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */ 2495 2496 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2497 2498 CRT2Index >>= 6; 2499 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */ 2500 2501 if(SiS_Pr->ChipType < SIS_315H) { 2502 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2503 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2504 VCLKIndex = VCLKIndexGEN; 2505 } 2506 } else { 2507 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2508 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2509 switch(resinfo) { 2510 /* Correct those whose IndexGEN doesn't match VBVCLK array */ 2511 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break; 2512 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break; 2513 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break; 2514 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break; 2515 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break; 2516 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break; 2517 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break; 2518 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break; 2519 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break; 2520 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break; 2521 default: VCLKIndex = VCLKIndexGEN; 2522 } 2523 2524 if(ModeNo <= 0x13) { 2525 if(SiS_Pr->ChipType <= SIS_315PRO) { 2526 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42; 2527 } else { 2528 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00; 2529 } 2530 } 2531 if(SiS_Pr->ChipType <= SIS_315PRO) { 2532 if(VCLKIndex == 0) VCLKIndex = 0x41; 2533 if(VCLKIndex == 1) VCLKIndex = 0x43; 2534 if(VCLKIndex == 4) VCLKIndex = 0x44; 2535 } 2536 } 2537 } 2538 2539 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */ 2540 2541 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 2542 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2; 2543 else VCLKIndex = HiTVVCLK; 2544 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK; 2545 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK; 2546 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2; 2547 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2; 2548 else VCLKIndex = TVVCLK; 2549 2550 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300; 2551 else VCLKIndex += TVCLKBASE_315; 2552 2553 } else { /* VGA2 */ 2554 2555 VCLKIndex = VCLKIndexGENCRT; 2556 if(SiS_Pr->ChipType < SIS_315H) { 2557 if(ModeNo > 0x13) { 2558 if( (SiS_Pr->ChipType == SIS_630) && 2559 (SiS_Pr->ChipRevision >= 0x30)) { 2560 if(VCLKIndex == 0x14) VCLKIndex = 0x34; 2561 } 2562 /* Better VGA2 clock for 1280x1024@75 */ 2563 if(VCLKIndex == 0x17) VCLKIndex = 0x45; 2564 } 2565 } 2566 } 2567 2568 } else { /* If not programming CRT2 */ 2569 2570 VCLKIndex = VCLKIndexGENCRT; 2571 if(SiS_Pr->ChipType < SIS_315H) { 2572 if(ModeNo > 0x13) { 2573 if( (SiS_Pr->ChipType != SIS_630) && 2574 (SiS_Pr->ChipType != SIS_300) ) { 2575 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2576 } 2577 } 2578 } 2579 } 2580 2581 } else { /* LVDS */ 2582 2583 VCLKIndex = CRT2Index; 2584 2585 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2586 2587 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) { 2588 2589 VCLKIndex &= 0x1f; 2590 tempbx = 0; 2591 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2592 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 2593 tempbx += 2; 2594 if(SiS_Pr->SiS_ModeType > ModeVGA) { 2595 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8; 2596 } 2597 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 2598 tempbx = 4; 2599 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2600 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 2601 tempbx = 6; 2602 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2603 } 2604 } 2605 switch(tempbx) { 2606 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break; 2607 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break; 2608 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break; 2609 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2610 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break; 2611 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break; 2612 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break; 2613 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break; 2614 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break; 2615 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2616 } 2617 VCLKIndex = CHTVVCLKPtr[VCLKIndex]; 2618 2619 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 2620 2621 if(SiS_Pr->ChipType < SIS_315H) { 2622 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2623 } else { 2624 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2625 } 2626 2627#ifdef CONFIG_FB_SIS_300 2628 /* Special Timing: Barco iQ Pro R series */ 2629 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44; 2630 2631 /* Special Timing: 848x480 and 856x480 parallel lvds panels */ 2632 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 2633 if(SiS_Pr->ChipType < SIS_315H) { 2634 VCLKIndex = VCLK34_300; 2635 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2636 } else { 2637 VCLKIndex = VCLK34_315; 2638 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2639 } 2640 } 2641#endif 2642 2643 } else { 2644 2645 VCLKIndex = VCLKIndexGENCRT; 2646 if(SiS_Pr->ChipType < SIS_315H) { 2647 if(ModeNo > 0x13) { 2648 if( (SiS_Pr->ChipType == SIS_630) && 2649 (SiS_Pr->ChipRevision >= 0x30) ) { 2650 if(VCLKIndex == 0x14) VCLKIndex = 0x2e; 2651 } 2652 } 2653 } 2654 } 2655 2656 } else { /* if not programming CRT2 */ 2657 2658 VCLKIndex = VCLKIndexGENCRT; 2659 if(SiS_Pr->ChipType < SIS_315H) { 2660 if(ModeNo > 0x13) { 2661 if( (SiS_Pr->ChipType != SIS_630) && 2662 (SiS_Pr->ChipType != SIS_300) ) { 2663 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2664 } 2665#if 0 2666 if(SiS_Pr->ChipType == SIS_730) { 2667 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */ 2668 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */ 2669 } 2670#endif 2671 } 2672 } 2673 2674 } 2675 2676 } 2677 2678 return VCLKIndex; 2679} 2680 2681/*********************************************/ 2682/* SET CRT2 MODE TYPE REGISTERS */ 2683/*********************************************/ 2684 2685static void 2686SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 2687{ 2688 unsigned short i, j, modeflag, tempah=0; 2689 short tempcl; 2690#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 2691 unsigned short tempbl; 2692#endif 2693#ifdef CONFIG_FB_SIS_315 2694 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 2695 unsigned short tempah2, tempbl2; 2696#endif 2697 2698 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 2699 2700 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 2701 2702 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); 2703 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7); 2704 2705 } else { 2706 2707 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0); 2708 if(SiS_Pr->ChipType >= SIS_315H) { 2709 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F); 2710 } 2711 2712 tempcl = SiS_Pr->SiS_ModeType; 2713 2714 if(SiS_Pr->ChipType < SIS_315H) { 2715 2716#ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */ 2717 2718 /* For 301BDH: (with LCD via LVDS) */ 2719 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 2720 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32); 2721 tempbl &= 0xef; 2722 tempbl |= 0x02; 2723 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 2724 tempbl |= 0x10; 2725 tempbl &= 0xfd; 2726 } 2727 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl); 2728 } 2729 2730 if(ModeNo > 0x13) { 2731 tempcl -= ModeVGA; 2732 if(tempcl >= 0) { 2733 tempah = ((0x10 >> tempcl) | 0x80); 2734 } 2735 } else tempah = 0x80; 2736 2737 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0; 2738 2739#endif /* CONFIG_FB_SIS_300 */ 2740 2741 } else { 2742 2743#ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */ 2744 2745 if(ModeNo > 0x13) { 2746 tempcl -= ModeVGA; 2747 if(tempcl >= 0) { 2748 tempah = (0x08 >> tempcl); 2749 if (tempah == 0) tempah = 1; 2750 tempah |= 0x40; 2751 } 2752 } else tempah = 0x40; 2753 2754 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50; 2755 2756#endif /* CONFIG_FB_SIS_315 */ 2757 2758 } 2759 2760 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2761 2762 if(SiS_Pr->ChipType < SIS_315H) { 2763 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2764 } else { 2765#ifdef CONFIG_FB_SIS_315 2766 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2767 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2768 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 2769 if(IS_SIS740) { 2770 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2771 } else { 2772 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2773 } 2774 } 2775#endif 2776 } 2777 2778 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2779 2780 tempah = 0x01; 2781 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 2782 tempah |= 0x02; 2783 } 2784 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 2785 tempah ^= 0x05; 2786 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 2787 tempah ^= 0x01; 2788 } 2789 } 2790 2791 if(SiS_Pr->ChipType < SIS_315H) { 2792 2793 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2794 2795 tempah = (tempah << 5) & 0xFF; 2796 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2797 tempah = (tempah >> 5) & 0xFF; 2798 2799 } else { 2800 2801 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08; 2802 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08; 2803 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah); 2804 tempah &= ~0x08; 2805 2806 } 2807 2808 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 2809 tempah |= 0x10; 2810 } 2811 2812 tempah |= 0x80; 2813 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2814 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80; 2815 } 2816 2817 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2818 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) { 2819 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2820 tempah |= 0x20; 2821 } 2822 } 2823 } 2824 2825 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah); 2826 2827 tempah = 0x80; 2828 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2829 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0; 2830 } 2831 2832 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40; 2833 2834 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2835 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) { 2836 tempah |= 0x40; 2837 } 2838 } 2839 2840 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah); 2841 2842 } else { /* LVDS */ 2843 2844 if(SiS_Pr->ChipType >= SIS_315H) { 2845 2846#ifdef CONFIG_FB_SIS_315 2847 /* LVDS can only be slave in 8bpp modes */ 2848 tempah = 0x80; 2849 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) { 2850 if(SiS_Pr->SiS_VBInfo & DriverMode) { 2851 tempah |= 0x02; 2852 } 2853 } 2854 2855 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02; 2856 2857 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01; 2858 2859 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1; 2860 2861 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah); 2862#endif 2863 2864 } else { 2865 2866#ifdef CONFIG_FB_SIS_300 2867 tempah = 0; 2868 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { 2869 tempah |= 0x02; 2870 } 2871 tempah <<= 5; 2872 2873 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2874 2875 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2876#endif 2877 2878 } 2879 2880 } 2881 2882 } /* LCDA */ 2883 2884 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2885 2886 if(SiS_Pr->ChipType >= SIS_315H) { 2887 2888#ifdef CONFIG_FB_SIS_315 2889 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */ 2890 2891 /* The following is nearly unpreditable and varies from machine 2892 * to machine. Especially the 301DH seems to be a real trouble 2893 * maker. Some BIOSes simply set the registers (like in the 2894 * NoLCD-if-statements here), some set them according to the 2895 * LCDA stuff. It is very likely that some machines are not 2896 * treated correctly in the following, very case-orientated 2897 * code. What do I do then...? 2898 */ 2899 2900 /* 740 variants match for 30xB, 301B-DH, 30xLV */ 2901 2902 if(!(IS_SIS740)) { 2903 tempah = 0x04; /* For all bridges */ 2904 tempbl = 0xfb; 2905 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2906 tempah = 0x00; 2907 if(SiS_IsDualEdge(SiS_Pr)) { 2908 tempbl = 0xff; 2909 } 2910 } 2911 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 2912 } 2913 2914 /* The following two are responsible for eventually wrong colors 2915 * in TV output. The DH (VB_NoLCD) conditions are unknown; the 2916 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version 2917 * in a 650 box (Jake). What is the criteria? 2918 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same 2919 * treatment like the 651+301B-DH(b0) case. Seems more to be the 2920 * chipset than the bridge revision. 2921 */ 2922 2923 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 2924 tempah = 0x30; 2925 tempbl = 0xc0; 2926 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2927 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) { 2928 tempah = 0x00; 2929 tempbl = 0x00; 2930 } 2931 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah); 2932 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl); 2933 } else if(SiS_Pr->SiS_VBType & VB_SIS301) { 2934 /* Fixes "TV-blue-bug" on 315+301 */ 2935 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */ 2936 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2937 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 2938 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */ 2939 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0); 2940 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */ 2941 tempah = 0x30; tempah2 = 0xc0; 2942 tempbl = 0xcf; tempbl2 = 0x3f; 2943 if(SiS_Pr->SiS_TVBlue == 0) { 2944 tempah = tempah2 = 0x00; 2945 } else if(SiS_Pr->SiS_TVBlue == -1) { 2946 /* Set on 651/M650, clear on 315/650 */ 2947 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ { 2948 tempah = tempah2 = 0x00; 2949 } 2950 } 2951 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); 2952 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2); 2953 } else { 2954 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */ 2955 tempbl = 0xcf; tempbl2 = 0x3f; 2956 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2957 tempah = tempah2 = 0x00; 2958 if(SiS_IsDualEdge(SiS_Pr)) { 2959 tempbl = tempbl2 = 0xff; 2960 } 2961 } 2962 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); 2963 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2); 2964 } 2965 2966 if(IS_SIS740) { 2967 tempah = 0x80; 2968 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00; 2969 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah); 2970 } else { 2971 tempah = 0x00; 2972 tempbl = 0x7f; 2973 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2974 tempbl = 0xff; 2975 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80; 2976 } 2977 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); 2978 } 2979 2980#endif /* CONFIG_FB_SIS_315 */ 2981 2982 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2983 2984#ifdef CONFIG_FB_SIS_300 2985 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2986 2987 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2988 ((SiS_Pr->SiS_VBType & VB_NoLCD) && 2989 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) { 2990 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F); 2991 } else { 2992 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80); 2993 } 2994#endif 2995 2996 } 2997 2998 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2999 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80); 3000 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 3001 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0); 3002 } 3003 } 3004 3005 } else { /* LVDS */ 3006 3007#ifdef CONFIG_FB_SIS_315 3008 if(SiS_Pr->ChipType >= SIS_315H) { 3009 3010 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 3011 3012 tempah = 0x04; 3013 tempbl = 0xfb; 3014 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3015 tempah = 0x00; 3016 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff; 3017 } 3018 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 3019 3020 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 3021 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 3022 } 3023 3024 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 3025 3026 } else if(SiS_Pr->ChipType == SIS_550) { 3027 3028 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 3029 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 3030 3031 } 3032 3033 } 3034#endif 3035 3036 } 3037 3038} 3039 3040/*********************************************/ 3041/* GET RESOLUTION DATA */ 3042/*********************************************/ 3043 3044unsigned short 3045SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 3046{ 3047 if(ModeNo <= 0x13) 3048 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo); 3049 else 3050 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO); 3051} 3052 3053static void 3054SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 3055{ 3056 unsigned short xres, yres, modeflag=0, resindex; 3057 3058 if(SiS_Pr->UseCustomMode) { 3059 xres = SiS_Pr->CHDisplay; 3060 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1; 3061 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 3062 /* DoubleScanMode-check done in CheckCalcCustomMode()! */ 3063 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay; 3064 return; 3065 } 3066 3067 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex); 3068 3069 if(ModeNo <= 0x13) { 3070 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal; 3071 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal; 3072 } else { 3073 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal; 3074 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal; 3075 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3076 } 3077 3078 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) { 3079 3080 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) { 3081 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) { 3082 if(yres == 350) yres = 400; 3083 } 3084 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) { 3085 if(ModeNo == 0x12) yres = 400; 3086 } 3087 } 3088 3089 if(modeflag & HalfDCLK) xres <<= 1; 3090 if(modeflag & DoubleScanMode) yres <<= 1; 3091 3092 } 3093 3094 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 3095 3096 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3097 switch(SiS_Pr->SiS_LCDResInfo) { 3098 case Panel_1024x768: 3099 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3100 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3101 if(yres == 350) yres = 357; 3102 if(yres == 400) yres = 420; 3103 if(yres == 480) yres = 525; 3104 } 3105 } 3106 break; 3107 case Panel_1280x1024: 3108 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3109 /* BIOS bug - does this regardless of scaling */ 3110 if(yres == 400) yres = 405; 3111 } 3112 if(yres == 350) yres = 360; 3113 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 3114 if(yres == 360) yres = 375; 3115 } 3116 break; 3117 case Panel_1600x1200: 3118 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3119 if(yres == 1024) yres = 1056; 3120 } 3121 break; 3122 } 3123 } 3124 3125 } else { 3126 3127 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3128 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) { 3129 if(xres == 720) xres = 640; 3130 } 3131 } else if(xres == 720) xres = 640; 3132 3133 if(SiS_Pr->SiS_SetFlag & SetDOSMode) { 3134 yres = 400; 3135 if(SiS_Pr->ChipType >= SIS_315H) { 3136 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480; 3137 } else { 3138 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480; 3139 } 3140 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480; 3141 } 3142 3143 } 3144 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 3145 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres; 3146} 3147 3148/*********************************************/ 3149/* GET CRT2 TIMING DATA */ 3150/*********************************************/ 3151 3152static void 3153SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3154 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index, 3155 unsigned short *ResIndex) 3156{ 3157 unsigned short tempbx=0, tempal=0, resinfo=0; 3158 3159 if(ModeNo <= 0x13) { 3160 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3161 } else { 3162 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 3163 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 3164 } 3165 3166 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) { 3167 3168 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */ 3169 3170 tempbx = SiS_Pr->SiS_LCDResInfo; 3171 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32; 3172 3173 /* patch index */ 3174 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) { 3175 if (resinfo == SIS_RI_1280x800) tempal = 9; 3176 else if(resinfo == SIS_RI_1400x1050) tempal = 11; 3177 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) || 3178 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) || 3179 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) { 3180 if (resinfo == SIS_RI_1280x768) tempal = 9; 3181 } 3182 3183 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3184 /* Pass 1:1 only (center-screen handled outside) */ 3185 /* This is never called for the panel's native resolution */ 3186 /* since Pass1:1 will not be set in this case */ 3187 tempbx = 100; 3188 if(ModeNo >= 0x13) { 3189 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS; 3190 } 3191 } 3192 3193#ifdef CONFIG_FB_SIS_315 3194 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 3195 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 3196 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3197 tempbx = 200; 3198 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; 3199 } 3200 } 3201 } 3202#endif 3203 3204 } else { /* TV */ 3205 3206 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 3207 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */ 3208 tempbx = 2; 3209 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 3210 tempbx = 13; 3211 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14; 3212 } 3213 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3214 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7; 3215 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6; 3216 else tempbx = 5; 3217 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 3218 } else { 3219 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3; 3220 else tempbx = 4; 3221 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 3222 } 3223 3224 } 3225 3226 tempal &= 0x3F; 3227 3228 if(ModeNo > 0x13) { 3229 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) { 3230 switch(resinfo) { 3231 case SIS_RI_720x480: 3232 tempal = 6; 3233 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9; 3234 break; 3235 case SIS_RI_720x576: 3236 case SIS_RI_768x576: 3237 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */ 3238 tempal = 6; 3239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3240 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8; 3241 } 3242 break; 3243 case SIS_RI_800x480: 3244 tempal = 4; 3245 break; 3246 case SIS_RI_512x384: 3247 case SIS_RI_1024x768: 3248 tempal = 7; 3249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3250 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8; 3251 } 3252 break; 3253 case SIS_RI_1280x720: 3254 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3255 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9; 3256 } 3257 break; 3258 } 3259 } 3260 } 3261 3262 *CRT2Index = tempbx; 3263 *ResIndex = tempal; 3264 3265 } else { /* LVDS, 301B-DH (if running on LCD) */ 3266 3267 tempbx = 0; 3268 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 3269 3270 tempbx = 90; 3271 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 3272 tempbx = 92; 3273 if(SiS_Pr->SiS_ModeType > ModeVGA) { 3274 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99; 3275 } 3276 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94; 3277 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96; 3278 } 3279 if(tempbx != 99) { 3280 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++; 3281 } 3282 3283 } else { 3284 3285 switch(SiS_Pr->SiS_LCDResInfo) { 3286 case Panel_640x480: tempbx = 12; break; 3287 case Panel_320x240_1: tempbx = 10; break; 3288 case Panel_320x240_2: 3289 case Panel_320x240_3: tempbx = 14; break; 3290 case Panel_800x600: tempbx = 16; break; 3291 case Panel_1024x600: tempbx = 18; break; 3292 case Panel_1152x768: 3293 case Panel_1024x768: tempbx = 20; break; 3294 case Panel_1280x768: tempbx = 22; break; 3295 case Panel_1280x1024: tempbx = 24; break; 3296 case Panel_1400x1050: tempbx = 26; break; 3297 case Panel_1600x1200: tempbx = 28; break; 3298#ifdef CONFIG_FB_SIS_300 3299 case Panel_Barco1366: tempbx = 80; break; 3300#endif 3301 } 3302 3303 switch(SiS_Pr->SiS_LCDResInfo) { 3304 case Panel_320x240_1: 3305 case Panel_320x240_2: 3306 case Panel_320x240_3: 3307 case Panel_640x480: 3308 break; 3309 default: 3310 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3311 } 3312 3313 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30; 3314 3315#ifdef CONFIG_FB_SIS_300 3316 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 3317 tempbx = 82; 3318 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3319 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 3320 tempbx = 84; 3321 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3322 } 3323#endif 3324 3325 } 3326 3327 (*CRT2Index) = tempbx; 3328 (*ResIndex) = tempal & 0x1F; 3329 } 3330} 3331 3332static void 3333SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3334 unsigned short RefreshRateTableIndex) 3335{ 3336 unsigned short tempax=0, tempbx=0, index, dotclock; 3337 unsigned short temp1=0, modeflag=0, tempcx=0; 3338 3339 SiS_Pr->SiS_RVBHCMAX = 1; 3340 SiS_Pr->SiS_RVBHCFACT = 1; 3341 3342 if(ModeNo <= 0x13) { 3343 3344 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3345 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex); 3346 3347 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0]; 3348 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6]; 3349 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7]; 3350 3351 dotclock = (modeflag & Charx8Dot) ? 8 : 9; 3352 3353 } else { 3354 3355 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3356 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2); 3357 3358 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0]; 3359 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8); 3360 tempax &= 0x03FF; 3361 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6]; 3362 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8; 3363 tempcx &= 0x0100; 3364 tempcx <<= 2; 3365 tempbx |= tempcx; 3366 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7]; 3367 3368 dotclock = 8; 3369 3370 } 3371 3372 if(temp1 & 0x01) tempbx |= 0x0100; 3373 if(temp1 & 0x20) tempbx |= 0x0200; 3374 3375 tempax += 5; 3376 tempax *= dotclock; 3377 if(modeflag & HalfDCLK) tempax <<= 1; 3378 3379 tempbx++; 3380 3381 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3382 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx; 3383} 3384 3385static void 3386SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 3387 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex) 3388{ 3389 unsigned short ResIndex; 3390 3391 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3392 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 3393 if(SiS_Pr->UseCustomMode) { 3394 ResIndex = SiS_Pr->CHTotal; 3395 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1; 3396 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex; 3397 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3398 } else { 3399 if(ModeNo < 0x13) { 3400 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3401 } else { 3402 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS; 3403 } 3404 if(ResIndex == 0x09) { 3405 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */ 3406 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */ 3407 } 3408 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT; 3409 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT; 3410 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT; 3411 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT; 3412 } 3413 } else { 3414 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3415 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3416 } 3417 } else { 3418 /* This handles custom modes and custom panels */ 3419 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; 3420 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; 3421 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3422 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3423 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE); 3424 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE); 3425 } 3426} 3427 3428static void 3429SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3430 unsigned short RefreshRateTableIndex) 3431{ 3432 unsigned short CRT2Index, ResIndex, backup; 3433 const struct SiS_LVDSData *LVDSData = NULL; 3434 3435 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex); 3436 3437 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3438 SiS_Pr->SiS_RVBHCMAX = 1; 3439 SiS_Pr->SiS_RVBHCFACT = 1; 3440 SiS_Pr->SiS_NewFlickerMode = 0; 3441 SiS_Pr->SiS_RVBHRS = 50; 3442 SiS_Pr->SiS_RY1COE = 0; 3443 SiS_Pr->SiS_RY2COE = 0; 3444 SiS_Pr->SiS_RY3COE = 0; 3445 SiS_Pr->SiS_RY4COE = 0; 3446 SiS_Pr->SiS_RVBHRS2 = 0; 3447 } 3448 3449 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3450 3451#ifdef CONFIG_FB_SIS_315 3452 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3453 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); 3454#endif 3455 3456 } else { 3457 3458 /* 301BDH needs LVDS Data */ 3459 backup = SiS_Pr->SiS_IF_DEF_LVDS; 3460 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3461 SiS_Pr->SiS_IF_DEF_LVDS = 1; 3462 } 3463 3464 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 3465 &CRT2Index, &ResIndex); 3466 3467 SiS_Pr->SiS_IF_DEF_LVDS = backup; 3468 3469 switch(CRT2Index) { 3470 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break; 3471 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break; 3472 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break; 3473 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break; 3474 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break; 3475 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; 3476#ifdef CONFIG_FB_SIS_300 3477 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break; 3478 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break; 3479 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break; 3480 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break; 3481 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break; 3482#endif 3483 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break; 3484 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break; 3485 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break; 3486 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break; 3487 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break; 3488 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break; 3489 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break; 3490 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break; 3491 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; 3492 } 3493 3494 if(LVDSData) { 3495 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT; 3496 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT; 3497 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT; 3498 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT; 3499 } else { 3500 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3501 } 3502 3503 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) && 3504 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && 3505 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) { 3506 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || 3507 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) { 3508 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; 3509 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; 3510#ifdef CONFIG_FB_SIS_300 3511 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 3512 if(ResIndex < 0x08) { 3513 SiS_Pr->SiS_HDE = 1280; 3514 SiS_Pr->SiS_VDE = 1024; 3515 } 3516 } 3517#endif 3518 } 3519 } 3520 } 3521} 3522 3523static void 3524SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3525 unsigned short RefreshRateTableIndex) 3526{ 3527 unsigned char *ROMAddr = NULL; 3528 unsigned short tempax, tempbx, modeflag, romptr=0; 3529 unsigned short resinfo, CRT2Index, ResIndex; 3530 const struct SiS_LCDData *LCDPtr = NULL; 3531 const struct SiS_TVData *TVPtr = NULL; 3532#ifdef CONFIG_FB_SIS_315 3533 short resinfo661; 3534#endif 3535 3536 if(ModeNo <= 0x13) { 3537 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3538 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 3539 } else if(SiS_Pr->UseCustomMode) { 3540 modeflag = SiS_Pr->CModeFlag; 3541 resinfo = 0; 3542 } else { 3543 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3544 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 3545#ifdef CONFIG_FB_SIS_315 3546 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661; 3547 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && 3548 (SiS_Pr->SiS_SetFlag & LCDVESATiming) && 3549 (resinfo661 >= 0) && 3550 (SiS_Pr->SiS_NeedRomModeData) ) { 3551 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { 3552 if((romptr = (SISGETROMW(21)))) { 3553 romptr += (resinfo661 * 10); 3554 ROMAddr = SiS_Pr->VirtualRomBase; 3555 } 3556 } 3557 } 3558#endif 3559 } 3560 3561 SiS_Pr->SiS_NewFlickerMode = 0; 3562 SiS_Pr->SiS_RVBHRS = 50; 3563 SiS_Pr->SiS_RY1COE = 0; 3564 SiS_Pr->SiS_RY2COE = 0; 3565 SiS_Pr->SiS_RY3COE = 0; 3566 SiS_Pr->SiS_RY4COE = 0; 3567 SiS_Pr->SiS_RVBHRS2 = 0; 3568 3569 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex); 3570 3571 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 3572 3573 if(SiS_Pr->UseCustomMode) { 3574 3575 SiS_Pr->SiS_RVBHCMAX = 1; 3576 SiS_Pr->SiS_RVBHCFACT = 1; 3577 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3578 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3579 3580 tempax = SiS_Pr->CHTotal; 3581 if(modeflag & HalfDCLK) tempax <<= 1; 3582 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3583 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3584 3585 } else { 3586 3587 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3588 3589 } 3590 3591 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 3592 3593 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3594 &CRT2Index,&ResIndex); 3595 3596 switch(CRT2Index) { 3597 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break; 3598 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break; 3599 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break; 3600 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break; 3601 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break; 3602 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break; 3603 case 8: TVPtr = SiS_Pr->SiS_StPALData; break; 3604 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break; 3605 case 10: TVPtr = SiS_Pr->SiS_St525iData; break; 3606 case 11: TVPtr = SiS_Pr->SiS_St525pData; break; 3607 case 12: TVPtr = SiS_Pr->SiS_St750pData; break; 3608 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break; 3609 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break; 3610 default: TVPtr = SiS_Pr->SiS_StPALData; break; 3611 } 3612 3613 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX; 3614 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT; 3615 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT; 3616 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT; 3617 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE; 3618 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE; 3619 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff; 3620 if(modeflag & HalfDCLK) { 3621 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS; 3622 if(SiS_Pr->SiS_RVBHRS2) { 3623 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3; 3624 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07; 3625 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax; 3626 else SiS_Pr->SiS_RVBHRS2 += tempax; 3627 } 3628 } else { 3629 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS; 3630 } 3631 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7; 3632 3633 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 3634 3635 if((resinfo == SIS_RI_960x600) || 3636 (resinfo == SIS_RI_1024x768) || 3637 (resinfo == SIS_RI_1280x1024) || 3638 (resinfo == SIS_RI_1280x720)) { 3639 SiS_Pr->SiS_NewFlickerMode = 0x40; 3640 } 3641 3642 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 3643 3644 SiS_Pr->SiS_HT = ExtHiTVHT; 3645 SiS_Pr->SiS_VT = ExtHiTVVT; 3646 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 3647 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 3648 SiS_Pr->SiS_HT = StHiTVHT; 3649 SiS_Pr->SiS_VT = StHiTVVT; 3650 } 3651 } 3652 3653 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3654 3655 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 3656 SiS_Pr->SiS_HT = 1650; 3657 SiS_Pr->SiS_VT = 750; 3658 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 3659 SiS_Pr->SiS_HT = NTSCHT; 3660 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT; 3661 SiS_Pr->SiS_VT = NTSCVT; 3662 } else { 3663 SiS_Pr->SiS_HT = NTSCHT; 3664 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3665 SiS_Pr->SiS_VT = NTSCVT; 3666 } 3667 3668 } else { 3669 3670 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE; 3671 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE; 3672 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE; 3673 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE; 3674 3675 if(modeflag & HalfDCLK) { 3676 SiS_Pr->SiS_RY1COE = 0x00; 3677 SiS_Pr->SiS_RY2COE = 0xf4; 3678 SiS_Pr->SiS_RY3COE = 0x10; 3679 SiS_Pr->SiS_RY4COE = 0x38; 3680 } 3681 3682 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 3683 SiS_Pr->SiS_HT = NTSCHT; 3684 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3685 SiS_Pr->SiS_VT = NTSCVT; 3686 } else { 3687 SiS_Pr->SiS_HT = PALHT; 3688 SiS_Pr->SiS_VT = PALVT; 3689 } 3690 3691 } 3692 3693 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3694 3695 SiS_Pr->SiS_RVBHCMAX = 1; 3696 SiS_Pr->SiS_RVBHCFACT = 1; 3697 3698 if(SiS_Pr->UseCustomMode) { 3699 3700 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3701 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3702 3703 tempax = SiS_Pr->CHTotal; 3704 if(modeflag & HalfDCLK) tempax <<= 1; 3705 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3706 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3707 3708 } else { 3709 3710 bool gotit = false; 3711 3712 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 3713 3714 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3715 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3716 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3717 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3718 gotit = true; 3719 3720 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) { 3721 3722#ifdef CONFIG_FB_SIS_315 3723 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr]; 3724 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1]; 3725 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8); 3726 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4); 3727 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8); 3728 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4); 3729 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8); 3730 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) { 3731 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3; 3732 tempax = (ROMAddr[romptr+9] >> 4) & 0x07; 3733 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax; 3734 else SiS_Pr->SiS_RVBHRS2 += tempax; 3735 } 3736 if(SiS_Pr->SiS_VGAHT) gotit = true; 3737 else { 3738 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 3739 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 3740 SiS_Pr->SiS_RVBHCMAX = 1; 3741 SiS_Pr->SiS_RVBHCFACT = 1; 3742 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3743 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3744 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3745 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3746 SiS_Pr->SiS_RVBHRS2 = 0; 3747 gotit = true; 3748 } 3749#endif 3750 3751 } 3752 3753 if(!gotit) { 3754 3755 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3756 &CRT2Index,&ResIndex); 3757 3758 switch(CRT2Index) { 3759 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3760 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; 3761 case Panel_1280x720 : 3762 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break; 3763 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break; 3764 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break; 3765 case Panel_1280x800 : 3766 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break; 3767 case Panel_1280x800_2 : 3768 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break; 3769 case Panel_1280x854 : 3770 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break; 3771 case Panel_1280x960 : 3772 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; 3773 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; 3774 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3775 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; 3776 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; 3777 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; 3778 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; 3779 case Panel_1680x1050 : 3780 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break; 3781 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break; 3782#ifdef CONFIG_FB_SIS_315 3783 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break; 3784 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3785#endif 3786 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3787 } 3788 3789 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; 3790 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; 3791 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; 3792 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT; 3793 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT; 3794 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT; 3795 3796 } 3797 3798 tempax = SiS_Pr->PanelXRes; 3799 tempbx = SiS_Pr->PanelYRes; 3800 3801 switch(SiS_Pr->SiS_LCDResInfo) { 3802 case Panel_1024x768: 3803 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 3804 if(SiS_Pr->ChipType < SIS_315H) { 3805 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3806 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3807 } 3808 } else { 3809 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527; 3810 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620; 3811 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775; 3812 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775; 3813 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3814 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3815 } 3816 break; 3817 case Panel_1280x960: 3818 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700; 3819 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800; 3820 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960; 3821 break; 3822 case Panel_1280x1024: 3823 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768; 3824 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800; 3825 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864; 3826 break; 3827 case Panel_1600x1200: 3828 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3829 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875; 3830 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000; 3831 } 3832 break; 3833 } 3834 3835 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3836 tempax = SiS_Pr->SiS_VGAHDE; 3837 tempbx = SiS_Pr->SiS_VGAVDE; 3838 } 3839 3840 SiS_Pr->SiS_HDE = tempax; 3841 SiS_Pr->SiS_VDE = tempbx; 3842 } 3843 } 3844} 3845 3846static void 3847SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3848 unsigned short RefreshRateTableIndex) 3849{ 3850 3851 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3852 3853 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 3854 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3855 } else { 3856 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3857 /* Need LVDS Data for LCD on 301B-DH */ 3858 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3859 } else { 3860 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3861 } 3862 } 3863 3864 } else { 3865 3866 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3867 3868 } 3869} 3870 3871/*********************************************/ 3872/* GET LVDS DES (SKEW) DATA */ 3873/*********************************************/ 3874 3875static const struct SiS_LVDSDes * 3876SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr) 3877{ 3878 const struct SiS_LVDSDes *PanelDesPtr = NULL; 3879 3880#ifdef CONFIG_FB_SIS_300 3881 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3882 3883 if(SiS_Pr->ChipType < SIS_315H) { 3884 if(SiS_Pr->SiS_LCDTypeInfo == 4) { 3885 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 3886 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a; 3887 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3888 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a; 3889 } 3890 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 3891 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b; 3892 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3893 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b; 3894 } 3895 } 3896 } 3897 } 3898 } 3899#endif 3900 return PanelDesPtr; 3901} 3902 3903static void 3904SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3905 unsigned short RefreshRateTableIndex) 3906{ 3907 unsigned short modeflag, ResIndex; 3908 const struct SiS_LVDSDes *PanelDesPtr = NULL; 3909 3910 SiS_Pr->SiS_LCDHDES = 0; 3911 SiS_Pr->SiS_LCDVDES = 0; 3912 3913 /* Some special cases */ 3914 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3915 3916 /* Trumpion */ 3917 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 3918 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3919 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3920 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3921 } 3922 } 3923 return; 3924 } 3925 3926 /* 640x480 on LVDS */ 3927 if(SiS_Pr->ChipType < SIS_315H) { 3928 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) { 3929 SiS_Pr->SiS_LCDHDES = 8; 3930 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512; 3931 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436; 3932 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440; 3933 return; 3934 } 3935 } 3936 3937 } /* LCD */ 3938 3939 if( (SiS_Pr->UseCustomMode) || 3940 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) || 3941 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 3942 (SiS_Pr->SiS_CustomT == CUT_PANEL856) || 3943 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) { 3944 return; 3945 } 3946 3947 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3948 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 3949 3950 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3951 3952#ifdef CONFIG_FB_SIS_315 3953 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3954 /* non-pass 1:1 only, see above */ 3955 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { 3956 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2); 3957 } 3958 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) { 3959 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2); 3960 } 3961 } 3962 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3963 switch(SiS_Pr->SiS_CustomT) { 3964 case CUT_UNIWILL1024: 3965 case CUT_UNIWILL10242: 3966 case CUT_CLEVO1400: 3967 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3968 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3969 } 3970 break; 3971 } 3972 switch(SiS_Pr->SiS_LCDResInfo) { 3973 case Panel_1280x1024: 3974 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { 3975 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3976 } 3977 break; 3978 case Panel_1280x800: /* Verified for Averatec 6240 */ 3979 case Panel_1280x800_2: /* Verified for Asus A4L */ 3980 case Panel_1280x854: /* Not verified yet FIXME */ 3981 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3982 break; 3983 } 3984 } 3985#endif 3986 3987 } else { 3988 3989 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 3990 3991 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) { 3992 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256; 3993 } 3994 3995 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) { 3996 3997 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES; 3998 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES; 3999 4000 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 4001 4002 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { 4003 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2); 4004 } 4005 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) { 4006 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2); 4007 } else { 4008 if(SiS_Pr->ChipType < SIS_315H) { 4009 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4010 } else { 4011 switch(SiS_Pr->SiS_LCDResInfo) { 4012 case Panel_800x600: 4013 case Panel_1024x768: 4014 case Panel_1280x1024: 4015 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT; 4016 break; 4017 case Panel_1400x1050: 4018 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4019 break; 4020 } 4021 } 4022 } 4023 4024 } else { 4025 4026 if(SiS_Pr->ChipType < SIS_315H) { 4027#ifdef CONFIG_FB_SIS_300 4028 switch(SiS_Pr->SiS_LCDResInfo) { 4029 case Panel_800x600: 4030 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 4031 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4032 } else { 4033 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3; 4034 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT; 4035 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2; 4036 else SiS_Pr->SiS_LCDVDES -= 4; 4037 } 4038 break; 4039 case Panel_1024x768: 4040 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 4041 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4042 } else { 4043 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1; 4044 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8; 4045 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12; 4046 } 4047 break; 4048 case Panel_1024x600: 4049 default: 4050 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) && 4051 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) { 4052 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4053 } else { 4054 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1; 4055 } 4056 break; 4057 } 4058 4059 switch(SiS_Pr->SiS_LCDTypeInfo) { 4060 case 1: 4061 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; 4062 break; 4063 case 3: /* 640x480 only? */ 4064 SiS_Pr->SiS_LCDHDES = 8; 4065 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512; 4066 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436; 4067 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440; 4068 break; 4069 } 4070#endif 4071 } else { 4072#ifdef CONFIG_FB_SIS_315 4073 switch(SiS_Pr->SiS_LCDResInfo) { 4074 case Panel_1024x768: 4075 case Panel_1280x1024: 4076 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 4077 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4078 } 4079 break; 4080 case Panel_320x240_1: 4081 case Panel_320x240_2: 4082 case Panel_320x240_3: 4083 SiS_Pr->SiS_LCDVDES = 524; 4084 break; 4085 } 4086#endif 4087 } 4088 } 4089 4090 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 4091 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 4092 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 4093 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632; 4094 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) { 4095 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) { 4096 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) { 4097 if(SiS_Pr->ChipType < SIS_315H) { 4098 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320; 4099 } else { 4100#ifdef CONFIG_FB_SIS_315 4101 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480; 4102 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804; 4103 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704; 4104 if(!(modeflag & HalfDCLK)) { 4105 SiS_Pr->SiS_LCDHDES = 320; 4106 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632; 4107 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542; 4108 } 4109#endif 4110 } 4111 } 4112 } 4113 } 4114 } 4115 } 4116} 4117 4118/*********************************************/ 4119/* DISABLE VIDEO BRIDGE */ 4120/*********************************************/ 4121 4122#ifdef CONFIG_FB_SIS_315 4123static int 4124SiS_HandlePWD(struct SiS_Private *SiS_Pr) 4125{ 4126 int ret = 0; 4127#ifdef SET_PWD 4128 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 4129 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr); 4130 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40; 4131 unsigned short temp; 4132 4133 if( (SiS_Pr->SiS_VBType & VB_SISPWD) && 4134 (romptr) && 4135 (SiS_Pr->SiS_PWDOffset) ) { 4136 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]); 4137 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]); 4138 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]); 4139 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]); 4140 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]); 4141 temp = 0x00; 4142 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) { 4143 temp = 0x80; 4144 ret = 1; 4145 } 4146 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp); 4147 } 4148#endif 4149 return ret; 4150} 4151#endif 4152 4153/* NEVER use any variables (VBInfo), this will be called 4154 * from outside the context of modeswitch! 4155 * MUST call getVBType before calling this 4156 */ 4157void 4158SiS_DisableBridge(struct SiS_Private *SiS_Pr) 4159{ 4160#ifdef CONFIG_FB_SIS_315 4161 unsigned short tempah, pushax=0, modenum; 4162#endif 4163 unsigned short temp=0; 4164 4165 if(SiS_Pr->SiS_VBType & VB_SISVB) { 4166 4167 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */ 4168 4169 if(SiS_Pr->ChipType < SIS_315H) { 4170 4171#ifdef CONFIG_FB_SIS_300 /* 300 series */ 4172 4173 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4174 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4175 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 4176 } else { 4177 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4178 } 4179 SiS_PanelDelay(SiS_Pr, 3); 4180 } 4181 if(SiS_Is301B(SiS_Pr)) { 4182 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f); 4183 SiS_ShortDelay(SiS_Pr,1); 4184 } 4185 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); 4186 SiS_DisplayOff(SiS_Pr); 4187 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4188 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4189 SiS_UnLockCRT2(SiS_Pr); 4190 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) { 4191 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 4192 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 4193 } 4194 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4195 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4196 SiS_PanelDelay(SiS_Pr, 2); 4197 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4198 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 4199 } else { 4200 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4201 } 4202 } 4203 4204#endif /* CONFIG_FB_SIS_300 */ 4205 4206 } else { 4207 4208#ifdef CONFIG_FB_SIS_315 /* 315 series */ 4209 4210 int didpwd = 0; 4211 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || 4212 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400); 4213 4214 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f; 4215 4216 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4217 4218#ifdef SET_EMI 4219 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4220 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 4221 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4222 } 4223 } 4224#endif 4225 4226 didpwd = SiS_HandlePWD(SiS_Pr); 4227 4228 if( (modenum <= 0x13) || 4229 (SiS_IsVAMode(SiS_Pr)) || 4230 (!(SiS_IsDualEdge(SiS_Pr))) ) { 4231 if(!didpwd) { 4232 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe); 4233 if(custom1) SiS_PanelDelay(SiS_Pr, 3); 4234 } else { 4235 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc); 4236 } 4237 } 4238 4239 if(!custom1) { 4240 SiS_DDC2Delay(SiS_Pr,0xff00); 4241 SiS_DDC2Delay(SiS_Pr,0xe000); 4242 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 4243 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06); 4244 if(IS_SIS740) { 4245 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4246 } 4247 SiS_PanelDelay(SiS_Pr, 3); 4248 } 4249 4250 } 4251 4252 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4253 /* if(SiS_Pr->ChipType < SIS_340) {*/ 4254 tempah = 0xef; 4255 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7; 4256 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4257 /*}*/ 4258 } 4259 4260 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4261 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10); 4262 } 4263 4264 tempah = 0x3f; 4265 if(SiS_IsDualEdge(SiS_Pr)) { 4266 tempah = 0x7f; 4267 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf; 4268 } 4269 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4270 4271 if((SiS_IsVAMode(SiS_Pr)) || 4272 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) { 4273 4274 SiS_DisplayOff(SiS_Pr); 4275 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4276 SiS_PanelDelay(SiS_Pr, 2); 4277 } 4278 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4279 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF); 4280 4281 } 4282 4283 if((!(SiS_IsVAMode(SiS_Pr))) || 4284 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) { 4285 4286 if(!(SiS_IsDualEdge(SiS_Pr))) { 4287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf); 4288 SiS_DisplayOff(SiS_Pr); 4289 } 4290 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4291 4292 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4293 SiS_PanelDelay(SiS_Pr, 2); 4294 } 4295 4296 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4297 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4298 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4299 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4300 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4301 4302 } 4303 4304 if(SiS_IsNotM650orLater(SiS_Pr)) { 4305 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4306 } 4307 4308 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4309 4310 if( (!(SiS_IsVAMode(SiS_Pr))) && 4311 (!(SiS_CRT2IsLCD(SiS_Pr))) && 4312 (!(SiS_IsDualEdge(SiS_Pr))) ) { 4313 4314 if(custom1) SiS_PanelDelay(SiS_Pr, 2); 4315 if(!didpwd) { 4316 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 4317 } 4318 if(custom1) SiS_PanelDelay(SiS_Pr, 4); 4319 } 4320 4321 if(!custom1) { 4322 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax); 4323 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4324 if(SiS_IsVAorLCD(SiS_Pr)) { 4325 SiS_PanelDelayLoop(SiS_Pr, 3, 20); 4326 } 4327 } 4328 } 4329 4330 } 4331 4332#endif /* CONFIG_FB_SIS_315 */ 4333 4334 } 4335 4336 } else { /* ============ For 301 ================ */ 4337 4338 if(SiS_Pr->ChipType < SIS_315H) { 4339#ifdef CONFIG_FB_SIS_300 4340 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4341 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4342 SiS_PanelDelay(SiS_Pr, 3); 4343 } 4344#endif 4345 } 4346 4347 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */ 4348 SiS_DisplayOff(SiS_Pr); 4349 4350 if(SiS_Pr->ChipType >= SIS_315H) { 4351 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4352 } 4353 4354 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */ 4355 4356 if(SiS_Pr->ChipType >= SIS_315H) { 4357 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4358 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4359 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4360 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4361 } else { 4362#ifdef CONFIG_FB_SIS_300 4363 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */ 4364 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4365 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4366 SiS_PanelDelay(SiS_Pr, 2); 4367 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4368 } 4369#endif 4370 } 4371 4372 } 4373 4374 } else { /* ============ For LVDS =============*/ 4375 4376 if(SiS_Pr->ChipType < SIS_315H) { 4377 4378#ifdef CONFIG_FB_SIS_300 /* 300 series */ 4379 4380 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 4381 SiS_SetCH700x(SiS_Pr,0x0E,0x09); 4382 } 4383 4384 if(SiS_Pr->ChipType == SIS_730) { 4385 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4386 SiS_WaitVBRetrace(SiS_Pr); 4387 } 4388 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4389 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4390 SiS_PanelDelay(SiS_Pr, 3); 4391 } 4392 } else { 4393 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4394 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4395 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4396 SiS_WaitVBRetrace(SiS_Pr); 4397 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) { 4398 SiS_DisplayOff(SiS_Pr); 4399 } 4400 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4401 SiS_PanelDelay(SiS_Pr, 3); 4402 } 4403 } 4404 } 4405 } 4406 4407 SiS_DisplayOff(SiS_Pr); 4408 4409 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4410 4411 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4412 SiS_UnLockCRT2(SiS_Pr); 4413 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 4414 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 4415 4416 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4417 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4418 SiS_PanelDelay(SiS_Pr, 2); 4419 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4420 } 4421 4422#endif /* CONFIG_FB_SIS_300 */ 4423 4424 } else { 4425 4426#ifdef CONFIG_FB_SIS_315 /* 315 series */ 4427 4428 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4429 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */ 4430 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18); 4431 /* } */ 4432 } 4433 4434 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4435 4436 if(SiS_Pr->ChipType == SIS_740) { 4437 temp = SiS_GetCH701x(SiS_Pr,0x61); 4438 if(temp < 1) { 4439 SiS_SetCH701x(SiS_Pr,0x76,0xac); 4440 SiS_SetCH701x(SiS_Pr,0x66,0x00); 4441 } 4442 4443 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4444 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) { 4445 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 4446 } 4447 } 4448 4449 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4450 (SiS_IsVAMode(SiS_Pr)) ) { 4451 SiS_Chrontel701xBLOff(SiS_Pr); 4452 SiS_Chrontel701xOff(SiS_Pr); 4453 } 4454 4455 if(SiS_Pr->ChipType != SIS_740) { 4456 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4457 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) { 4458 SiS_SetCH701x(SiS_Pr,0x49,0x01); 4459 } 4460 } 4461 4462 } 4463 4464 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4465 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4466 SiS_PanelDelay(SiS_Pr, 3); 4467 } 4468 4469 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4470 (!(SiS_IsDualEdge(SiS_Pr))) || 4471 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) { 4472 SiS_DisplayOff(SiS_Pr); 4473 } 4474 4475 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4476 (!(SiS_IsDualEdge(SiS_Pr))) || 4477 (!(SiS_IsVAMode(SiS_Pr))) ) { 4478 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4479 } 4480 4481 if(SiS_Pr->ChipType == SIS_740) { 4482 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4483 } 4484 4485 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4486 4487 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4488 (!(SiS_IsDualEdge(SiS_Pr))) || 4489 (!(SiS_IsVAMode(SiS_Pr))) ) { 4490 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4491 } 4492 4493 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4494 if(SiS_CRT2IsLCD(SiS_Pr)) { 4495 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4496 if(SiS_Pr->ChipType == SIS_550) { 4497 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf); 4498 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef); 4499 } 4500 } 4501 } else { 4502 if(SiS_Pr->ChipType == SIS_740) { 4503 if(SiS_IsLCDOrLCDA(SiS_Pr)) { 4504 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4505 } 4506 } else if(SiS_IsVAMode(SiS_Pr)) { 4507 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4508 } 4509 } 4510 4511 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4512 if(SiS_IsDualEdge(SiS_Pr)) { 4513 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */ 4514 } else { 4515 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 4516 } 4517 } 4518 4519 SiS_UnLockCRT2(SiS_Pr); 4520 4521 if(SiS_Pr->ChipType == SIS_550) { 4522 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/ 4523 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */ 4524 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4525 (!(SiS_IsDualEdge(SiS_Pr))) || 4526 (!(SiS_IsVAMode(SiS_Pr))) ) { 4527 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 4528 } 4529 4530 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4531 if(SiS_CRT2IsLCD(SiS_Pr)) { 4532 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4533 SiS_PanelDelay(SiS_Pr, 2); 4534 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4535 } 4536 } 4537 } 4538 4539#endif /* CONFIG_FB_SIS_315 */ 4540 4541 } /* 315 series */ 4542 4543 } /* LVDS */ 4544 4545} 4546 4547/*********************************************/ 4548/* ENABLE VIDEO BRIDGE */ 4549/*********************************************/ 4550 4551/* NEVER use any variables (VBInfo), this will be called 4552 * from outside the context of a mode switch! 4553 * MUST call getVBType before calling this 4554 */ 4555static 4556void 4557SiS_EnableBridge(struct SiS_Private *SiS_Pr) 4558{ 4559 unsigned short temp=0, tempah; 4560#ifdef CONFIG_FB_SIS_315 4561 unsigned short temp1, pushax=0; 4562 bool delaylong = false; 4563#endif 4564 4565 if(SiS_Pr->SiS_VBType & VB_SISVB) { 4566 4567 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */ 4568 4569 if(SiS_Pr->ChipType < SIS_315H) { 4570 4571#ifdef CONFIG_FB_SIS_300 /* 300 series */ 4572 4573 if(SiS_CRT2IsLCD(SiS_Pr)) { 4574 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4575 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4576 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { 4577 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4578 } 4579 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) { 4580 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) { 4581 SiS_PanelDelay(SiS_Pr, 0); 4582 } 4583 } 4584 } 4585 4586 if((SiS_Pr->SiS_VBType & VB_NoLCD) && 4587 (SiS_CRT2IsLCD(SiS_Pr))) { 4588 4589 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */ 4590 SiS_DisplayOn(SiS_Pr); 4591 SiS_UnLockCRT2(SiS_Pr); 4592 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 4593 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4594 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 4595 } else { 4596 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 4597 } 4598 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4599 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4600 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4601 SiS_PanelDelay(SiS_Pr, 1); 4602 } 4603 SiS_WaitVBRetrace(SiS_Pr); 4604 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4605 } 4606 } 4607 4608 } else { 4609 4610 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4611 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4612 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4613 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4614 } 4615 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4616 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4617 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ 4618 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0); 4619 SiS_DisplayOn(SiS_Pr); 4620 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4621 if(SiS_CRT2IsLCD(SiS_Pr)) { 4622 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4623 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4624 SiS_PanelDelay(SiS_Pr, 1); 4625 } 4626 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 4627 } 4628 } 4629 } 4630 4631 } 4632 4633 4634#endif /* CONFIG_FB_SIS_300 */ 4635 4636 } else { 4637 4638#ifdef CONFIG_FB_SIS_315 /* 315 series */ 4639 4640#ifdef SET_EMI 4641 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0; 4642 int didpwd = 0; 4643 /* unsigned short emidelay=0; */ 4644#endif 4645 4646 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4647 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef); 4648#ifdef SET_EMI 4649 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4650 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4651 } 4652#endif 4653 } 4654 4655 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4656 /*if(SiS_Pr->ChipType < SIS_340) { */ 4657 tempah = 0x10; 4658 if(SiS_LCDAEnabled(SiS_Pr)) { 4659 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18; 4660 else tempah = 0x08; 4661 } 4662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4663 /*}*/ 4664 } 4665 4666 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4667 4668 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 4669 SiS_DisplayOff(SiS_Pr); 4670 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06); 4671 if(IS_SIS740) { 4672 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4673 } 4674 4675 didpwd = SiS_HandlePWD(SiS_Pr); 4676 4677 if(SiS_IsVAorLCD(SiS_Pr)) { 4678 if(!didpwd) { 4679 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 4680 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4681 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4682 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4683 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4684 SiS_GenericDelay(SiS_Pr, 17664); 4685 } 4686 } 4687 } else { 4688 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4689 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4690 SiS_GenericDelay(SiS_Pr, 17664); 4691 } 4692 } 4693 } 4694 4695 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) { 4696 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4697 delaylong = true; 4698 } 4699 4700 } 4701 4702 if(!(SiS_IsVAMode(SiS_Pr))) { 4703 4704 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; 4705 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4706 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4707 if(!(tempah & SetCRT2ToRAMDAC)) { 4708 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20; 4709 } 4710 } 4711 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4712 4713 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4714 4715 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4716 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4717 4718 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4719 SiS_PanelDelay(SiS_Pr, 2); 4720 } 4721 4722 } else { 4723 4724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20); 4725 4726 } 4727 4728 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20); 4729 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4730 4731 if(SiS_Pr->SiS_VBType & VB_SISPOWER) { 4732 if( (SiS_LCDAEnabled(SiS_Pr)) || 4733 (SiS_CRT2IsLCD(SiS_Pr)) ) { 4734 /* Enable "LVDS PLL power on" (even on 301C) */ 4735 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f); 4736 /* Enable "LVDS Driver Power on" (even on 301C) */ 4737 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f); 4738 } 4739 } 4740 4741 tempah = 0xc0; 4742 if(SiS_IsDualEdge(SiS_Pr)) { 4743 tempah = 0x80; 4744 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40; 4745 } 4746 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4747 4748 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4749 4750 SiS_PanelDelay(SiS_Pr, 2); 4751 4752 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10); 4753 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4754 4755 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 4756#ifdef SET_EMI 4757 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4758 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4759 SiS_GenericDelay(SiS_Pr, 2048); 4760 } 4761#endif 4762 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c); 4763 4764 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4765#ifdef SET_EMI 4766 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 4767 4768 if(SiS_Pr->SiS_ROMNew) { 4769 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 4770 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr); 4771 if(romptr) { 4772 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4773 SiS_Pr->EMI_30 = 0; 4774 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0]; 4775 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1]; 4776 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2]; 4777 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40; 4778 /* emidelay = SISGETROMW((romptr + 0x22)); */ 4779 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true; 4780 } 4781 } 4782 4783 /* (P4_30|0x40) */ 4784 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */ 4785 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */ 4786 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */ 4787 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */ 4788 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */ 4789 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */ 4790 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */ 4791 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */ 4792 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */ 4793 4794 if(SiS_Pr->HaveEMI) { 4795 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31; 4796 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33; 4797 } else { 4798 r30 = 0; 4799 } 4800 4801 /* EMI_30 is read at driver start; however, the BIOS sets this 4802 * (if it is used) only if the LCD is in use. In case we caught 4803 * the machine while on TV output, this bit is not set and we 4804 * don't know if it should be set - hence our detection is wrong. 4805 * Work-around this here: 4806 */ 4807 4808 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) { 4809 switch((cr36 & 0x0f)) { 4810 case 2: 4811 r30 |= 0x40; 4812 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40; 4813 if(!SiS_Pr->HaveEMI) { 4814 r31 = 0x05; r32 = 0x60; r33 = 0x33; 4815 if((cr36 & 0xf0) == 0x30) { 4816 r31 = 0x0d; r32 = 0x70; r33 = 0x40; 4817 } 4818 } 4819 break; 4820 case 3: /* 1280x1024 */ 4821 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40; 4822 if(!SiS_Pr->HaveEMI) { 4823 r31 = 0x12; r32 = 0xd0; r33 = 0x6b; 4824 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 4825 r31 = 0x0d; r32 = 0x70; r33 = 0x6b; 4826 } 4827 } 4828 break; 4829 case 9: /* 1400x1050 */ 4830 r30 |= 0x40; 4831 if(!SiS_Pr->HaveEMI) { 4832 r31 = 0x05; r32 = 0x60; r33 = 0x00; 4833 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) { 4834 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */ 4835 } 4836 } 4837 break; 4838 case 11: /* 1600x1200 - unknown */ 4839 r30 |= 0x40; 4840 if(!SiS_Pr->HaveEMI) { 4841 r31 = 0x05; r32 = 0x60; r33 = 0x00; 4842 } 4843 } 4844 } 4845 4846 /* BIOS values don't work so well sometimes */ 4847 if(!SiS_Pr->OverruleEMI) { 4848#ifdef COMPAL_HACK 4849 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) { 4850 if((cr36 & 0x0f) == 0x09) { 4851 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00; 4852 } 4853 } 4854#endif 4855#ifdef COMPAQ_HACK 4856 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 4857 if((cr36 & 0x0f) == 0x03) { 4858 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b; 4859 } 4860 } 4861#endif 4862#ifdef ASUS_HACK 4863 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4864 if((cr36 & 0x0f) == 0x02) { 4865 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */ 4866 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */ 4867 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */ 4868 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */ 4869 } 4870 } 4871#endif 4872 } 4873 4874 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) { 4875 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4876 SiS_GenericDelay(SiS_Pr, 2048); 4877 } 4878 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31); 4879 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32); 4880 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33); 4881#endif /* SET_EMI */ 4882 4883 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 4884 4885#ifdef SET_EMI 4886 if( (SiS_LCDAEnabled(SiS_Pr)) || 4887 (SiS_CRT2IsLCD(SiS_Pr)) ) { 4888 if(r30 & 0x40) { 4889 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/ 4890 SiS_PanelDelayLoop(SiS_Pr, 3, 5); 4891 if(delaylong) { 4892 SiS_PanelDelayLoop(SiS_Pr, 3, 5); 4893 delaylong = false; 4894 } 4895 SiS_WaitVBRetrace(SiS_Pr); 4896 SiS_WaitVBRetrace(SiS_Pr); 4897 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4898 SiS_GenericDelay(SiS_Pr, 1280); 4899 } 4900 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */ 4901 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/ 4902 } 4903 } 4904#endif 4905 } 4906 } 4907 4908 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4909 if(SiS_IsVAorLCD(SiS_Pr)) { 4910 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4911 if(delaylong) { 4912 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4913 } 4914 SiS_WaitVBRetrace(SiS_Pr); 4915 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4916 SiS_GenericDelay(SiS_Pr, 2048); 4917 SiS_WaitVBRetrace(SiS_Pr); 4918 } 4919 if(!didpwd) { 4920 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 4921 } else { 4922 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03); 4923 } 4924 } 4925 } 4926 4927 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax); 4928 SiS_DisplayOn(SiS_Pr); 4929 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff); 4930 4931 } 4932 4933 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4934 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4935 } 4936 4937#endif /* CONFIG_FB_SIS_315 */ 4938 4939 } 4940 4941 } else { /* ============ For 301 ================ */ 4942 4943 if(SiS_Pr->ChipType < SIS_315H) { 4944 if(SiS_CRT2IsLCD(SiS_Pr)) { 4945 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4946 SiS_PanelDelay(SiS_Pr, 0); 4947 } 4948 } 4949 4950 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4951 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4952 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4953 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4954 } 4955 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4956 4957 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4958 4959 if(SiS_Pr->ChipType >= SIS_315H) { 4960 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 4961 if(!(temp & 0x80)) { 4962 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */ 4963 } 4964 } 4965 4966 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ 4967 4968 SiS_VBLongWait(SiS_Pr); 4969 SiS_DisplayOn(SiS_Pr); 4970 if(SiS_Pr->ChipType >= SIS_315H) { 4971 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4972 } 4973 SiS_VBLongWait(SiS_Pr); 4974 4975 if(SiS_Pr->ChipType < SIS_315H) { 4976 if(SiS_CRT2IsLCD(SiS_Pr)) { 4977 SiS_PanelDelay(SiS_Pr, 1); 4978 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4979 } 4980 } 4981 4982 } 4983 4984 } else { /* =================== For LVDS ================== */ 4985 4986 if(SiS_Pr->ChipType < SIS_315H) { 4987 4988#ifdef CONFIG_FB_SIS_300 /* 300 series */ 4989 4990 if(SiS_CRT2IsLCD(SiS_Pr)) { 4991 if(SiS_Pr->ChipType == SIS_730) { 4992 SiS_PanelDelay(SiS_Pr, 1); 4993 SiS_PanelDelay(SiS_Pr, 1); 4994 SiS_PanelDelay(SiS_Pr, 1); 4995 } 4996 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4997 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) { 4998 SiS_PanelDelay(SiS_Pr, 0); 4999 } 5000 } 5001 5002 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 5003 SiS_DisplayOn(SiS_Pr); 5004 SiS_UnLockCRT2(SiS_Pr); 5005 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 5006 if(SiS_BridgeInSlavemode(SiS_Pr)) { 5007 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 5008 } else { 5009 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 5010 } 5011 5012 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 5013 if(!(SiS_CRT2IsLCD(SiS_Pr))) { 5014 SiS_WaitVBRetrace(SiS_Pr); 5015 SiS_SetCH700x(SiS_Pr,0x0E,0x0B); 5016 } 5017 } 5018 5019 if(SiS_CRT2IsLCD(SiS_Pr)) { 5020 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 5021 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 5022 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 5023 SiS_PanelDelay(SiS_Pr, 1); 5024 SiS_PanelDelay(SiS_Pr, 1); 5025 } 5026 SiS_WaitVBRetrace(SiS_Pr); 5027 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 5028 } 5029 } 5030 } 5031 5032#endif /* CONFIG_FB_SIS_300 */ 5033 5034 } else { 5035 5036#ifdef CONFIG_FB_SIS_315 /* 315 series */ 5037 5038 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 5039 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */ 5040 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18); 5041 /*}*/ 5042 } 5043 5044 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 5045 if(SiS_CRT2IsLCD(SiS_Pr)) { 5046 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 5047 SiS_PanelDelay(SiS_Pr, 0); 5048 } 5049 } 5050 5051 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 5052 SiS_UnLockCRT2(SiS_Pr); 5053 5054 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 5055 5056 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5057 temp = SiS_GetCH701x(SiS_Pr,0x66); 5058 temp &= 0x20; 5059 SiS_Chrontel701xBLOff(SiS_Pr); 5060 } 5061 5062 if(SiS_Pr->ChipType != SIS_550) { 5063 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 5064 } 5065 5066 if(SiS_Pr->ChipType == SIS_740) { 5067 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5068 if(SiS_IsLCDOrLCDA(SiS_Pr)) { 5069 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 5070 } 5071 } 5072 } 5073 5074 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 5075 if(!(temp1 & 0x80)) { 5076 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); 5077 } 5078 5079 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5080 if(temp) { 5081 SiS_Chrontel701xBLOn(SiS_Pr); 5082 } 5083 } 5084 5085 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 5086 if(SiS_CRT2IsLCD(SiS_Pr)) { 5087 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 5088 if(SiS_Pr->ChipType == SIS_550) { 5089 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40); 5090 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10); 5091 } 5092 } 5093 } else if(SiS_IsVAMode(SiS_Pr)) { 5094 if(SiS_Pr->ChipType != SIS_740) { 5095 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 5096 } 5097 } 5098 5099 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 5100 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 5101 } 5102 5103 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5104 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) { 5105 SiS_Chrontel701xOn(SiS_Pr); 5106 } 5107 if( (SiS_IsVAMode(SiS_Pr)) || 5108 (SiS_IsLCDOrLCDA(SiS_Pr)) ) { 5109 SiS_ChrontelDoSomething1(SiS_Pr); 5110 } 5111 } 5112 5113 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5114 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 5115 if( (SiS_IsVAMode(SiS_Pr)) || 5116 (SiS_IsLCDOrLCDA(SiS_Pr)) ) { 5117 SiS_Chrontel701xBLOn(SiS_Pr); 5118 SiS_ChrontelInitTVVSync(SiS_Pr); 5119 } 5120 } 5121 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 5122 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 5123 if(SiS_CRT2IsLCD(SiS_Pr)) { 5124 SiS_PanelDelay(SiS_Pr, 1); 5125 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 5126 } 5127 } 5128 } 5129 5130#endif /* CONFIG_FB_SIS_315 */ 5131 5132 } /* 310 series */ 5133 5134 } /* LVDS */ 5135 5136} 5137 5138/*********************************************/ 5139/* SET PART 1 REGISTER GROUP */ 5140/*********************************************/ 5141 5142/* Set CRT2 OFFSET / PITCH */ 5143static void 5144SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 5145 unsigned short RRTI) 5146{ 5147 unsigned short offset; 5148 unsigned char temp; 5149 5150 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return; 5151 5152 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI); 5153 5154 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF)); 5155 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8)); 5156 5157 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1); 5158 if(offset & 0x07) temp++; 5159 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp); 5160} 5161 5162/* Set CRT2 sync and PanelLink mode */ 5163static void 5164SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex) 5165{ 5166 unsigned short tempah=0, tempbl, infoflag; 5167 5168 tempbl = 0xC0; 5169 5170 if(SiS_Pr->UseCustomMode) { 5171 infoflag = SiS_Pr->CInfoFlag; 5172 } else { 5173 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 5174 } 5175 5176 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */ 5177 5178 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5179 tempah = 0; 5180 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) { 5181 tempah = SiS_Pr->SiS_LCDInfo; 5182 } else tempah = infoflag >> 8; 5183 tempah &= 0xC0; 5184 tempah |= 0x20; 5185 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5186 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5187 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 5188 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 5189 tempah |= 0xf0; 5190 } 5191 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 5192 (SiS_Pr->SiS_IF_DEF_DSTN) || 5193 (SiS_Pr->SiS_IF_DEF_TRUMPION) || 5194 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 5195 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 5196 tempah |= 0x30; 5197 } 5198 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 5199 (SiS_Pr->SiS_IF_DEF_DSTN) ) { 5200 tempah &= ~0xc0; 5201 } 5202 } 5203 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5204 if(SiS_Pr->ChipType >= SIS_315H) { 5205 tempah >>= 3; 5206 tempah &= 0x18; 5207 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah); 5208 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */ 5209 } else { 5210 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0); 5211 } 5212 } else { 5213 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5214 } 5215 5216 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5217 5218 if(SiS_Pr->ChipType < SIS_315H) { 5219 5220#ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */ 5221 5222 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */ 5223 5224 tempah = infoflag >> 8; 5225 tempbl = 0; 5226 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5227 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5228 tempah = SiS_Pr->SiS_LCDInfo; 5229 tempbl = (tempah >> 6) & 0x03; 5230 } 5231 } 5232 tempah &= 0xC0; 5233 tempah |= 0x20; 5234 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5235 tempah |= 0xc0; 5236 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5237 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 5238 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5239 } 5240 5241 } else { /* 630 - 301 */ 5242 5243 tempah = ((infoflag >> 8) & 0xc0) | 0x20; 5244 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5245 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5246 5247 } 5248 5249#endif /* CONFIG_FB_SIS_300 */ 5250 5251 } else { 5252 5253#ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */ 5254 5255 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */ 5256 5257 tempbl = 0; 5258 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) && 5259 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5260 tempah = infoflag >> 8; 5261 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5262 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6); 5263 } 5264 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) && 5265 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) { 5266 tempah = infoflag >> 8; 5267 tempbl = 0x03; 5268 } else { 5269 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 5270 tempbl = (tempah >> 6) & 0x03; 5271 tempbl |= 0x08; 5272 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04; 5273 } 5274 tempah &= 0xC0; 5275 tempah |= 0x20; 5276 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5277 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0; 5278 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5279 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 5280 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5281 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5282 } 5283 } 5284 5285 } else { /* 315 - TMDS */ 5286 5287 tempah = tempbl = infoflag >> 8; 5288 if(!SiS_Pr->UseCustomMode) { 5289 tempbl = 0; 5290 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5291 if(ModeNo <= 0x13) { 5292 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5293 } 5294 } 5295 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5296 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5297 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5298 tempah = SiS_Pr->SiS_LCDInfo; 5299 tempbl = (tempah >> 6) & 0x03; 5300 } 5301 } 5302 } 5303 } 5304 tempah &= 0xC0; 5305 tempah |= 0x20; 5306 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5307 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 5308 /* Imitate BIOS bug */ 5309 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0; 5310 } 5311 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5312 tempah >>= 3; 5313 tempah &= 0x18; 5314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah); 5315 } else { 5316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5317 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 5318 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5319 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5320 } 5321 } 5322 } 5323 5324 } 5325#endif /* CONFIG_FB_SIS_315 */ 5326 } 5327 } 5328} 5329 5330/* Set CRT2 FIFO on 300/540/630/730 */ 5331#ifdef CONFIG_FB_SIS_300 5332static void 5333SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo) 5334{ 5335 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 5336 unsigned short temp, index, modeidindex, refreshratetableindex; 5337 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0; 5338 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup; 5339 unsigned int data, pci50, pciA0; 5340 static const unsigned char colortharray[] = { 5341 1, 1, 2, 2, 3, 4 5342 }; 5343 5344 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate; 5345 5346 if(!SiS_Pr->CRT1UsesCustomMode) { 5347 5348 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */ 5349 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex); 5350 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 5351 SiS_Pr->SiS_SelectCRT2Rate = 0; 5352 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex); 5353 5354 if(CRT1ModeNo >= 0x13) { 5355 /* Get VCLK */ 5356 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide); 5357 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 5358 5359 /* Get colordepth */ 5360 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1; 5361 if(!colorth) colorth++; 5362 } 5363 5364 } else { 5365 5366 CRT1ModeNo = 0xfe; 5367 5368 /* Get VCLK */ 5369 VCLK = SiS_Pr->CSRClock_CRT1; 5370 5371 /* Get color depth */ 5372 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)]; 5373 5374 } 5375 5376 if(CRT1ModeNo >= 0x13) { 5377 /* Get MCLK */ 5378 if(SiS_Pr->ChipType == SIS_300) { 5379 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A); 5380 } else { 5381 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A); 5382 } 5383 index &= 0x07; 5384 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; 5385 5386 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1; 5387 if(!temp) temp++; 5388 temp <<= 2; 5389 5390 data2 = temp - ((colorth * VCLK) / MCLK); 5391 5392 temp = (28 * 16) % data2; 5393 data2 = (28 * 16) / data2; 5394 if(temp) data2++; 5395 5396 if(SiS_Pr->ChipType == SIS_300) { 5397 5398 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl); 5399 data = SiS_GetFIFOThresholdB300(tempbx, tempcl); 5400 5401 } else { 5402 5403 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); 5404 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0); 5405 5406 if(SiS_Pr->ChipType == SIS_730) { 5407 5408 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3); 5409 index += (unsigned short)(((pci50 >> 9)) & 0x03); 5410 5411 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */ 5412 index = 0; /* -- do it like the BIOS anyway... */ 5413 5414 } else { 5415 5416 pci50 >>= 24; 5417 pciA0 >>= 24; 5418 5419 index = (pci50 >> 1) & 0x07; 5420 5421 if(pci50 & 0x01) index += 6; 5422 if(!(pciA0 & 0x01)) index += 24; 5423 5424 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12; 5425 5426 } 5427 5428 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15; 5429 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5; 5430 5431 } 5432 5433 data += data2; /* CRT1 Request Period */ 5434 5435 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5436 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; 5437 5438 if(!SiS_Pr->UseCustomMode) { 5439 5440 CRT2ModeNo = ModeNo; 5441 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex); 5442 5443 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex); 5444 5445 /* Get VCLK */ 5446 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex); 5447 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 5448 5449 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 5450 if(SiS_Pr->SiS_UseROM) { 5451 if(ROMAddr[0x220] & 0x01) { 5452 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8); 5453 } 5454 } 5455 } 5456 5457 } else { 5458 5459 /* Get VCLK */ 5460 CRT2ModeNo = 0xfe; 5461 VCLK = SiS_Pr->CSRClock; 5462 5463 } 5464 5465 /* Get colordepth */ 5466 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1; 5467 if(!colorth) colorth++; 5468 5469 data = data * VCLK * colorth; 5470 temp = data % (MCLK << 4); 5471 data = data / (MCLK << 4); 5472 if(temp) data++; 5473 5474 if(data < 6) data = 6; 5475 else if(data > 0x14) data = 0x14; 5476 5477 if(SiS_Pr->ChipType == SIS_300) { 5478 temp = 0x16; 5479 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) 5480 temp = 0x13; 5481 } else { 5482 temp = 0x16; 5483 if(( (SiS_Pr->ChipType == SIS_630) || 5484 (SiS_Pr->ChipType == SIS_730) ) && 5485 (SiS_Pr->ChipRevision >= 0x30)) 5486 temp = 0x1b; 5487 } 5488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp); 5489 5490 if((SiS_Pr->ChipType == SIS_630) && 5491 (SiS_Pr->ChipRevision >= 0x30)) { 5492 if(data > 0x13) data = 0x13; 5493 } 5494 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data); 5495 5496 } else { /* If mode <= 0x13, we just restore everything */ 5497 5498 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5499 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; 5500 5501 } 5502} 5503#endif 5504 5505/* Set CRT2 FIFO on 315/330 series */ 5506#ifdef CONFIG_FB_SIS_315 5507static void 5508SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr) 5509{ 5510 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B); 5511 if( (SiS_Pr->ChipType == SIS_760) && 5512 (SiS_Pr->SiS_SysFlags & SF_760LFB) && 5513 (SiS_Pr->SiS_ModeType == Mode32Bpp) && 5514 (SiS_Pr->SiS_VGAHDE >= 1280) && 5515 (SiS_Pr->SiS_VGAVDE >= 1024) ) { 5516 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03); 5517 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b); 5518 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0); 5519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01); 5520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0); 5521 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e); 5522 } else { 5523 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04); 5524 } 5525 5526} 5527#endif 5528 5529static unsigned short 5530SiS_GetVGAHT2(struct SiS_Private *SiS_Pr) 5531{ 5532 unsigned int tempax,tempbx; 5533 5534 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX; 5535 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT; 5536 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx; 5537 return (unsigned short)tempax; 5538} 5539 5540/* Set Part 1 / SiS bridge slave mode */ 5541static void 5542SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, 5543 unsigned short RefreshRateTableIndex) 5544{ 5545 unsigned short temp, modeflag, i, j, xres=0, VGAVDE; 5546 static const unsigned short CRTranslation[] = { 5547 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */ 5548 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 5549 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */ 5550 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00, 5551 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */ 5552 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00 5553 }; 5554 5555 if(ModeNo <= 0x13) { 5556 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 5557 } else if(SiS_Pr->UseCustomMode) { 5558 modeflag = SiS_Pr->CModeFlag; 5559 xres = SiS_Pr->CHDisplay; 5560 } else { 5561 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5562 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes; 5563 } 5564 5565 /* The following is only done if bridge is in slave mode: */ 5566 5567 if(SiS_Pr->ChipType >= SIS_315H) { 5568 if(xres >= 1600) { /* BIOS: == 1600 */ 5569 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04); 5570 } 5571 } 5572 5573 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */ 5574 5575 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE; 5576 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1; 5577 5578 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay; 5579 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5580 SiS_Pr->CHBlankStart += 16; 5581 } 5582 5583 SiS_Pr->CHBlankEnd = 32; 5584 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5585 if(xres == 1600) SiS_Pr->CHBlankEnd += 80; 5586 } 5587 5588 temp = SiS_Pr->SiS_VGAHT - 96; 5589 if(!(modeflag & HalfDCLK)) temp -= 32; 5590 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 5591 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04); 5592 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2); 5593 temp -= 3; 5594 temp <<= 3; 5595 } else { 5596 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2; 5597 } 5598 SiS_Pr->CHSyncStart = temp; 5599 5600 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */ 5601 5602 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */ 5603 5604 VGAVDE = SiS_Pr->SiS_VGAVDE; 5605 if (VGAVDE == 357) VGAVDE = 350; 5606 else if(VGAVDE == 360) VGAVDE = 350; 5607 else if(VGAVDE == 375) VGAVDE = 350; 5608 else if(VGAVDE == 405) VGAVDE = 400; 5609 else if(VGAVDE == 420) VGAVDE = 400; 5610 else if(VGAVDE == 525) VGAVDE = 480; 5611 else if(VGAVDE == 1056) VGAVDE = 1024; 5612 SiS_Pr->CVDisplay = VGAVDE; 5613 5614 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay; 5615 5616 SiS_Pr->CVBlankEnd = 1; 5617 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226; 5618 5619 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1; 5620 SiS_Pr->CVSyncStart = VGAVDE + temp; 5621 5622 temp >>= 3; 5623 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp; 5624 5625 SiS_CalcCRRegisters(SiS_Pr, 0); 5626 SiS_Pr->CCRT1CRTC[16] &= ~0xE0; 5627 5628 for(i = 0; i <= 7; i++) { 5629 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]); 5630 } 5631 for(i = 0x10, j = 8; i <= 0x12; i++, j++) { 5632 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5633 } 5634 for(i = 0x15, j = 11; i <= 0x16; i++, j++) { 5635 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5636 } 5637 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) { 5638 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5639 } 5640 5641 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0; 5642 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp); 5643 5644 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5; 5645 if(modeflag & DoubleScanMode) temp |= 0x80; 5646 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp); 5647 5648 temp = 0; 5649 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01); 5650 if(modeflag & HalfDCLK) temp |= 0x08; 5651 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */ 5652 5653 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */ 5654 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */ 5655 5656 temp = 0; 5657 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5658 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7; 5659 } 5660 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */ 5661 5662 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5663 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */ 5664} 5665 5666/* Setup panel link 5667 * This is used for LVDS, LCDA and Chrontel TV output 5668 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA 5669 */ 5670static void 5671SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 5672 unsigned short RefreshRateTableIndex) 5673{ 5674 unsigned short modeflag, resinfo = 0; 5675 unsigned short push2, tempax, tempbx, tempcx, temp; 5676 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0; 5677 bool islvds = false, issis = false, chkdclkfirst = false; 5678#ifdef CONFIG_FB_SIS_300 5679 unsigned short crt2crtc = 0; 5680#endif 5681#ifdef CONFIG_FB_SIS_315 5682 unsigned short pushcx; 5683#endif 5684 5685 if(ModeNo <= 0x13) { 5686 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 5687 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 5688#ifdef CONFIG_FB_SIS_300 5689 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 5690#endif 5691 } else if(SiS_Pr->UseCustomMode) { 5692 modeflag = SiS_Pr->CModeFlag; 5693 } else { 5694 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5695 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 5696#ifdef CONFIG_FB_SIS_300 5697 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 5698#endif 5699 } 5700 5701 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */ 5702 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 5703 islvds = true; 5704 } 5705 5706 /* is really sis if sis bridge, but not 301B-DH */ 5707 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 5708 issis = true; 5709 } 5710 5711 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) { 5712 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { 5713 chkdclkfirst = true; 5714 } 5715 } 5716 5717#ifdef CONFIG_FB_SIS_315 5718 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 5719 if(IS_SIS330) { 5720 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); 5721 } else if(IS_SIS740) { 5722 if(islvds) { 5723 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); 5724 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03); 5725 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); 5727 } 5728 } else { 5729 if(islvds) { 5730 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); 5731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00); 5732 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5733 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f); 5734 if(SiS_Pr->SiS_VBType & VB_SIS30xC) { 5735 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) || 5736 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5737 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20); 5738 } 5739 } 5740 } 5741 } 5742 } 5743#endif 5744 5745 /* Horizontal */ 5746 5747 tempax = SiS_Pr->SiS_LCDHDES; 5748 if(islvds) { 5749 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5750 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) { 5751 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) && 5752 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 5753 tempax -= 8; 5754 } 5755 } 5756 } 5757 } 5758 5759 temp = (tempax & 0x0007); 5760 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */ 5761 temp = (tempax >> 3) & 0x00FF; 5762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */ 5763 5764 tempbx = SiS_Pr->SiS_HDE; 5765 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5766 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5767 tempbx = SiS_Pr->PanelXRes; 5768 } 5769 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) || 5770 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) || 5771 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) { 5772 tempbx >>= 1; 5773 } 5774 } 5775 5776 tempax += tempbx; 5777 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT; 5778 5779 temp = tempax; 5780 if(temp & 0x07) temp += 8; 5781 temp >>= 3; 5782 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */ 5783 5784 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2; 5785 5786 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5787 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5788 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS; 5789 } 5790 } 5791 5792 tempcx += tempax; 5793 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT; 5794 5795 temp = (tempcx >> 3) & 0x00FF; 5796 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5797 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5798 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5799 switch(ModeNo) { 5800 case 0x04: 5801 case 0x05: 5802 case 0x0d: temp = 0x56; break; 5803 case 0x10: temp = 0x60; break; 5804 case 0x13: temp = 0x5f; break; 5805 case 0x40: 5806 case 0x41: 5807 case 0x4f: 5808 case 0x43: 5809 case 0x44: 5810 case 0x62: 5811 case 0x56: 5812 case 0x53: 5813 case 0x5d: 5814 case 0x5e: temp = 0x54; break; 5815 } 5816 } 5817 } 5818 } 5819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */ 5820 5821 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5822 temp += 2; 5823 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5824 temp += 8; 5825 if(SiS_Pr->PanelHRE != 999) { 5826 temp = tempcx + SiS_Pr->PanelHRE; 5827 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT; 5828 temp >>= 3; 5829 } 5830 } 5831 } else { 5832 temp += 10; 5833 } 5834 5835 temp &= 0x1F; 5836 temp |= ((tempcx & 0x07) << 5); 5837 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */ 5838 5839 /* Vertical */ 5840 5841 tempax = SiS_Pr->SiS_VGAVDE; 5842 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5843 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5844 tempax = SiS_Pr->PanelYRes; 5845 } 5846 } 5847 5848 tempbx = SiS_Pr->SiS_LCDVDES + tempax; 5849 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; 5850 5851 push2 = tempbx; 5852 5853 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; 5854 if(SiS_Pr->ChipType < SIS_315H) { 5855 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5856 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5857 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes; 5858 } 5859 } 5860 } 5861 if(islvds) tempcx >>= 1; 5862 else tempcx >>= 2; 5863 5864 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && 5865 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) && 5866 (SiS_Pr->PanelVRS != 999) ) { 5867 tempcx = SiS_Pr->PanelVRS; 5868 tempbx += tempcx; 5869 if(issis) tempbx++; 5870 } else { 5871 tempbx += tempcx; 5872 if(SiS_Pr->ChipType < SIS_315H) tempbx++; 5873 else if(issis) tempbx++; 5874 } 5875 5876 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; 5877 5878 temp = tempbx & 0x00FF; 5879 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5880 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5881 if(ModeNo == 0x10) temp = 0xa9; 5882 } 5883 } 5884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */ 5885 5886 tempcx >>= 3; 5887 tempcx++; 5888 5889 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5890 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5891 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE; 5892 } 5893 } 5894 5895 tempcx += tempbx; 5896 temp = tempcx & 0x000F; 5897 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */ 5898 5899 temp = ((tempbx >> 8) & 0x07) << 3; 5900 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { 5901 if(SiS_Pr->SiS_HDE != 640) { 5902 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; 5903 } 5904 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; 5905 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40; 5906 tempbx = 0x87; 5907 if((SiS_Pr->ChipType >= SIS_315H) || 5908 (SiS_Pr->ChipRevision >= 0x30)) { 5909 tempbx = 0x07; 5910 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 5911 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80; 5912 } 5913 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */ 5914 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5915 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 5916 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80; 5917 } else { 5918 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80; 5919 } 5920 } 5921 } 5922 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp); 5923 5924 tempbx = push2; /* BPLVDEE */ 5925 5926 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */ 5927 5928 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5929 switch(SiS_Pr->SiS_LCDResInfo) { 5930 case Panel_640x480: 5931 tempbx = SiS_Pr->SiS_VGAVDE - 1; 5932 tempcx = SiS_Pr->SiS_VGAVDE; 5933 break; 5934 case Panel_800x600: 5935 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5936 if(resinfo == SIS_RI_800x600) tempcx++; 5937 } 5938 break; 5939 case Panel_1024x600: 5940 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5941 if(resinfo == SIS_RI_1024x600) tempcx++; 5942 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 5943 if(resinfo == SIS_RI_800x600) tempcx++; 5944 } 5945 } 5946 break; 5947 case Panel_1024x768: 5948 if(SiS_Pr->ChipType < SIS_315H) { 5949 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5950 if(resinfo == SIS_RI_1024x768) tempcx++; 5951 } 5952 } 5953 break; 5954 } 5955 } 5956 5957 temp = ((tempbx >> 8) & 0x07) << 3; 5958 temp |= ((tempcx >> 8) & 0x07); 5959 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp); 5960 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx); 5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx); 5962 5963 /* Vertical scaling */ 5964 5965 if(SiS_Pr->ChipType < SIS_315H) { 5966 5967#ifdef CONFIG_FB_SIS_300 /* 300 series */ 5968 tempeax = SiS_Pr->SiS_VGAVDE << 6; 5969 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE); 5970 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE; 5971 if(temp) tempeax++; 5972 5973 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F; 5974 5975 temp = (unsigned short)(tempeax & 0x00FF); 5976 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */ 5977 tempvcfact = temp; 5978#endif /* CONFIG_FB_SIS_300 */ 5979 5980 } else { 5981 5982#ifdef CONFIG_FB_SIS_315 /* 315 series */ 5983 tempeax = SiS_Pr->SiS_VGAVDE << 18; 5984 tempebx = SiS_Pr->SiS_VDE; 5985 temp = (tempeax % tempebx); 5986 tempeax = tempeax / tempebx; 5987 if(temp) tempeax++; 5988 tempvcfact = tempeax; 5989 5990 temp = (unsigned short)(tempeax & 0x00FF); 5991 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp); 5992 temp = (unsigned short)((tempeax & 0x00FF00) >> 8); 5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp); 5994 temp = (unsigned short)((tempeax & 0x00030000) >> 16); 5995 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04; 5996 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp); 5997 5998 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) { 5999 temp = (unsigned short)(tempeax & 0x00FF); 6000 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp); 6001 temp = (unsigned short)((tempeax & 0x00FF00) >> 8); 6002 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp); 6003 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6); 6004 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp); 6005 temp = 0; 6006 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08; 6007 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp); 6008 } 6009#endif 6010 6011 } 6012 6013 /* Horizontal scaling */ 6014 6015 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/ 6016 if(chkdclkfirst) { 6017 if(modeflag & HalfDCLK) tempeax >>= 1; 6018 } 6019 tempebx = tempeax << 16; 6020 if(SiS_Pr->SiS_HDE == tempeax) { 6021 tempecx = 0xFFFF; 6022 } else { 6023 tempecx = tempebx / SiS_Pr->SiS_HDE; 6024 if(SiS_Pr->ChipType >= SIS_315H) { 6025 if(tempebx % SiS_Pr->SiS_HDE) tempecx++; 6026 } 6027 } 6028 6029 if(SiS_Pr->ChipType >= SIS_315H) { 6030 tempeax = (tempebx / tempecx) - 1; 6031 } else { 6032 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1; 6033 } 6034 tempecx = (tempecx << 16) | (tempeax & 0xFFFF); 6035 temp = (unsigned short)(tempecx & 0x00FF); 6036 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp); 6037 6038 if(SiS_Pr->ChipType >= SIS_315H) { 6039 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact; 6040 tempbx = (unsigned short)(tempeax & 0xFFFF); 6041 } else { 6042 tempeax = SiS_Pr->SiS_VGAVDE << 6; 6043 tempbx = tempvcfact & 0x3f; 6044 if(tempbx == 0) tempbx = 64; 6045 tempeax /= tempbx; 6046 tempbx = (unsigned short)(tempeax & 0xFFFF); 6047 } 6048 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--; 6049 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) { 6050 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1; 6051 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1; 6052 } 6053 6054 temp = ((tempbx >> 8) & 0x07) << 3; 6055 temp = temp | ((tempecx >> 8) & 0x07); 6056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp); 6057 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx); 6058 6059 tempecx >>= 16; /* BPLHCFACT */ 6060 if(!chkdclkfirst) { 6061 if(modeflag & HalfDCLK) tempecx >>= 1; 6062 } 6063 temp = (unsigned short)((tempecx & 0xFF00) >> 8); 6064 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp); 6065 temp = (unsigned short)(tempecx & 0x00FF); 6066 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp); 6067 6068#ifdef CONFIG_FB_SIS_315 6069 if(SiS_Pr->ChipType >= SIS_315H) { 6070 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 6071 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) { 6072 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20); 6073 } 6074 } else { 6075 if(islvds) { 6076 if(SiS_Pr->ChipType == SIS_740) { 6077 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); 6078 } else { 6079 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23); 6080 } 6081 } 6082 } 6083 } 6084#endif 6085 6086#ifdef CONFIG_FB_SIS_300 6087 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 6088 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 6089 unsigned char *trumpdata; 6090 int i, j = crt2crtc; 6091 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 }; 6092 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 }; 6093 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 }; 6094 6095 if(SiS_Pr->SiS_UseROM) { 6096 trumpdata = &ROMAddr[0x8001 + (j * 80)]; 6097 } else { 6098 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7; 6099 trumpdata = &SiS300_TrumpionData[j][0]; 6100 } 6101 6102 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf); 6103 for(i=0; i<5; i++) { 6104 SiS_SetTrumpionBlock(SiS_Pr, trumpdata); 6105 } 6106 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6107 if(ModeNo == 0x13) { 6108 for(i=0; i<4; i++) { 6109 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]); 6110 } 6111 } else if(ModeNo == 0x10) { 6112 for(i=0; i<4; i++) { 6113 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]); 6114 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]); 6115 } 6116 } 6117 } 6118 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 6119 } 6120#endif 6121 6122#ifdef CONFIG_FB_SIS_315 6123 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { 6124 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00); 6125 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00); 6126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00); 6127 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87); 6128 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A); 6129 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B); 6130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03); 6131 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */ 6132 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6133 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6134 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6135 tempax += 64; 6136 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff); 6137 temp = (tempax >> 8) << 3; 6138 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp); 6139 tempax += 32; /* Blpe = lBlps+32 */ 6140 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff); 6141 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */ 6142 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007); 6143 6144 tempax = SiS_Pr->SiS_VDE; 6145 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6146 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6147 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6148 tempax >>= 1; 6149 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff); 6150 temp = (tempax >> 8) << 3; 6151 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp); 6152 6153 tempeax = SiS_Pr->SiS_HDE; 6154 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6155 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6156 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1; 6157 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */ 6158 temp = tempeax & 0x7f; 6159 tempeax >>= 7; 6160 if(temp) tempeax++; 6161 temp = tempeax & 0x3f; 6162 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp); 6163 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */ 6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00); 6165 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10); 6166 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040); 6167 6168 tempax = SiS_Pr->SiS_HDE; 6169 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6170 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6171 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6172 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */ 6173 pushcx = tempax; 6174 temp = tempax & 0x00FF; 6175 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp); 6176 temp = ((tempax & 0xFF00) >> 8) << 3; 6177 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp); 6178 6179 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */ 6180 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6181 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6182 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6183 tempeax = tempax * pushcx; 6184 temp = tempeax & 0xFF; 6185 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp); 6186 temp = (tempeax & 0xFF00) >> 8; 6187 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp); 6188 temp = ((tempeax & 0xFF0000) >> 16) | 0x10; 6189 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp); 6190 temp = ((tempeax & 0x01000000) >> 24) << 7; 6191 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp); 6192 6193 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03); 6194 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50); 6195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00); 6196 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01); 6197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38); 6198 6199 if(SiS_Pr->SiS_IF_DEF_FSTN) { 6200 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02); 6201 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00); 6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00); 6203 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c); 6204 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00); 6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00); 6206 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80); 6207 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0); 6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00); 6209 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0); 6210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00); 6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10); 6212 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00); 6213 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00); 6214 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10); 6215 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25); 6216 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80); 6217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14); 6218 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03); 6219 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a); 6220 } 6221 } 6222#endif /* CONFIG_FB_SIS_315 */ 6223} 6224 6225/* Set Part 1 */ 6226static void 6227SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6228 unsigned short RefreshRateTableIndex) 6229{ 6230#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 6231 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 6232#endif 6233 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0; 6234 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0; 6235#ifdef CONFIG_FB_SIS_315 6236 unsigned short tempbl=0; 6237#endif 6238 6239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 6240 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6241 return; 6242 } 6243 6244 if(ModeNo <= 0x13) { 6245 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 6246 } else if(SiS_Pr->UseCustomMode) { 6247 modeflag = SiS_Pr->CModeFlag; 6248 } else { 6249 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2); 6250 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 6251 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 6252 } 6253 6254 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6255 6256 if( ! ((SiS_Pr->ChipType >= SIS_315H) && 6257 (SiS_Pr->SiS_IF_DEF_LVDS == 1) && 6258 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) { 6259 6260 if(SiS_Pr->ChipType < SIS_315H ) { 6261#ifdef CONFIG_FB_SIS_300 6262 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo); 6263#endif 6264 } else { 6265#ifdef CONFIG_FB_SIS_315 6266 SiS_SetCRT2FIFO_310(SiS_Pr); 6267#endif 6268 } 6269 6270 /* 1. Horizontal setup */ 6271 6272 if(SiS_Pr->ChipType < SIS_315H ) { 6273 6274#ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/ 6275 6276 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ 6277 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ 6278 6279 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4; 6280 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */ 6281 6282 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ 6283 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */ 6284 6285 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */ 6286 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2; 6287 tempbx = pushbx + tempcx; 6288 tempcx <<= 1; 6289 tempcx += tempbx; 6290 6291 bridgeadd = 12; 6292 6293#endif /* CONFIG_FB_SIS_300 */ 6294 6295 } else { 6296 6297#ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */ 6298 6299 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */ 6300 if(modeflag & HalfDCLK) { 6301 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6302 tempcx >>= 1; 6303 } else { 6304 tempax = SiS_Pr->SiS_VGAHDE >> 1; 6305 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax; 6306 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 6307 tempcx = SiS_Pr->SiS_HT - tempax; 6308 } 6309 } 6310 } 6311 tempcx--; 6312 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */ 6313 temp = (tempcx >> 4) & 0xF0; 6314 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */ 6315 6316 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */ 6317 tempbx = SiS_Pr->SiS_VGAHDE; 6318 tempcx -= tempbx; 6319 tempcx >>= 2; 6320 if(modeflag & HalfDCLK) { 6321 tempbx >>= 1; 6322 tempcx >>= 1; 6323 } 6324 tempbx += 16; 6325 6326 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */ 6327 6328 pushbx = tempbx; 6329 tempcx >>= 1; 6330 tempbx += tempcx; 6331 tempcx += tempbx; 6332 6333 bridgeadd = 16; 6334 6335 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6336 if(SiS_Pr->ChipType >= SIS_661) { 6337 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 6338 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 6339 if(resinfo == SIS_RI_1280x1024) { 6340 tempcx = (tempcx & 0xff00) | 0x30; 6341 } else if(resinfo == SIS_RI_1600x1200) { 6342 tempcx = (tempcx & 0xff00) | 0xff; 6343 } 6344 } 6345 } 6346 } 6347 6348#endif /* CONFIG_FB_SIS_315 */ 6349 6350 } /* 315/330 series */ 6351 6352 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6353 6354 if(SiS_Pr->UseCustomMode) { 6355 tempbx = SiS_Pr->CHSyncStart + bridgeadd; 6356 tempcx = SiS_Pr->CHSyncEnd + bridgeadd; 6357 tempax = SiS_Pr->SiS_VGAHT; 6358 if(modeflag & HalfDCLK) tempax >>= 1; 6359 tempax--; 6360 if(tempcx > tempax) tempcx = tempax; 6361 } 6362 6363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 6364 unsigned char cr4, cr14, cr5, cr15; 6365 if(SiS_Pr->UseCustomMode) { 6366 cr4 = SiS_Pr->CCRT1CRTC[4]; 6367 cr14 = SiS_Pr->CCRT1CRTC[14]; 6368 cr5 = SiS_Pr->CCRT1CRTC[5]; 6369 cr15 = SiS_Pr->CCRT1CRTC[15]; 6370 } else { 6371 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4]; 6372 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14]; 6373 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5]; 6374 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15]; 6375 } 6376 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */ 6377 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */ 6378 tempcx &= 0x00FF; 6379 tempcx |= (tempbx & 0xFF00); 6380 tempbx += bridgeadd; 6381 tempcx += bridgeadd; 6382 tempax = SiS_Pr->SiS_VGAHT; 6383 if(modeflag & HalfDCLK) tempax >>= 1; 6384 tempax--; 6385 if(tempcx > tempax) tempcx = tempax; 6386 } 6387 6388 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) { 6389 tempbx = 1040; 6390 tempcx = 1044; /* HWCursor bug! */ 6391 } 6392 6393 } 6394 6395 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */ 6396 6397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */ 6398 6399 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0); 6400 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */ 6401 6402 /* 2. Vertical setup */ 6403 6404 tempcx = SiS_Pr->SiS_VGAVT - 1; 6405 temp = tempcx & 0x00FF; 6406 6407 if(SiS_Pr->ChipType < SIS_661) { 6408 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6409 if(SiS_Pr->ChipType < SIS_315H) { 6410 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6411 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { 6412 temp--; 6413 } 6414 } 6415 } else { 6416 temp--; 6417 } 6418 } else if(SiS_Pr->ChipType >= SIS_315H) { 6419 temp--; 6420 } 6421 } 6422 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */ 6423 6424 tempbx = SiS_Pr->SiS_VGAVDE - 1; 6425 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */ 6426 6427 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07); 6428 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */ 6429 6430 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) { 6431 tempbx++; 6432 tempax = tempbx; 6433 tempcx++; 6434 tempcx -= tempax; 6435 tempcx >>= 2; 6436 tempbx += tempcx; 6437 if(tempcx < 4) tempcx = 4; 6438 tempcx >>= 2; 6439 tempcx += tempbx; 6440 tempcx++; 6441 } else { 6442 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */ 6443 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */ 6444 } 6445 6446 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6447 if(SiS_Pr->UseCustomMode) { 6448 tempbx = SiS_Pr->CVSyncStart; 6449 tempcx = SiS_Pr->CVSyncEnd; 6450 } 6451 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 6452 unsigned char cr8, cr7, cr13; 6453 if(SiS_Pr->UseCustomMode) { 6454 cr8 = SiS_Pr->CCRT1CRTC[8]; 6455 cr7 = SiS_Pr->CCRT1CRTC[7]; 6456 cr13 = SiS_Pr->CCRT1CRTC[13]; 6457 tempcx = SiS_Pr->CCRT1CRTC[9]; 6458 } else { 6459 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8]; 6460 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7]; 6461 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13]; 6462 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9]; 6463 } 6464 tempbx = cr8; 6465 if(cr7 & 0x04) tempbx |= 0x0100; 6466 if(cr7 & 0x80) tempbx |= 0x0200; 6467 if(cr13 & 0x08) tempbx |= 0x0400; 6468 } 6469 } 6470 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */ 6471 6472 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F); 6473 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */ 6474 6475 /* 3. Panel delay compensation */ 6476 6477 if(SiS_Pr->ChipType < SIS_315H) { 6478 6479#ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */ 6480 6481 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6482 temp = 0x20; 6483 if(SiS_Pr->ChipType == SIS_300) { 6484 temp = 0x10; 6485 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c; 6486 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20; 6487 } 6488 if(SiS_Pr->SiS_VBType & VB_SIS301) { 6489 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20; 6490 } 6491 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24; 6492 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c; 6493 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08; 6494 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6495 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c; 6496 else temp = 0x20; 6497 } 6498 if(SiS_Pr->SiS_UseROM) { 6499 if(ROMAddr[0x220] & 0x80) { 6500 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) 6501 temp = ROMAddr[0x221]; 6502 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) 6503 temp = ROMAddr[0x222]; 6504 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) 6505 temp = ROMAddr[0x223]; 6506 else 6507 temp = ROMAddr[0x224]; 6508 } 6509 } 6510 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6511 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC; 6512 } 6513 6514 } else { 6515 temp = 0x20; 6516 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 6517 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04; 6518 } 6519 if(SiS_Pr->SiS_UseROM) { 6520 if(ROMAddr[0x220] & 0x80) { 6521 temp = ROMAddr[0x220]; 6522 } 6523 } 6524 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6525 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC; 6526 } 6527 } 6528 6529 temp &= 0x3c; 6530 6531 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */ 6532 6533#endif /* CONFIG_FB_SIS_300 */ 6534 6535 } else { 6536 6537#ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/ 6538 6539 if(SiS_Pr->ChipType < SIS_661) { 6540 6541 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6542 6543 if(SiS_Pr->ChipType == SIS_740) temp = 0x03; 6544 else temp = 0x00; 6545 6546 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a; 6547 tempbl = 0xF0; 6548 if(SiS_Pr->ChipType == SIS_650) { 6549 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6550 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F; 6551 } 6552 } 6553 6554 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) { 6555 temp = 0x08; 6556 tempbl = 0; 6557 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 6558 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0; 6559 } 6560 } 6561 6562 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */ 6563 } 6564 6565 } /* < 661 */ 6566 6567 tempax = 0; 6568 if(modeflag & DoubleScanMode) tempax |= 0x80; 6569 if(modeflag & HalfDCLK) tempax |= 0x40; 6570 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax); 6571 6572#endif /* CONFIG_FB_SIS_315 */ 6573 6574 } 6575 6576 } /* Slavemode */ 6577 6578 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6579 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 6580 /* For 301BDH with LCD, we set up the Panel Link */ 6581 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6582 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6583 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6584 } 6585 } else { 6586 if(SiS_Pr->ChipType < SIS_315H) { 6587 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6588 } else { 6589 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6590 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 6591 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex); 6592 } 6593 } else { 6594 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex); 6595 } 6596 } 6597 } 6598} 6599 6600/*********************************************/ 6601/* SET PART 2 REGISTER GROUP */ 6602/*********************************************/ 6603 6604#ifdef CONFIG_FB_SIS_315 6605static unsigned char * 6606SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype) 6607{ 6608 const unsigned char *tableptr = NULL; 6609 unsigned short a, b, p = 0; 6610 6611 a = SiS_Pr->SiS_VGAHDE; 6612 b = SiS_Pr->SiS_HDE; 6613 if(tabletype) { 6614 a = SiS_Pr->SiS_VGAVDE; 6615 b = SiS_Pr->SiS_VDE; 6616 } 6617 6618 if(a < b) { 6619 tableptr = SiS_Part2CLVX_1; 6620 } else if(a == b) { 6621 tableptr = SiS_Part2CLVX_2; 6622 } else { 6623 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6624 tableptr = SiS_Part2CLVX_4; 6625 } else { 6626 tableptr = SiS_Part2CLVX_3; 6627 } 6628 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 6629 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3; 6630 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3; 6631 else tableptr = SiS_Part2CLVX_5; 6632 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6633 tableptr = SiS_Part2CLVX_6; 6634 } 6635 do { 6636 if((tableptr[p] | tableptr[p+1] << 8) == a) break; 6637 p += 0x42; 6638 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff); 6639 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42; 6640 } 6641 p += 2; 6642 return ((unsigned char *)&tableptr[p]); 6643} 6644 6645static void 6646SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6647 unsigned short RefreshRateTableIndex) 6648{ 6649 unsigned char *tableptr; 6650 unsigned char temp; 6651 int i, j; 6652 6653 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return; 6654 6655 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0); 6656 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) { 6657 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]); 6658 } 6659 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 6660 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1); 6661 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) { 6662 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]); 6663 } 6664 } 6665 temp = 0x10; 6666 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04; 6667 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp); 6668} 6669 6670static bool 6671SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex, 6672 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index, 6673 unsigned short *ResIndex) 6674{ 6675 6676 if(SiS_Pr->ChipType < SIS_315H) return false; 6677 6678 if(ModeNo <= 0x13) 6679 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6680 else 6681 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6682 6683 (*ResIndex) &= 0x3f; 6684 (*CRT2Index) = 0; 6685 6686 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6687 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 6688 (*CRT2Index) = 200; 6689 } 6690 } 6691 6692 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 6693 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6694 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206; 6695 } 6696 } 6697 return (((*CRT2Index) != 0)); 6698} 6699#endif 6700 6701#ifdef CONFIG_FB_SIS_300 6702static void 6703SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc) 6704{ 6705 unsigned short tempcx; 6706 static const unsigned char atable[] = { 6707 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02, 6708 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02 6709 }; 6710 6711 if(!SiS_Pr->UseCustomMode) { 6712 if( ( ( (SiS_Pr->ChipType == SIS_630) || 6713 (SiS_Pr->ChipType == SIS_730) ) && 6714 (SiS_Pr->ChipRevision > 2) ) && 6715 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) && 6716 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) && 6717 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) { 6718 if(ModeNo == 0x13) { 6719 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9); 6720 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC); 6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6); 6722 } else if((crt2crtc & 0x3F) == 4) { 6723 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B); 6724 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13); 6725 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5); 6726 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08); 6727 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2); 6728 } 6729 } 6730 6731 if(SiS_Pr->ChipType < SIS_315H) { 6732 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) { 6733 crt2crtc &= 0x1f; 6734 tempcx = 0; 6735 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6736 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6737 tempcx += 7; 6738 } 6739 } 6740 tempcx += crt2crtc; 6741 if(crt2crtc >= 4) { 6742 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff); 6743 } 6744 6745 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6746 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6747 if(crt2crtc == 4) { 6748 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28); 6749 } 6750 } 6751 } 6752 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18); 6753 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]); 6754 } 6755 } 6756 } 6757} 6758 6759/* For ECS A907. Highly preliminary. */ 6760static void 6761SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, 6762 unsigned short ModeNo) 6763{ 6764 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; 6765 unsigned short crt2crtc, resindex; 6766 int i, j; 6767 6768 if(SiS_Pr->ChipType != SIS_300) return; 6769 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return; 6770 if(SiS_Pr->UseCustomMode) return; 6771 6772 if(ModeNo <= 0x13) { 6773 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6774 } else { 6775 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6776 } 6777 6778 resindex = crt2crtc & 0x3F; 6779 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; 6780 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2; 6781 6782 /* The BIOS code (1.16.51,56) is obviously a fragment! */ 6783 if(ModeNo > 0x13) { 6784 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; 6785 resindex = 4; 6786 } 6787 6788 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 6789 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); 6790 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { 6791 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6792 } 6793 for(j = 0x1c; j <= 0x1d; i++, j++ ) { 6794 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6795 } 6796 for(j = 0x1f; j <= 0x21; i++, j++ ) { 6797 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6798 } 6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); 6800 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); 6801} 6802#endif 6803 6804static void 6805SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 6806{ 6807 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return; 6808 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return; 6809 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return; 6810 6811 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 6812 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6813 static const unsigned char specialtv[] = { 6814 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53, 6815 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a, 6816 0x58,0xe4,0x73,0xda,0x13 6817 }; 6818 int i, j; 6819 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) { 6820 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]); 6821 } 6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72); 6823 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) { 6824 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 6825 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); 6826 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b); 6827 } else { 6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */ 6829 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */ 6830 } 6831 } 6832 } 6833 } else { 6834 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) || 6835 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) { 6836 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */ 6837 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */ 6838 } else { 6839 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */ 6840 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */ 6841 } 6842 } 6843} 6844 6845static void 6846SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 6847{ 6848 unsigned short temp; 6849 6850 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 6851 if(SiS_Pr->SiS_VGAVDE == 525) { 6852 temp = 0xc3; 6853 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6854 temp++; 6855 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2; 6856 } 6857 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6858 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3); 6859 } else if(SiS_Pr->SiS_VGAVDE == 420) { 6860 temp = 0x4d; 6861 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6862 temp++; 6863 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++; 6864 } 6865 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6866 } 6867 } 6868 6869 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6870 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) { 6871 if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 6872 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03); 6873 /* Not always for LV, see SetGrp2 */ 6874 } 6875 temp = 1; 6876 if(ModeNo <= 0x13) temp = 3; 6877 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp); 6878 } 6879#if 0 6880 /* 651+301C, for 1280x768 - do I really need that? */ 6881 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) { 6882 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { 6883 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) || 6884 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) { 6885 SiS_SetReg(SiS_Part2Port,0x01,0x2b); 6886 SiS_SetReg(SiS_Part2Port,0x02,0x13); 6887 SiS_SetReg(SiS_Part2Port,0x04,0xe5); 6888 SiS_SetReg(SiS_Part2Port,0x05,0x08); 6889 SiS_SetReg(SiS_Part2Port,0x06,0xe2); 6890 SiS_SetReg(SiS_Part2Port,0x1c,0x21); 6891 SiS_SetReg(SiS_Part2Port,0x1d,0x45); 6892 SiS_SetReg(SiS_Part2Port,0x1f,0x0b); 6893 SiS_SetReg(SiS_Part2Port,0x20,0x00); 6894 SiS_SetReg(SiS_Part2Port,0x21,0xa9); 6895 SiS_SetReg(SiS_Part2Port,0x23,0x0b); 6896 SiS_SetReg(SiS_Part2Port,0x25,0x04); 6897 } 6898 } 6899 } 6900#endif 6901 } 6902} 6903 6904static void 6905SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6906 unsigned short RefreshRateTableIndex) 6907{ 6908 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp; 6909 unsigned short push2, modeflag, crt2crtc, bridgeoffset; 6910 unsigned int longtemp, PhaseIndex; 6911 bool newtvphase; 6912 const unsigned char *TimingPoint; 6913#ifdef CONFIG_FB_SIS_315 6914 unsigned short resindex, CRT2Index; 6915 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; 6916 6917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 6918#endif 6919 6920 if(ModeNo <= 0x13) { 6921 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 6922 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6923 } else if(SiS_Pr->UseCustomMode) { 6924 modeflag = SiS_Pr->CModeFlag; 6925 crt2crtc = 0; 6926 } else { 6927 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 6928 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6929 } 6930 6931 temp = 0; 6932 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08; 6933 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04; 6934 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02; 6935 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01; 6936 6937 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10; 6938 6939 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp); 6940 6941 PhaseIndex = 0x01; /* SiS_PALPhase */ 6942 TimingPoint = SiS_Pr->SiS_PALTiming; 6943 6944 newtvphase = false; 6945 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) && 6946 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || 6947 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) { 6948 newtvphase = true; 6949 } 6950 6951 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6952 6953 TimingPoint = SiS_Pr->SiS_HiTVExtTiming; 6954 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6955 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing; 6956 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 6957 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing; 6958 } 6959 } 6960 6961 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 6962 6963 i = 0; 6964 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2; 6965 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1; 6966 6967 TimingPoint = &SiS_YPbPrTable[i][0]; 6968 6969 PhaseIndex = 0x00; /* SiS_NTSCPhase */ 6970 6971 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6972 6973 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */ 6974 6975 } else { 6976 6977 TimingPoint = SiS_Pr->SiS_NTSCTiming; 6978 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */ 6979 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */ 6980 6981 } 6982 6983 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) { 6984 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */ 6985 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */ 6986 } 6987 6988 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6989 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 6990 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */ 6991 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) { 6992 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */ 6993 } else { 6994 PhaseIndex = 0x10; /* SiS_SpecialPhase */ 6995 } 6996 } 6997 6998 for(i = 0x31, j = 0; i <= 0x34; i++, j++) { 6999 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]); 7000 } 7001 7002 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) { 7003 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 7004 } 7005 for(i = 0x39; i <= 0x45; i++, j++) { 7006 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 7007 } 7008 7009 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7010 if(SiS_Pr->SiS_ModeType != ModeText) { 7011 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F); 7012 } 7013 } 7014 7015 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode); 7016 7017 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE); 7018 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE); 7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE); 7020 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE); 7021 7022 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950; 7023 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680; 7024 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520; 7025 else tempax = 440; /* NTSC, YPbPr 525 */ 7026 7027 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) || 7028 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) && 7029 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) { 7030 7031 tempax -= SiS_Pr->SiS_VDE; 7032 tempax >>= 1; 7033 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) { 7034 tempax >>= 1; 7035 } 7036 tempax &= 0x00ff; 7037 7038 temp = tempax + (unsigned short)TimingPoint[0]; 7039 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 7040 7041 temp = tempax + (unsigned short)TimingPoint[1]; 7042 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp); 7043 7044 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) { 7045 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 7046 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); 7047 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); 7048 } else { 7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17); 7050 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d); 7051 } 7052 } 7053 7054 } 7055 7056 tempcx = SiS_Pr->SiS_HT; 7057 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 7058 tempcx--; 7059 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--; 7060 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx); 7061 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f)); 7062 7063 tempcx = SiS_Pr->SiS_HT >> 1; 7064 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 7065 tempcx += 7; 7066 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4; 7067 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0)); 7068 7069 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8); 7070 tempbx += tempcx; 7071 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx); 7072 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0)); 7073 7074 tempbx += 8; 7075 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7076 tempbx -= 4; 7077 tempcx = tempbx; 7078 } 7079 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0)); 7080 7081 j += 2; 7082 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8)); 7083 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx); 7084 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0)); 7085 7086 tempcx += 8; 7087 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4; 7088 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0)); 7089 7090 tempcx = SiS_Pr->SiS_HT >> 1; 7091 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 7092 j += 2; 7093 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8)); 7094 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0)); 7095 7096 tempcx -= 11; 7097 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 7098 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1; 7099 } 7100 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx); 7101 7102 tempbx = SiS_Pr->SiS_VDE; 7103 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7104 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746; 7105 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746; 7106 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853; 7107 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 7108 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) { 7109 tempbx >>= 1; 7110 if(SiS_Pr->ChipType >= SIS_315H) { 7111 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 7112 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++; 7113 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 7114 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 7115 if(crt2crtc == 4) tempbx++; 7116 } 7117 } 7118 } 7119 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 7120 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7121 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++; 7122 } 7123 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 7124 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */ 7125 } 7126 } 7127 } 7128 tempbx -= 2; 7129 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx); 7130 7131 temp = (tempcx >> 8) & 0x0F; 7132 temp |= ((tempbx >> 2) & 0xC0); 7133 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { 7134 temp |= 0x10; 7135 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20; 7136 } 7137 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp); 7138 7139 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) { 7140 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5)); 7141 } 7142 7143 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7144 tempbx = SiS_Pr->SiS_VDE; 7145 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 7146 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) { 7147 tempbx >>= 1; 7148 } 7149 tempbx -= 3; 7150 temp = ((tempbx >> 3) & 0x60) | 0x18; 7151 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp); 7152 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx); 7153 7154 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) { 7155 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4)); 7156 } 7157 } 7158 7159 tempbx = 0; 7160 if(!(modeflag & HalfDCLK)) { 7161 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) { 7162 tempax = 0; 7163 tempbx |= 0x20; 7164 } 7165 } 7166 7167 tempch = tempcl = 0x01; 7168 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7169 if(SiS_Pr->SiS_VGAHDE >= 960) { 7170 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) { 7171 tempcl = 0x20; 7172 if(SiS_Pr->SiS_VGAHDE >= 1280) { 7173 tempch = 20; 7174 tempbx &= ~0x20; 7175 } else { 7176 tempch = 25; /* OK */ 7177 } 7178 } 7179 } 7180 } 7181 7182 if(!(tempbx & 0x20)) { 7183 if(modeflag & HalfDCLK) tempcl <<= 1; 7184 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13; 7185 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3; 7186 tempax = longtemp / SiS_Pr->SiS_HDE; 7187 if(longtemp % SiS_Pr->SiS_HDE) tempax++; 7188 tempbx |= ((tempax >> 8) & 0x1F); 7189 tempcx = tempax >> 13; 7190 } 7191 7192 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax); 7193 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx); 7194 7195 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7196 7197 tempcx &= 0x07; 7198 if(tempbx & 0x20) tempcx = 0; 7199 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx); 7200 7201 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 7202 tempbx = 0x0382; 7203 tempcx = 0x007e; 7204 } else { 7205 tempbx = 0x0369; 7206 tempcx = 0x0061; 7207 } 7208 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx); 7209 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx); 7210 temp = (tempcx & 0x0300) >> 6; 7211 temp |= ((tempbx >> 8) & 0x03); 7212 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 7213 temp |= 0x10; 7214 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20; 7215 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40; 7216 } 7217 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp); 7218 7219 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43); 7220 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3)); 7221 7222 SiS_SetTVSpecial(SiS_Pr, ModeNo); 7223 7224 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 7225 temp = 0; 7226 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8; 7227 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp); 7228 } 7229 7230 } 7231 7232 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 7233 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) { 7234 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01); 7235 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1)); 7236 } 7237 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF); 7238 } 7239 7240 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7241 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 7242 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00); 7243 } 7244 } 7245 7246 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return; 7247 7248 /* From here: Part2 LCD setup */ 7249 7250 tempbx = SiS_Pr->SiS_HDE; 7251 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7252 tempbx--; /* RHACTE = HDE - 1 */ 7253 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx); 7254 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0)); 7255 7256 temp = 0x01; 7257 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 7258 if(SiS_Pr->SiS_ModeType == ModeEGA) { 7259 if(SiS_Pr->SiS_VGAHDE >= 1024) { 7260 temp = 0x02; 7261 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 7262 temp = 0x01; 7263 } 7264 } 7265 } 7266 } 7267 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp); 7268 7269 tempbx = SiS_Pr->SiS_VDE - 1; 7270 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx); 7271 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07)); 7272 7273 tempcx = SiS_Pr->SiS_VT - 1; 7274 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx); 7275 temp = (tempcx >> 3) & 0xE0; 7276 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 7277 /* Enable dithering; only do this for 32bpp mode */ 7278 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { 7279 temp |= 0x10; 7280 } 7281 } 7282 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp); 7283 7284 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0); 7285 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0); 7286 7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB); 7288 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF); 7289 7290#ifdef CONFIG_FB_SIS_315 7291 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 7292 &CRT2Index, &resindex)) { 7293 switch(CRT2Index) { 7294 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break; 7295 default: 7296 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; 7297 } 7298 7299 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 7300 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); 7301 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { 7302 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7303 } 7304 for(j = 0x1c; j <= 0x1d; i++, j++ ) { 7305 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7306 } 7307 for(j = 0x1f; j <= 0x21; i++, j++ ) { 7308 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7309 } 7310 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); 7311 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); 7312 7313 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7314 7315 } else { 7316#endif 7317 7318 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */ 7319 /* Clevo dual-link 1024x768 */ 7320 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */ 7321 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */ 7322 7323 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7324 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) { 7325 tempbx = SiS_Pr->SiS_VDE - 1; 7326 tempcx = SiS_Pr->SiS_VT - 1; 7327 } else { 7328 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2); 7329 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2); 7330 } 7331 } else { 7332 tempbx = SiS_Pr->PanelYRes; 7333 tempcx = SiS_Pr->SiS_VT; 7334 tempax = 1; 7335 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7336 tempax = SiS_Pr->PanelYRes; 7337 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */ 7338 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) { 7339 tempax = tempcx = 0; 7340 } else { 7341 tempax -= SiS_Pr->SiS_VDE; 7342 } 7343 tempax >>= 1; 7344 } 7345 tempcx -= tempax; /* lcdvdes */ 7346 tempbx -= tempax; /* lcdvdee */ 7347 } 7348 7349 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ 7350 7351 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */ 7352 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */ 7353 7354 temp = (tempbx >> 5) & 0x38; 7355 temp |= ((tempcx >> 8) & 0x07); 7356 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp); 7357 7358 tempax = SiS_Pr->SiS_VDE; 7359 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7360 tempax = SiS_Pr->PanelYRes; 7361 } 7362 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4; 7363 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7364 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7365 tempcx = (SiS_Pr->SiS_VT - tempax) / 10; 7366 } 7367 } 7368 7369 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1; 7370 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7371 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7372 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */ 7373 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes; 7374 if(tempax % 4) { tempax >>= 2; tempax++; } 7375 else { tempax >>= 2; } 7376 tempbx -= (tempax - 1); 7377 } else { 7378 tempbx -= 10; 7379 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1; 7380 } 7381 } 7382 } 7383 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 7384 tempbx++; 7385 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) { 7386 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 7387 tempbx = 770; 7388 tempcx = 3; 7389 } 7390 } 7391 } 7392 7393 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */ 7394 7395 if(SiS_Pr->UseCustomMode) { 7396 tempbx = SiS_Pr->CVSyncStart; 7397 } 7398 7399 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */ 7400 7401 temp = (tempbx >> 4) & 0xF0; 7402 tempbx += (tempcx + 1); 7403 temp |= (tempbx & 0x0F); 7404 7405 if(SiS_Pr->UseCustomMode) { 7406 temp &= 0xf0; 7407 temp |= (SiS_Pr->CVSyncEnd & 0x0f); 7408 } 7409 7410 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 7411 7412#ifdef CONFIG_FB_SIS_300 7413 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc); 7414#endif 7415 7416 bridgeoffset = 7; 7417 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2; 7418 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */ 7419 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++; 7420 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */ 7421 /* Higher bridgeoffset shifts to the LEFT */ 7422 7423 temp = 0; 7424 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7425 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) { 7426 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7427 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1; 7428 } 7429 } 7430 temp += bridgeoffset; 7431 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */ 7432 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0)); 7433 7434 tempcx = SiS_Pr->SiS_HT; 7435 tempax = tempbx = SiS_Pr->SiS_HDE; 7436 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7437 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) { 7438 tempax = SiS_Pr->PanelXRes; 7439 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7440 } 7441 } 7442 if(SiS_IsDualLink(SiS_Pr)) { 7443 tempcx >>= 1; 7444 tempbx >>= 1; 7445 tempax >>= 1; 7446 } 7447 7448 tempbx += bridgeoffset; 7449 7450 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */ 7451 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f)); 7452 7453 tempcx = (tempcx - tempax) >> 2; 7454 7455 tempbx += tempcx; 7456 push2 = tempbx; 7457 7458 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 7459 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7460 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 7461 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47; 7462 } 7463 } 7464 } 7465 7466 if(SiS_Pr->UseCustomMode) { 7467 tempbx = SiS_Pr->CHSyncStart; 7468 if(modeflag & HalfDCLK) tempbx <<= 1; 7469 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7470 tempbx += bridgeoffset; 7471 } 7472 7473 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */ 7474 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0)); 7475 7476 tempbx = push2; 7477 7478 tempcx <<= 1; 7479 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7480 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2; 7481 } 7482 tempbx += tempcx; 7483 7484 if(SiS_Pr->UseCustomMode) { 7485 tempbx = SiS_Pr->CHSyncEnd; 7486 if(modeflag & HalfDCLK) tempbx <<= 1; 7487 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7488 tempbx += bridgeoffset; 7489 } 7490 7491 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */ 7492 7493 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7494 7495#ifdef CONFIG_FB_SIS_300 7496 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo); 7497#endif 7498#ifdef CONFIG_FB_SIS_315 7499 } /* CRT2-LCD from table */ 7500#endif 7501} 7502 7503/*********************************************/ 7504/* SET PART 3 REGISTER GROUP */ 7505/*********************************************/ 7506 7507static void 7508SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7509{ 7510 unsigned short i; 7511 const unsigned char *tempdi; 7512 7513 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7514 7515#ifndef SIS_CP 7516 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00); 7517#else 7518 SIS_CP_INIT301_CP 7519#endif 7520 7521 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 7522 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA); 7523 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8); 7524 } else { 7525 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5); 7526 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7); 7527 } 7528 7529 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 7530 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA); 7531 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8); 7532 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8); 7533 } 7534 7535 tempdi = NULL; 7536 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7537 tempdi = SiS_Pr->SiS_HiTVGroup3Data; 7538 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 7539 tempdi = SiS_Pr->SiS_HiTVGroup3Simu; 7540 } 7541 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 7542 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) { 7543 tempdi = SiS_HiTVGroup3_1; 7544 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2; 7545 } 7546 } 7547 if(tempdi) { 7548 for(i=0; i<=0x3E; i++) { 7549 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]); 7550 } 7551 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 7552 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 7553 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f); 7554 } 7555 } 7556 } 7557 7558#ifdef SIS_CP 7559 SIS_CP_INIT301_CP2 7560#endif 7561} 7562 7563/*********************************************/ 7564/* SET PART 4 REGISTER GROUP */ 7565/*********************************************/ 7566 7567#ifdef CONFIG_FB_SIS_315 7568#if 0 7569static void 7570SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift) 7571{ 7572 unsigned short temp, temp1, temp2; 7573 7574 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f); 7575 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20); 7576 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7577 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp); 7578 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0)); 7579 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f; 7580 temp = (unsigned short)((int)(temp) + shift); 7581 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f)); 7582 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43); 7583 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42); 7584 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7585 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp); 7586 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0)); 7587} 7588#endif 7589 7590static void 7591SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7592{ 7593 unsigned short temp, temp1; 7594 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 7595 7596 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return; 7597 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return; 7598 7599 if(SiS_Pr->ChipType >= XGI_20) return; 7600 7601 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) { 7602 if(!(ROMAddr[0x61] & 0x04)) return; 7603 } 7604 7605 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08); 7606 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a); 7607 if(!(temp & 0x01)) { 7608 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf); 7609 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc); 7610 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) { 7611 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8); 7612 } 7613 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb); 7614 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000; 7615 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002; 7616 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400; 7617 else temp = 0x0402; 7618 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 7619 temp1 = 0; 7620 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4; 7621 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1); 7622 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01; 7623 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff)); 7624 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8)); 7625 if(ModeNo > 0x13) { 7626 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd); 7627 } 7628 } else { 7629 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03; 7630 if(temp1 == 0x01) temp |= 0x01; 7631 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */ 7632 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff)); 7633 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8)); 7634 if(ModeNo > 0x13) { 7635 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd); 7636 } 7637 } 7638 7639#if 0 7640 if(SiS_Pr->ChipType >= SIS_661) { /* ? */ 7641 if(SiS_Pr->SiS_TVMode & TVAspect43) { 7642 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 7643 if(resinfo == SIS_RI_1024x768) { 7644 SiS_ShiftXPos(SiS_Pr, 97); 7645 } else { 7646 SiS_ShiftXPos(SiS_Pr, 111); 7647 } 7648 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) { 7649 SiS_ShiftXPos(SiS_Pr, 136); 7650 } 7651 } 7652 } 7653#endif 7654 7655 } 7656 7657} 7658#endif 7659 7660static void 7661SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7662 unsigned short RefreshRateTableIndex) 7663{ 7664 unsigned short vclkindex, temp, reg1, reg2; 7665 7666 if(SiS_Pr->UseCustomMode) { 7667 reg1 = SiS_Pr->CSR2B; 7668 reg2 = SiS_Pr->CSR2C; 7669 } else { 7670 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 7671 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A; 7672 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B; 7673 } 7674 7675 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7676 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) { 7677 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57); 7678 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46); 7679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6); 7680 } else { 7681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1); 7682 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2); 7683 } 7684 } else { 7685 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01); 7686 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2); 7687 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1); 7688 } 7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00); 7690 temp = 0x08; 7691 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20; 7692 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp); 7693} 7694 7695static void 7696SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr) 7697{ 7698 if(SiS_Pr->ChipType >= SIS_315H) { 7699 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 7700 if((SiS_CRT2IsLCD(SiS_Pr)) || 7701 (SiS_IsVAMode(SiS_Pr))) { 7702 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) { 7703 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c); 7704 } else { 7705 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20); 7706 } 7707 } 7708 } 7709 } 7710 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 7711 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00); 7712#ifdef SET_EMI 7713 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 7714#endif 7715 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 7716 } 7717} 7718 7719static void 7720SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7721 unsigned short RefreshRateTableIndex) 7722{ 7723 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo; 7724 unsigned int tempebx, tempeax, templong; 7725 7726 if(ModeNo <= 0x13) { 7727 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7728 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 7729 } else if(SiS_Pr->UseCustomMode) { 7730 modeflag = SiS_Pr->CModeFlag; 7731 resinfo = 0; 7732 } else { 7733 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7734 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 7735 } 7736 7737 if(SiS_Pr->ChipType >= SIS_315H) { 7738 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 7739 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7740 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7741 } 7742 } 7743 } 7744 7745 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) { 7746 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7747 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f); 7748 } 7749 } 7750 7751 if(SiS_Pr->ChipType >= SIS_315H) { 7752 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7753 SiS_SetDualLinkEtc(SiS_Pr); 7754 return; 7755 } 7756 } 7757 7758 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT); 7759 7760 tempbx = SiS_Pr->SiS_RVBHCMAX; 7761 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx); 7762 7763 temp = (tempbx >> 1) & 0x80; 7764 7765 tempcx = SiS_Pr->SiS_VGAHT - 1; 7766 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx); 7767 7768 temp |= ((tempcx >> 5) & 0x78); 7769 7770 tempcx = SiS_Pr->SiS_VGAVT - 1; 7771 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5; 7772 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx); 7773 7774 temp |= ((tempcx >> 8) & 0x07); 7775 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp); 7776 7777 tempbx = SiS_Pr->SiS_VGAHDE; 7778 if(modeflag & HalfDCLK) tempbx >>= 1; 7779 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7780 7781 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7782 temp = 0; 7783 if(tempbx > 800) temp = 0x60; 7784 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7785 temp = 0; 7786 if(tempbx > 1024) temp = 0xC0; 7787 else if(tempbx >= 960) temp = 0xA0; 7788 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) { 7789 temp = 0; 7790 if(tempbx >= 1280) temp = 0x40; 7791 else if(tempbx >= 1024) temp = 0x20; 7792 } else { 7793 temp = 0x80; 7794 if(tempbx >= 1024) temp = 0xA0; 7795 } 7796 7797 temp |= SiS_Pr->Init_P4_0E; 7798 7799 if(SiS_Pr->SiS_VBType & VB_SIS301) { 7800 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) { 7801 temp &= 0xf0; 7802 temp |= 0x0A; 7803 } 7804 } 7805 7806 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp); 7807 7808 tempeax = SiS_Pr->SiS_VGAVDE; 7809 tempebx = SiS_Pr->SiS_VDE; 7810 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7811 if(!(temp & 0xE0)) tempebx >>=1; 7812 } 7813 7814 tempcx = SiS_Pr->SiS_RVBHRS; 7815 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx); 7816 tempcx >>= 8; 7817 tempcx |= 0x40; 7818 7819 if(tempeax <= tempebx) { 7820 tempcx ^= 0x40; 7821 } else { 7822 tempeax -= tempebx; 7823 } 7824 7825 tempeax *= (256 * 1024); 7826 templong = tempeax % tempebx; 7827 tempeax /= tempebx; 7828 if(templong) tempeax++; 7829 7830 temp = (unsigned short)(tempeax & 0x000000FF); 7831 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp); 7832 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8); 7833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp); 7834 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */ 7835 temp |= (tempcx & 0x4F); 7836 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp); 7837 7838 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7839 7840 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28); 7841 7842 /* Calc Linebuffer max address and set/clear decimode */ 7843 tempbx = 0; 7844 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08; 7845 tempax = SiS_Pr->SiS_VGAHDE; 7846 if(modeflag & HalfDCLK) tempax >>= 1; 7847 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1; 7848 if(tempax > 800) { 7849 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7850 tempax -= 800; 7851 } else { 7852 tempbx = 0x08; 7853 if(tempax == 960) tempax *= 25; /* Correct */ 7854 else if(tempax == 1024) tempax *= 25; 7855 else tempax *= 20; 7856 temp = tempax % 32; 7857 tempax /= 32; 7858 if(temp) tempax++; 7859 tempax++; 7860 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7861 if(resinfo == SIS_RI_1024x768 || 7862 resinfo == SIS_RI_1024x576 || 7863 resinfo == SIS_RI_1280x1024 || 7864 resinfo == SIS_RI_1280x720) { 7865 /* Otherwise white line or garbage at right edge */ 7866 tempax = (tempax & 0xff00) | 0x20; 7867 } 7868 } 7869 } 7870 } 7871 tempax--; 7872 temp = ((tempax >> 4) & 0x30) | tempbx; 7873 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax); 7874 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp); 7875 7876 temp = 0x0036; tempbx = 0xD0; 7877 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 7878 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */ 7879 } 7880 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7881 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) { 7882 temp |= 0x01; 7883 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 7884 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 7885 temp &= ~0x01; 7886 } 7887 } 7888 } 7889 } 7890 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp); 7891 7892 tempbx = SiS_Pr->SiS_HT >> 1; 7893 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7894 tempbx -= 2; 7895 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx); 7896 temp = (tempbx >> 5) & 0x38; 7897 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp); 7898 7899 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 7900 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7901 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7902 /* LCD-too-dark-error-source, see FinalizeLCD() */ 7903 } 7904 } 7905 7906 SiS_SetDualLinkEtc(SiS_Pr); 7907 7908 } /* 301B */ 7909 7910 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 7911} 7912 7913/*********************************************/ 7914/* SET PART 5 REGISTER GROUP */ 7915/*********************************************/ 7916 7917static void 7918SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7919{ 7920 7921 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7922 7923 if(SiS_Pr->SiS_ModeType == ModeVGA) { 7924 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) { 7925 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 7926 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); 7927 } 7928 } 7929} 7930 7931/*********************************************/ 7932/* MODIFY CRT1 GROUP FOR SLAVE MODE */ 7933/*********************************************/ 7934 7935static bool 7936SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7937 unsigned short RefreshRateTableIndex, unsigned short *ResIndex, 7938 unsigned short *DisplayType) 7939 { 7940 unsigned short modeflag = 0; 7941 bool checkhd = true; 7942 7943 /* Pass 1:1 not supported here */ 7944 7945 if(ModeNo <= 0x13) { 7946 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7947 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 7948 } else { 7949 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7950 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 7951 } 7952 7953 (*ResIndex) &= 0x3F; 7954 7955 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 7956 7957 (*DisplayType) = 80; 7958 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) { 7959 (*DisplayType) = 82; 7960 if(SiS_Pr->SiS_ModeType > ModeVGA) { 7961 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84; 7962 } 7963 } 7964 if((*DisplayType) != 84) { 7965 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++; 7966 } 7967 7968 } else { 7969 7970 (*DisplayType = 0); 7971 switch(SiS_Pr->SiS_LCDResInfo) { 7972 case Panel_320x240_1: (*DisplayType) = 50; 7973 checkhd = false; 7974 break; 7975 case Panel_320x240_2: (*DisplayType) = 14; 7976 break; 7977 case Panel_320x240_3: (*DisplayType) = 18; 7978 break; 7979 case Panel_640x480: (*DisplayType) = 10; 7980 break; 7981 case Panel_1024x600: (*DisplayType) = 26; 7982 break; 7983 default: return true; 7984 } 7985 7986 if(checkhd) { 7987 if(modeflag & HalfDCLK) (*DisplayType)++; 7988 } 7989 7990 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) { 7991 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2; 7992 } 7993 7994 } 7995 7996 return true; 7997} 7998 7999static void 8000SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 8001 unsigned short RefreshRateTableIndex) 8002{ 8003 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType; 8004 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL; 8005 static const unsigned short CRIdx[] = { 8006 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 8007 0x07, 0x10, 0x11, 0x15, 0x16 8008 }; 8009 8010 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 8011 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 8012 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 8013 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) 8014 return; 8015 8016 if(SiS_Pr->SiS_IF_DEF_LVDS) { 8017 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 8018 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return; 8019 } 8020 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 8021 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return; 8022 } else return; 8023 8024 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return; 8025 8026 if(SiS_Pr->ChipType < SIS_315H) { 8027 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return; 8028 } 8029 8030 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 8031 &ResIndex, &DisplayType))) { 8032 return; 8033 } 8034 8035 switch(DisplayType) { 8036 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */ 8037 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */ 8038 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */ 8039 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */ 8040 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */ 8041 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break; 8042 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break; 8043#if 0 /* Works better with calculated numbers */ 8044 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break; 8045 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break; 8046 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break; 8047 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break; 8048#endif 8049 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break; 8050 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break; 8051 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break; 8052 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break; 8053 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break; 8054 } 8055 8056 if(LVDSCRT1Ptr) { 8057 8058 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 8059 8060 for(i = 0; i <= 10; i++) { 8061 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i]; 8062 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah); 8063 } 8064 8065 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) { 8066 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; 8067 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah); 8068 } 8069 8070 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0; 8071 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah); 8072 8073 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 8074 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 8075 8076 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5; 8077 if(modeflag & DoubleScanMode) tempah |= 0x80; 8078 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah); 8079 8080 } else { 8081 8082 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); 8083 8084 } 8085} 8086 8087/*********************************************/ 8088/* SET CRT2 ECLK */ 8089/*********************************************/ 8090 8091static void 8092SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 8093 unsigned short RefreshRateTableIndex) 8094{ 8095 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 8096 unsigned short clkbase, vclkindex = 0; 8097 unsigned char sr2b, sr2c; 8098 8099 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 8100 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 8101 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) { 8102 RefreshRateTableIndex--; 8103 } 8104 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 8105 RefreshRateTableIndex); 8106 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 8107 } else { 8108 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 8109 RefreshRateTableIndex); 8110 } 8111 8112 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B; 8113 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C; 8114 8115 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 8116 if(SiS_Pr->SiS_UseROM) { 8117 if(ROMAddr[0x220] & 0x01) { 8118 sr2b = ROMAddr[0x227]; 8119 sr2c = ROMAddr[0x228]; 8120 } 8121 } 8122 } 8123 8124 clkbase = 0x02B; 8125 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 8126 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 8127 clkbase += 3; 8128 } 8129 } 8130 8131 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20); 8132 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 8133 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 8134 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10); 8135 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 8136 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 8137 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00); 8138 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 8139 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 8140} 8141 8142/*********************************************/ 8143/* SET UP CHRONTEL CHIPS */ 8144/*********************************************/ 8145 8146static void 8147SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 8148 unsigned short RefreshRateTableIndex) 8149{ 8150 unsigned short TVType, resindex; 8151 const struct SiS_CHTVRegData *CHTVRegData = NULL; 8152 8153 if(ModeNo <= 0x13) 8154 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 8155 else 8156 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 8157 8158 resindex &= 0x3F; 8159 8160 TVType = 0; 8161 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8162 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 8163 TVType += 2; 8164 if(SiS_Pr->SiS_ModeType > ModeVGA) { 8165 if(SiS_Pr->SiS_CHSOverScan) TVType = 8; 8166 } 8167 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 8168 TVType = 4; 8169 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8170 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 8171 TVType = 6; 8172 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8173 } 8174 } 8175 8176 switch(TVType) { 8177 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break; 8178 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break; 8179 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break; 8180 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8181 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break; 8182 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break; 8183 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break; 8184 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break; 8185 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break; 8186 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8187 } 8188 8189 8190 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8191 8192#ifdef CONFIG_FB_SIS_300 8193 8194 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */ 8195 8196 /* We don't support modes >800x600 */ 8197 if (resindex > 5) return; 8198 8199 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 8200 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/ 8201 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/ 8202 } else { 8203 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/ 8204 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/ 8205 } 8206 8207 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */ 8208 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */ 8209 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */ 8210 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */ 8211 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */ 8212 8213 /* Set minimum flicker filter for Luma channel (SR1-0=00), 8214 minimum text enhancement (S3-2=10), 8215 maximum flicker filter for Chroma channel (S5-4=10) 8216 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!) 8217 */ 8218 SiS_SetCH700x(SiS_Pr,0x01,0x28); 8219 8220 /* Set video bandwidth 8221 High bandwidth Luma composite video filter(S0=1) 8222 low bandwidth Luma S-video filter (S2-1=00) 8223 disable peak filter in S-video channel (S3=0) 8224 high bandwidth Chroma Filter (S5-4=11) 8225 =00110001=0x31 8226 */ 8227 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */ 8228 8229 /* Register 0x3D does not exist in non-macrovision register map 8230 (Maybe this is a macrovision register?) 8231 */ 8232#ifndef SIS_CP 8233 SiS_SetCH70xx(SiS_Pr,0x3d,0x00); 8234#endif 8235 8236 /* Register 0x10 only contains 1 writable bit (S0) for sensing, 8237 all other bits a read-only. Macrovision? 8238 */ 8239 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F); 8240 8241 /* Register 0x11 only contains 3 writable bits (S0-S2) for 8242 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) ) 8243 */ 8244 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8); 8245 8246 /* Clear DSEN 8247 */ 8248 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF); 8249 8250 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */ 8251 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) { 8252 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */ 8253 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8254 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */ 8255 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */ 8256 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */ 8257 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0); 8258 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0); 8259 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0); 8260 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0); 8261 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0); 8262 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0); 8263 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0); 8264 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */ 8265 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */ 8266 } 8267 } else { 8268 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */ 8269 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8270 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); 8271 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */ 8272#if 0 8273 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */ 8274 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */ 8275 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */ 8276 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0); 8277 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0); 8278 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0); 8279 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0); 8280 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0); 8281 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */ 8282 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */ 8283#endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */ 8284 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8285 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); 8286 } 8287 } 8288 } else { /* ---- PAL ---- */ 8289 /* We don't play around with FSCI in PAL mode */ 8290 SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF); /* loop filter off */ 8291 SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE); /* ACIV on */ 8292 } 8293 8294#endif /* 300 */ 8295 8296 } else { 8297 8298 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */ 8299 8300#ifdef CONFIG_FB_SIS_315 8301 8302 unsigned short temp; 8303 8304 /* We don't support modes >1024x768 */ 8305 if (resindex > 6) return; 8306 8307 temp = CHTVRegData[resindex].Reg[0]; 8308 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10; 8309 SiS_SetCH701x(SiS_Pr,0x00,temp); 8310 8311 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]); 8312 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]); 8313 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]); 8314 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]); 8315 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]); 8316 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]); 8317 8318 temp = CHTVRegData[resindex].Reg[7]; 8319 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66; 8320 SiS_SetCH701x(SiS_Pr,0x07,temp); 8321 8322 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]); 8323 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]); 8324 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]); 8325 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]); 8326 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]); 8327 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]); 8328 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]); 8329 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]); 8330 8331 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02; 8332 /* D1 should be set for PAL, PAL-N and NTSC-J, 8333 but I won't do that for PAL unless somebody 8334 tells me to do so. Since the BIOS uses 8335 non-default CIV values and blacklevels, 8336 this might be compensated anyway. 8337 */ 8338 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02; 8339 SiS_SetCH701x(SiS_Pr,0x21,temp); 8340 8341#endif /* 315 */ 8342 8343 } 8344 8345#ifdef SIS_CP 8346 SIS_CP_INIT301_CP3 8347#endif 8348 8349} 8350 8351#ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */ 8352 8353void 8354SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr) 8355{ 8356 unsigned short temp; 8357 8358 /* Enable Chrontel 7019 LCD panel backlight */ 8359 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8360 if(SiS_Pr->ChipType == SIS_740) { 8361 SiS_SetCH701x(SiS_Pr,0x66,0x65); 8362 } else { 8363 temp = SiS_GetCH701x(SiS_Pr,0x66); 8364 temp |= 0x20; 8365 SiS_SetCH701x(SiS_Pr,0x66,temp); 8366 } 8367 } 8368} 8369 8370void 8371SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr) 8372{ 8373 unsigned short temp; 8374 8375 /* Disable Chrontel 7019 LCD panel backlight */ 8376 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8377 temp = SiS_GetCH701x(SiS_Pr,0x66); 8378 temp &= 0xDF; 8379 SiS_SetCH701x(SiS_Pr,0x66,temp); 8380 } 8381} 8382 8383static void 8384SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr) 8385{ 8386 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b }; 8387 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 }; 8388 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 }; 8389 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8390 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8391 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8392 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8393 const unsigned char *tableptr = NULL; 8394 int i; 8395 8396 /* Set up Power up/down timing */ 8397 8398 if(SiS_Pr->ChipType == SIS_740) { 8399 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8400 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740; 8401 else tableptr = table1024_740; 8402 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8403 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8404 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8405 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740; 8406 else tableptr = table1400_740; 8407 } else return; 8408 } else { 8409 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8410 tableptr = table1024_650; 8411 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8412 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8413 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8414 tableptr = table1400_650; 8415 } else return; 8416 } 8417 8418 for(i=0; i<5; i++) { 8419 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]); 8420 } 8421} 8422 8423static void 8424SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr) 8425{ 8426 const unsigned char *tableptr = NULL; 8427 unsigned short tempbh; 8428 int i; 8429 static const unsigned char regtable[] = { 8430 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71, 8431 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 8432 }; 8433 static const unsigned char table1024_740[] = { 8434 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, 8435 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 8436 }; 8437 static const unsigned char table1280_740[] = { 8438 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8439 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 8440 }; 8441 static const unsigned char table1400_740[] = { 8442 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8443 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 8444 }; 8445 static const unsigned char table1600_740[] = { 8446 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, 8447 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 8448 }; 8449 static const unsigned char table1024_650[] = { 8450 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, 8451 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 8452 }; 8453 static const unsigned char table1280_650[] = { 8454 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8455 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 8456 }; 8457 static const unsigned char table1400_650[] = { 8458 0x60, 0x03, 0x11, 0x00, 0x40, 0xef, 8459 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 8460 }; 8461 static const unsigned char table1600_650[] = { 8462 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, 8463 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a 8464 }; 8465 8466 if(SiS_Pr->ChipType == SIS_740) { 8467 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740; 8468 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740; 8469 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740; 8470 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740; 8471 else return; 8472 } else { 8473 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650; 8474 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650; 8475 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650; 8476 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650; 8477 else return; 8478 } 8479 8480 tempbh = SiS_GetCH701x(SiS_Pr,0x74); 8481 if((tempbh == 0xf6) || (tempbh == 0xc7)) { 8482 tempbh = SiS_GetCH701x(SiS_Pr,0x73); 8483 if(tempbh == 0xc8) { 8484 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return; 8485 } else if(tempbh == 0xdb) { 8486 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return; 8487 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return; 8488 } else if(tempbh == 0xde) { 8489 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return; 8490 } 8491 } 8492 8493 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d; 8494 else tempbh = 0x0c; 8495 8496 for(i = 0; i < tempbh; i++) { 8497 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]); 8498 } 8499 SiS_ChrontelPowerSequencing(SiS_Pr); 8500 tempbh = SiS_GetCH701x(SiS_Pr,0x1e); 8501 tempbh |= 0xc0; 8502 SiS_SetCH701x(SiS_Pr,0x1e,tempbh); 8503 8504 if(SiS_Pr->ChipType == SIS_740) { 8505 tempbh = SiS_GetCH701x(SiS_Pr,0x1c); 8506 tempbh &= 0xfb; 8507 SiS_SetCH701x(SiS_Pr,0x1c,tempbh); 8508 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8509 tempbh = SiS_GetCH701x(SiS_Pr,0x64); 8510 tempbh |= 0x40; 8511 SiS_SetCH701x(SiS_Pr,0x64,tempbh); 8512 tempbh = SiS_GetCH701x(SiS_Pr,0x03); 8513 tempbh &= 0x3f; 8514 SiS_SetCH701x(SiS_Pr,0x03,tempbh); 8515 } 8516} 8517 8518static void 8519SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr) 8520{ 8521 unsigned char temp, temp1; 8522 8523 temp1 = SiS_GetCH701x(SiS_Pr,0x49); 8524 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 8525 temp = SiS_GetCH701x(SiS_Pr,0x47); 8526 temp &= 0x7f; /* Use external VSYNC */ 8527 SiS_SetCH701x(SiS_Pr,0x47,temp); 8528 SiS_LongDelay(SiS_Pr, 3); 8529 temp = SiS_GetCH701x(SiS_Pr,0x47); 8530 temp |= 0x80; /* Use internal VSYNC */ 8531 SiS_SetCH701x(SiS_Pr,0x47,temp); 8532 SiS_SetCH701x(SiS_Pr,0x49,temp1); 8533} 8534 8535static void 8536SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr) 8537{ 8538 unsigned short temp; 8539 8540 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8541 if(SiS_Pr->ChipType == SIS_740) { 8542 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8543 temp |= 0x04; /* Invert XCLK phase */ 8544 SiS_SetCH701x(SiS_Pr,0x1c,temp); 8545 } 8546 if(SiS_IsYPbPr(SiS_Pr)) { 8547 temp = SiS_GetCH701x(SiS_Pr,0x01); 8548 temp &= 0x3f; 8549 temp |= 0x80; /* Enable YPrPb (HDTV) */ 8550 SiS_SetCH701x(SiS_Pr,0x01,temp); 8551 } 8552 if(SiS_IsChScart(SiS_Pr)) { 8553 temp = SiS_GetCH701x(SiS_Pr,0x01); 8554 temp &= 0x3f; 8555 temp |= 0xc0; /* Enable SCART + CVBS */ 8556 SiS_SetCH701x(SiS_Pr,0x01,temp); 8557 } 8558 if(SiS_Pr->ChipType == SIS_740) { 8559 SiS_ChrontelResetVSync(SiS_Pr); 8560 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */ 8561 } else { 8562 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */ 8563 temp = SiS_GetCH701x(SiS_Pr,0x49); 8564 if(SiS_IsYPbPr(SiS_Pr)) { 8565 temp = SiS_GetCH701x(SiS_Pr,0x73); 8566 temp |= 0x60; 8567 SiS_SetCH701x(SiS_Pr,0x73,temp); 8568 } 8569 temp = SiS_GetCH701x(SiS_Pr,0x47); 8570 temp &= 0x7f; 8571 SiS_SetCH701x(SiS_Pr,0x47,temp); 8572 SiS_LongDelay(SiS_Pr, 2); 8573 temp = SiS_GetCH701x(SiS_Pr,0x47); 8574 temp |= 0x80; 8575 SiS_SetCH701x(SiS_Pr,0x47,temp); 8576 } 8577 } 8578} 8579 8580static void 8581SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr) 8582{ 8583 unsigned short temp; 8584 8585 /* Complete power down of LVDS */ 8586 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8587 if(SiS_Pr->ChipType == SIS_740) { 8588 SiS_LongDelay(SiS_Pr, 1); 8589 SiS_GenericDelay(SiS_Pr, 5887); 8590 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8591 SiS_SetCH701x(SiS_Pr,0x66,0x00); 8592 } else { 8593 SiS_LongDelay(SiS_Pr, 2); 8594 temp = SiS_GetCH701x(SiS_Pr,0x76); 8595 temp &= 0xfc; 8596 SiS_SetCH701x(SiS_Pr,0x76,temp); 8597 SiS_SetCH701x(SiS_Pr,0x66,0x00); 8598 } 8599 } 8600} 8601 8602static void 8603SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr) 8604{ 8605 unsigned short temp; 8606 8607 if(SiS_Pr->ChipType == SIS_740) { 8608 8609 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */ 8610 temp &= 0x01; 8611 if(!temp) { 8612 8613 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8614 temp = SiS_GetCH701x(SiS_Pr,0x49); 8615 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 8616 } 8617 8618 /* Reset Chrontel 7019 datapath */ 8619 SiS_SetCH701x(SiS_Pr,0x48,0x10); 8620 SiS_LongDelay(SiS_Pr, 1); 8621 SiS_SetCH701x(SiS_Pr,0x48,0x18); 8622 8623 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8624 SiS_ChrontelResetVSync(SiS_Pr); 8625 SiS_SetCH701x(SiS_Pr,0x49,temp); 8626 } 8627 8628 } else { 8629 8630 /* Clear/set/clear GPIO */ 8631 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8632 temp &= 0xef; 8633 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8634 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8635 temp |= 0x10; 8636 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8637 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8638 temp &= 0xef; 8639 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8640 temp = SiS_GetCH701x(SiS_Pr,0x61); 8641 if(!temp) { 8642 SiS_SetCH701xForLCD(SiS_Pr); 8643 } 8644 } 8645 8646 } else { /* 650 */ 8647 /* Reset Chrontel 7019 datapath */ 8648 SiS_SetCH701x(SiS_Pr,0x48,0x10); 8649 SiS_LongDelay(SiS_Pr, 1); 8650 SiS_SetCH701x(SiS_Pr,0x48,0x18); 8651 } 8652} 8653 8654static void 8655SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr) 8656{ 8657 unsigned short temp; 8658 8659 if(SiS_Pr->ChipType == SIS_740) { 8660 8661 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8662 SiS_ChrontelResetVSync(SiS_Pr); 8663 } 8664 8665 } else { 8666 8667 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */ 8668 temp = SiS_GetCH701x(SiS_Pr,0x49); 8669 temp &= 1; 8670 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */ 8671 temp = SiS_GetCH701x(SiS_Pr,0x47); 8672 temp &= 0x70; 8673 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */ 8674 SiS_LongDelay(SiS_Pr, 3); 8675 temp = SiS_GetCH701x(SiS_Pr,0x47); 8676 temp |= 0x80; 8677 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */ 8678 } 8679 8680 } 8681} 8682 8683static void 8684SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 8685{ 8686 unsigned short temp,temp1; 8687 8688 if(SiS_Pr->ChipType == SIS_740) { 8689 8690 temp = SiS_GetCH701x(SiS_Pr,0x61); 8691 if(temp < 1) { 8692 temp++; 8693 SiS_SetCH701x(SiS_Pr,0x61,temp); 8694 } 8695 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */ 8696 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */ 8697 SiS_LongDelay(SiS_Pr, 1); 8698 SiS_GenericDelay(SiS_Pr, 5887); 8699 8700 } else { /* 650 */ 8701 8702 temp1 = 0; 8703 temp = SiS_GetCH701x(SiS_Pr,0x61); 8704 if(temp < 2) { 8705 temp++; 8706 SiS_SetCH701x(SiS_Pr,0x61,temp); 8707 temp1 = 1; 8708 } 8709 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8710 temp = SiS_GetCH701x(SiS_Pr,0x66); 8711 temp |= 0x5f; 8712 SiS_SetCH701x(SiS_Pr,0x66,temp); 8713 if(ModeNo > 0x13) { 8714 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8715 SiS_GenericDelay(SiS_Pr, 1023); 8716 } else { 8717 SiS_GenericDelay(SiS_Pr, 767); 8718 } 8719 } else { 8720 if(!temp1) 8721 SiS_GenericDelay(SiS_Pr, 767); 8722 } 8723 temp = SiS_GetCH701x(SiS_Pr,0x76); 8724 temp |= 0x03; 8725 SiS_SetCH701x(SiS_Pr,0x76,temp); 8726 temp = SiS_GetCH701x(SiS_Pr,0x66); 8727 temp &= 0x7f; 8728 SiS_SetCH701x(SiS_Pr,0x66,temp); 8729 SiS_LongDelay(SiS_Pr, 1); 8730 8731 } 8732} 8733 8734static void 8735SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr) 8736{ 8737 unsigned short temp; 8738 8739 SiS_LongDelay(SiS_Pr, 1); 8740 8741 do { 8742 temp = SiS_GetCH701x(SiS_Pr,0x66); 8743 temp &= 0x04; /* PLL stable? -> bail out */ 8744 if(temp == 0x04) break; 8745 8746 if(SiS_Pr->ChipType == SIS_740) { 8747 /* Power down LVDS output, PLL normal operation */ 8748 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8749 } 8750 8751 SiS_SetCH701xForLCD(SiS_Pr); 8752 8753 temp = SiS_GetCH701x(SiS_Pr,0x76); 8754 temp &= 0xfb; /* Reset PLL */ 8755 SiS_SetCH701x(SiS_Pr,0x76,temp); 8756 SiS_LongDelay(SiS_Pr, 2); 8757 temp = SiS_GetCH701x(SiS_Pr,0x76); 8758 temp |= 0x04; /* PLL normal operation */ 8759 SiS_SetCH701x(SiS_Pr,0x76,temp); 8760 if(SiS_Pr->ChipType == SIS_740) { 8761 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */ 8762 } else { 8763 SiS_SetCH701x(SiS_Pr,0x78,0x60); 8764 } 8765 SiS_LongDelay(SiS_Pr, 2); 8766 } while(0); 8767 8768 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */ 8769} 8770 8771static void 8772SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr) 8773{ 8774 unsigned short temp; 8775 8776 temp = SiS_GetCH701x(SiS_Pr,0x03); 8777 temp |= 0x80; /* Set datapath 1 to TV */ 8778 temp &= 0xbf; /* Set datapath 2 to LVDS */ 8779 SiS_SetCH701x(SiS_Pr,0x03,temp); 8780 8781 if(SiS_Pr->ChipType == SIS_740) { 8782 8783 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8784 temp &= 0xfb; /* Normal XCLK phase */ 8785 SiS_SetCH701x(SiS_Pr,0x1c,temp); 8786 8787 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8788 8789 temp = SiS_GetCH701x(SiS_Pr,0x64); 8790 temp |= 0x40; /* ? Bit not defined */ 8791 SiS_SetCH701x(SiS_Pr,0x64,temp); 8792 8793 temp = SiS_GetCH701x(SiS_Pr,0x03); 8794 temp &= 0x3f; /* D1 input to both LVDS and TV */ 8795 SiS_SetCH701x(SiS_Pr,0x03,temp); 8796 8797 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) { 8798 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */ 8799 SiS_LongDelay(SiS_Pr, 1); 8800 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */ 8801 SiS_ChrontelResetDB(SiS_Pr); 8802 SiS_ChrontelDoSomething2(SiS_Pr); 8803 SiS_ChrontelDoSomething3(SiS_Pr, 0); 8804 } else { 8805 temp = SiS_GetCH701x(SiS_Pr,0x66); 8806 if(temp != 0x45) { 8807 SiS_ChrontelResetDB(SiS_Pr); 8808 SiS_ChrontelDoSomething2(SiS_Pr); 8809 SiS_ChrontelDoSomething3(SiS_Pr, 0); 8810 } 8811 } 8812 8813 } else { /* 650 */ 8814 8815 SiS_ChrontelResetDB(SiS_Pr); 8816 SiS_ChrontelDoSomething2(SiS_Pr); 8817 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34); 8818 SiS_ChrontelDoSomething3(SiS_Pr,temp); 8819 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */ 8820 8821 } 8822 8823} 8824#endif /* 315 series */ 8825 8826/*********************************************/ 8827/* MAIN: SET CRT2 REGISTER GROUP */ 8828/*********************************************/ 8829 8830bool 8831SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 8832{ 8833#ifdef CONFIG_FB_SIS_300 8834 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 8835#endif 8836 unsigned short ModeIdIndex, RefreshRateTableIndex; 8837 8838 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 8839 8840 if(!SiS_Pr->UseCustomMode) { 8841 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex); 8842 } else { 8843 ModeIdIndex = 0; 8844 } 8845 8846 /* Used for shifting CR33 */ 8847 SiS_Pr->SiS_SelectCRT2Rate = 4; 8848 8849 SiS_UnLockCRT2(SiS_Pr); 8850 8851 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex); 8852 8853 SiS_SaveCRT2Info(SiS_Pr,ModeNo); 8854 8855 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8856 SiS_DisableBridge(SiS_Pr); 8857 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) { 8858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80); 8859 } 8860 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex); 8861 } 8862 8863 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 8864 SiS_LockCRT2(SiS_Pr); 8865 SiS_DisplayOn(SiS_Pr); 8866 return true; 8867 } 8868 8869 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8870 8871 /* Set up Panel Link for LVDS and LCDA */ 8872 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; 8873 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 8874 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) || 8875 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) { 8876 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8877 } 8878 8879 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8880 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8881 } 8882 8883 if(SiS_Pr->SiS_VBType & VB_SISVB) { 8884 8885 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8886 8887 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8888#ifdef CONFIG_FB_SIS_315 8889 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8890#endif 8891 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex); 8892 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8893#ifdef CONFIG_FB_SIS_315 8894 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex); 8895#endif 8896 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex); 8897 8898 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex); 8899 8900 /* For 301BDH (Panel link initialization): */ 8901 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 8902 8903 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) { 8904 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 8905 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8906 } 8907 } 8908 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8909 } 8910 } 8911 8912 } else { 8913 8914 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex); 8915 8916 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8917 8918 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8919 8920 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8921 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 8922 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 8923 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8924#ifdef CONFIG_FB_SIS_315 8925 SiS_SetCH701xForLCD(SiS_Pr); 8926#endif 8927 } 8928 } 8929 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8930 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8931 } 8932 } 8933 } 8934 8935 } 8936 8937#ifdef CONFIG_FB_SIS_300 8938 if(SiS_Pr->ChipType < SIS_315H) { 8939 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8940 if(SiS_Pr->SiS_UseOEM) { 8941 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) { 8942 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 8943 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8944 } 8945 } else { 8946 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8947 } 8948 } 8949 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 8950 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 8951 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 8952 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex); 8953 } 8954 SiS_DisplayOn(SiS_Pr); 8955 } 8956 } 8957 } 8958#endif 8959 8960#ifdef CONFIG_FB_SIS_315 8961 if(SiS_Pr->ChipType >= SIS_315H) { 8962 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8963 if(SiS_Pr->ChipType < SIS_661) { 8964 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex); 8965 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8966 } else { 8967 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8968 } 8969 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40); 8970 } 8971 } 8972#endif 8973 8974 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8975 SiS_EnableBridge(SiS_Pr); 8976 } 8977 8978 SiS_DisplayOn(SiS_Pr); 8979 8980 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8981 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8982 /* Disable LCD panel when using TV */ 8983 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C); 8984 } else { 8985 /* Disable TV when using LCD */ 8986 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8); 8987 } 8988 } 8989 8990 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8991 SiS_LockCRT2(SiS_Pr); 8992 } 8993 8994 return true; 8995} 8996 8997 8998/*********************************************/ 8999/* ENABLE/DISABLE LCD BACKLIGHT (SIS) */ 9000/*********************************************/ 9001 9002void 9003SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr) 9004{ 9005 /* Switch on LCD backlight on SiS30xLV */ 9006 SiS_DDC2Delay(SiS_Pr,0xff00); 9007 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 9008 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 9009 SiS_WaitVBRetrace(SiS_Pr); 9010 } 9011 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) { 9012 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 9013 } 9014} 9015 9016void 9017SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr) 9018{ 9019 /* Switch off LCD backlight on SiS30xLV */ 9020 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 9021 SiS_DDC2Delay(SiS_Pr,0xff00); 9022} 9023 9024/*********************************************/ 9025/* DDC RELATED FUNCTIONS */ 9026/*********************************************/ 9027 9028static void 9029SiS_SetupDDCN(struct SiS_Private *SiS_Pr) 9030{ 9031 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data; 9032 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk; 9033 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) { 9034 SiS_Pr->SiS_DDC_NData &= 0x0f; 9035 SiS_Pr->SiS_DDC_NClk &= 0x0f; 9036 } 9037} 9038 9039#ifdef CONFIG_FB_SIS_300 9040static unsigned char * 9041SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr) 9042{ 9043 int i, j, num; 9044 unsigned short tempah,temp; 9045 unsigned char *mydataptr; 9046 9047 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 9048 mydataptr = dataptr; 9049 num = *mydataptr++; 9050 if(!num) return mydataptr; 9051 if(i) { 9052 SiS_SetStop(SiS_Pr); 9053 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2); 9054 } 9055 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9056 tempah = SiS_Pr->SiS_DDC_DeviceAddr; 9057 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ 9058 if(temp) continue; /* (ERROR: no ack) */ 9059 tempah = *mydataptr++; 9060 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */ 9061 if(temp) continue; /* (ERROR: no ack) */ 9062 for(j=0; j<num; j++) { 9063 tempah = *mydataptr++; 9064 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */ 9065 if(temp) break; 9066 } 9067 if(temp) continue; 9068 if(SiS_SetStop(SiS_Pr)) continue; 9069 return mydataptr; 9070 } 9071 return NULL; 9072} 9073 9074static bool 9075SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr) 9076{ 9077 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */ 9078 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9079 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9080 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9081 SiS_SetupDDCN(SiS_Pr); 9082 9083 SiS_SetSwitchDDC2(SiS_Pr); 9084 9085 while(*dataptr) { 9086 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr); 9087 if(!dataptr) return false; 9088 } 9089 return true; 9090} 9091#endif 9092 9093/* The Chrontel 700x is connected to the 630/730 via 9094 * the 630/730's DDC/I2C port. 9095 * 9096 * On 630(S)T chipset, the index changed from 0x11 to 9097 * 0x0a, possibly for working around the DDC problems 9098 */ 9099 9100static bool 9101SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor) 9102{ 9103 unsigned short temp, i; 9104 9105 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 9106 if(i) { 9107 SiS_SetStop(SiS_Pr); 9108 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4); 9109 } 9110 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9111 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */ 9112 if(temp) continue; /* (ERROR: no ack) */ 9113 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */ 9114 if(temp) continue; /* (ERROR: no ack) */ 9115 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */ 9116 if(temp) continue; /* (ERROR: no ack) */ 9117 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */ 9118 SiS_Pr->SiS_ChrontelInit = 1; 9119 return true; 9120 } 9121 return false; 9122} 9123 9124/* Write to Chrontel 700x */ 9125void 9126SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9127{ 9128 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 9129 9130 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9131 9132 if(!(SiS_Pr->SiS_ChrontelInit)) { 9133 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9134 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9135 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9136 SiS_SetupDDCN(SiS_Pr); 9137 } 9138 9139 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) && 9140 (!(SiS_Pr->SiS_ChrontelInit)) ) { 9141 SiS_Pr->SiS_DDC_Index = 0x0a; 9142 SiS_Pr->SiS_DDC_Data = 0x80; 9143 SiS_Pr->SiS_DDC_Clk = 0x40; 9144 SiS_SetupDDCN(SiS_Pr); 9145 9146 SiS_SetChReg(SiS_Pr, reg, val, 0x80); 9147 } 9148} 9149 9150/* Write to Chrontel 701x */ 9151/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */ 9152void 9153SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9154{ 9155 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9156 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9157 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9158 SiS_SetupDDCN(SiS_Pr); 9159 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 9160 SiS_SetChReg(SiS_Pr, reg, val, 0); 9161} 9162 9163static 9164void 9165SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9166{ 9167 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9168 SiS_SetCH700x(SiS_Pr, reg, val); 9169 else 9170 SiS_SetCH701x(SiS_Pr, reg, val); 9171} 9172 9173static unsigned short 9174SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor) 9175{ 9176 unsigned short tempah, temp, i; 9177 9178 for(i=0; i<20; i++) { /* Do 20 attempts to read */ 9179 if(i) { 9180 SiS_SetStop(SiS_Pr); 9181 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4); 9182 } 9183 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9184 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */ 9185 if(temp) continue; /* (ERROR: no ack) */ 9186 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */ 9187 if(temp) continue; /* (ERROR: no ack) */ 9188 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */ 9189 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */ 9190 if(temp) continue; /* (ERROR: no ack) */ 9191 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */ 9192 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */ 9193 SiS_Pr->SiS_ChrontelInit = 1; 9194 return tempah; 9195 } 9196 return 0xFFFF; 9197} 9198 9199/* Read from Chrontel 700x */ 9200/* Parameter is [Register no (S7-S0)] */ 9201unsigned short 9202SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9203{ 9204 unsigned short result; 9205 9206 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9207 9208 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9209 9210 if(!(SiS_Pr->SiS_ChrontelInit)) { 9211 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9212 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9213 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9214 SiS_SetupDDCN(SiS_Pr); 9215 } 9216 9217 SiS_Pr->SiS_DDC_ReadAddr = tempbx; 9218 9219 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) && 9220 (!SiS_Pr->SiS_ChrontelInit) ) { 9221 9222 SiS_Pr->SiS_DDC_Index = 0x0a; 9223 SiS_Pr->SiS_DDC_Data = 0x80; 9224 SiS_Pr->SiS_DDC_Clk = 0x40; 9225 SiS_SetupDDCN(SiS_Pr); 9226 9227 result = SiS_GetChReg(SiS_Pr,0x80); 9228 } 9229 return result; 9230} 9231 9232/* Read from Chrontel 701x */ 9233/* Parameter is [Register no (S7-S0)] */ 9234unsigned short 9235SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9236{ 9237 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9238 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9239 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9240 SiS_SetupDDCN(SiS_Pr); 9241 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9242 9243 SiS_Pr->SiS_DDC_ReadAddr = tempbx; 9244 9245 return SiS_GetChReg(SiS_Pr,0); 9246} 9247 9248/* Read from Chrontel 70xx */ 9249/* Parameter is [Register no (S7-S0)] */ 9250static 9251unsigned short 9252SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9253{ 9254 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9255 return SiS_GetCH700x(SiS_Pr, tempbx); 9256 else 9257 return SiS_GetCH701x(SiS_Pr, tempbx); 9258} 9259 9260void 9261SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg, 9262 unsigned char myor, unsigned short myand) 9263{ 9264 unsigned short tempbl; 9265 9266 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor; 9267 SiS_SetCH70xx(SiS_Pr, reg, tempbl); 9268} 9269 9270/* Our own DDC functions */ 9271static 9272unsigned short 9273SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, 9274 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32, 9275 unsigned int VBFlags2) 9276{ 9277 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 }; 9278 unsigned char flag, cr32; 9279 unsigned short temp = 0, myadaptnum = adaptnum; 9280 9281 if(adaptnum != 0) { 9282 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF; 9283 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF; 9284 } 9285 9286 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */ 9287 9288 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */ 9289 9290 SiS_Pr->SiS_DDC_SecAddr = 0; 9291 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype]; 9292 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4; 9293 SiS_Pr->SiS_DDC_Index = 0x11; 9294 flag = 0xff; 9295 9296 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32); 9297 9298#if 0 9299 if(VBFlags2 & VB2_SISBRIDGE) { 9300 if(myadaptnum == 0) { 9301 if(!(cr32 & 0x20)) { 9302 myadaptnum = 2; 9303 if(!(cr32 & 0x10)) { 9304 myadaptnum = 1; 9305 if(!(cr32 & 0x08)) { 9306 myadaptnum = 0; 9307 } 9308 } 9309 } 9310 } 9311 } 9312#endif 9313 9314 if(VGAEngine == SIS_300_VGA) { /* 300 series */ 9315 9316 if(myadaptnum != 0) { 9317 flag = 0; 9318 if(VBFlags2 & VB2_SISBRIDGE) { 9319 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9320 SiS_Pr->SiS_DDC_Index = 0x0f; 9321 } 9322 } 9323 9324 if(!(VBFlags2 & VB2_301)) { 9325 if((cr32 & 0x80) && (checkcr32)) { 9326 if(myadaptnum >= 1) { 9327 if(!(cr32 & 0x08)) { 9328 myadaptnum = 1; 9329 if(!(cr32 & 0x10)) return 0xFFFF; 9330 } 9331 } 9332 } 9333 } 9334 9335 temp = 4 - (myadaptnum * 2); 9336 if(flag) temp = 0; 9337 9338 } else { /* 315/330 series */ 9339 9340 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */ 9341 9342 if(VBFlags2 & VB2_SISBRIDGE) { 9343 if(myadaptnum == 2) { 9344 myadaptnum = 1; 9345 } 9346 } 9347 9348 if(myadaptnum == 1) { 9349 flag = 0; 9350 if(VBFlags2 & VB2_SISBRIDGE) { 9351 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9352 SiS_Pr->SiS_DDC_Index = 0x0f; 9353 } 9354 } 9355 9356 if((cr32 & 0x80) && (checkcr32)) { 9357 if(myadaptnum >= 1) { 9358 if(!(cr32 & 0x08)) { 9359 myadaptnum = 1; 9360 if(!(cr32 & 0x10)) return 0xFFFF; 9361 } 9362 } 9363 } 9364 9365 temp = myadaptnum; 9366 if(myadaptnum == 1) { 9367 temp = 0; 9368 if(VBFlags2 & VB2_LVDS) flag = 0xff; 9369 } 9370 9371 if(flag) temp = 0; 9372 } 9373 9374 SiS_Pr->SiS_DDC_Data = 0x02 << temp; 9375 SiS_Pr->SiS_DDC_Clk = 0x01 << temp; 9376 9377 SiS_SetupDDCN(SiS_Pr); 9378 9379 return 0; 9380} 9381 9382static unsigned short 9383SiS_WriteDABDDC(struct SiS_Private *SiS_Pr) 9384{ 9385 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9386 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) { 9387 return 0xFFFF; 9388 } 9389 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) { 9390 return 0xFFFF; 9391 } 9392 return 0; 9393} 9394 9395static unsigned short 9396SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr) 9397{ 9398 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9399 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) { 9400 return 0xFFFF; 9401 } 9402 return 0; 9403} 9404 9405static unsigned short 9406SiS_PrepareDDC(struct SiS_Private *SiS_Pr) 9407{ 9408 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr); 9409 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr)); 9410 return 0; 9411} 9412 9413static void 9414SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno) 9415{ 9416 SiS_SetSCLKLow(SiS_Pr); 9417 if(yesno) { 9418 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9419 SiS_Pr->SiS_DDC_Index, 9420 SiS_Pr->SiS_DDC_NData, 9421 SiS_Pr->SiS_DDC_Data); 9422 } else { 9423 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9424 SiS_Pr->SiS_DDC_Index, 9425 SiS_Pr->SiS_DDC_NData, 9426 0); 9427 } 9428 SiS_SetSCLKHigh(SiS_Pr); 9429} 9430 9431static unsigned short 9432SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) 9433{ 9434 unsigned char mask, value; 9435 unsigned short temp, ret=0; 9436 bool failed = false; 9437 9438 SiS_SetSwitchDDC2(SiS_Pr); 9439 if(SiS_PrepareDDC(SiS_Pr)) { 9440 SiS_SetStop(SiS_Pr); 9441 return 0xFFFF; 9442 } 9443 mask = 0xf0; 9444 value = 0x20; 9445 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9446 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9447 SiS_SendACK(SiS_Pr, 0); 9448 if(temp == 0) { 9449 mask = 0xff; 9450 value = 0xff; 9451 } else { 9452 failed = true; 9453 ret = 0xFFFF; 9454 } 9455 } 9456 if(!failed) { 9457 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9458 SiS_SendACK(SiS_Pr, 1); 9459 temp &= mask; 9460 if(temp == value) ret = 0; 9461 else { 9462 ret = 0xFFFF; 9463 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9464 if(temp == 0x30) ret = 0; 9465 } 9466 } 9467 } 9468 SiS_SetStop(SiS_Pr); 9469 return ret; 9470} 9471 9472static 9473unsigned short 9474SiS_ProbeDDC(struct SiS_Private *SiS_Pr) 9475{ 9476 unsigned short flag; 9477 9478 flag = 0x180; 9479 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; 9480 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02; 9481 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; 9482 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08; 9483 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; 9484 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10; 9485 if(!(flag & 0x1a)) flag = 0; 9486 return flag; 9487} 9488 9489static 9490unsigned short 9491SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer) 9492{ 9493 unsigned short flag, length, i; 9494 unsigned char chksum,gotcha; 9495 9496 if(DDCdatatype > 4) return 0xFFFF; 9497 9498 flag = 0; 9499 SiS_SetSwitchDDC2(SiS_Pr); 9500 if(!(SiS_PrepareDDC(SiS_Pr))) { 9501 length = 127; 9502 if(DDCdatatype != 1) length = 255; 9503 chksum = 0; 9504 gotcha = 0; 9505 for(i=0; i<length; i++) { 9506 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9507 chksum += buffer[i]; 9508 gotcha |= buffer[i]; 9509 SiS_SendACK(SiS_Pr, 0); 9510 } 9511 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9512 chksum += buffer[i]; 9513 SiS_SendACK(SiS_Pr, 1); 9514 if(gotcha) flag = (unsigned short)chksum; 9515 else flag = 0xFFFF; 9516 } else { 9517 flag = 0xFFFF; 9518 } 9519 SiS_SetStop(SiS_Pr); 9520 return flag; 9521} 9522 9523/* Our private DDC functions 9524 9525 It complies somewhat with the corresponding VESA function 9526 in arguments and return values. 9527 9528 Since this is probably called before the mode is changed, 9529 we use our pre-detected pSiS-values instead of SiS_Pr as 9530 regards chipset and video bridge type. 9531 9532 Arguments: 9533 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog) 9534 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B. 9535 LCDA is CRT1, but DDC is read from CRT2 port. 9536 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2) 9537 buffer: ptr to 256 data bytes which will be filled with read data. 9538 9539 Returns 0xFFFF if error, otherwise 9540 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum) 9541 if DDCdatatype = 0: Returns supported DDC modes 9542 9543 */ 9544unsigned short 9545SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, 9546 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer, 9547 unsigned int VBFlags2) 9548{ 9549 unsigned char sr1f, cr17=1; 9550 unsigned short result; 9551 9552 if(adaptnum > 2) 9553 return 0xFFFF; 9554 9555 if(DDCdatatype > 4) 9556 return 0xFFFF; 9557 9558 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0)) 9559 return 0xFFFF; 9560 9561 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF) 9562 return 0xFFFF; 9563 9564 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f); 9565 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04); 9566 if(VGAEngine == SIS_300_VGA) { 9567 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80; 9568 if(!cr17) { 9569 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80); 9570 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01); 9571 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); 9572 } 9573 } 9574 if((sr1f) || (!cr17)) { 9575 SiS_WaitRetrace1(SiS_Pr); 9576 SiS_WaitRetrace1(SiS_Pr); 9577 SiS_WaitRetrace1(SiS_Pr); 9578 SiS_WaitRetrace1(SiS_Pr); 9579 } 9580 9581 if(DDCdatatype == 0) { 9582 result = SiS_ProbeDDC(SiS_Pr); 9583 } else { 9584 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer); 9585 if((!result) && (DDCdatatype == 1)) { 9586 if((buffer[0] == 0x00) && (buffer[1] == 0xff) && 9587 (buffer[2] == 0xff) && (buffer[3] == 0xff) && 9588 (buffer[4] == 0xff) && (buffer[5] == 0xff) && 9589 (buffer[6] == 0xff) && (buffer[7] == 0x00) && 9590 (buffer[0x12] == 1)) { 9591 if(!SiS_Pr->DDCPortMixup) { 9592 if(adaptnum == 1) { 9593 if(!(buffer[0x14] & 0x80)) result = 0xFFFE; 9594 } else { 9595 if(buffer[0x14] & 0x80) result = 0xFFFE; 9596 } 9597 } 9598 } 9599 } 9600 } 9601 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f); 9602 if(VGAEngine == SIS_300_VGA) { 9603 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17); 9604 } 9605 return result; 9606} 9607 9608/* Generic I2C functions for Chrontel & DDC --------- */ 9609 9610static void 9611SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr) 9612{ 9613 SiS_SetSCLKHigh(SiS_Pr); 9614 SiS_WaitRetrace1(SiS_Pr); 9615 9616 SiS_SetSCLKLow(SiS_Pr); 9617 SiS_WaitRetrace1(SiS_Pr); 9618} 9619 9620unsigned short 9621SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr) 9622{ 9623 SiS_WaitRetrace1(SiS_Pr); 9624 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1); 9625} 9626 9627/* Set I2C start condition */ 9628/* This is done by a SD high-to-low transition while SC is high */ 9629static unsigned short 9630SiS_SetStart(struct SiS_Private *SiS_Pr) 9631{ 9632 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9633 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9634 SiS_Pr->SiS_DDC_Index, 9635 SiS_Pr->SiS_DDC_NData, 9636 SiS_Pr->SiS_DDC_Data); /* SD->high */ 9637 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9638 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9639 SiS_Pr->SiS_DDC_Index, 9640 SiS_Pr->SiS_DDC_NData, 9641 0x00); /* SD->low = start condition */ 9642 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9643 return 0; 9644} 9645 9646/* Set I2C stop condition */ 9647/* This is done by a SD low-to-high transition while SC is high */ 9648static unsigned short 9649SiS_SetStop(struct SiS_Private *SiS_Pr) 9650{ 9651 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9652 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9653 SiS_Pr->SiS_DDC_Index, 9654 SiS_Pr->SiS_DDC_NData, 9655 0x00); /* SD->low */ 9656 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9657 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9658 SiS_Pr->SiS_DDC_Index, 9659 SiS_Pr->SiS_DDC_NData, 9660 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */ 9661 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */ 9662 return 0; 9663} 9664 9665/* Write 8 bits of data */ 9666static unsigned short 9667SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax) 9668{ 9669 unsigned short i,flag,temp; 9670 9671 flag = 0x80; 9672 for(i = 0; i < 8; i++) { 9673 SiS_SetSCLKLow(SiS_Pr); /* SC->low */ 9674 if(tempax & flag) { 9675 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9676 SiS_Pr->SiS_DDC_Index, 9677 SiS_Pr->SiS_DDC_NData, 9678 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */ 9679 } else { 9680 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9681 SiS_Pr->SiS_DDC_Index, 9682 SiS_Pr->SiS_DDC_NData, 9683 0x00); /* Write bit (0) to SD */ 9684 } 9685 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */ 9686 flag >>= 1; 9687 } 9688 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */ 9689 return temp; 9690} 9691 9692static unsigned short 9693SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr) 9694{ 9695 unsigned short i, temp, getdata; 9696 9697 getdata = 0; 9698 for(i = 0; i < 8; i++) { 9699 getdata <<= 1; 9700 SiS_SetSCLKLow(SiS_Pr); 9701 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9702 SiS_Pr->SiS_DDC_Index, 9703 SiS_Pr->SiS_DDC_NData, 9704 SiS_Pr->SiS_DDC_Data); 9705 SiS_SetSCLKHigh(SiS_Pr); 9706 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9707 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01; 9708 } 9709 return getdata; 9710} 9711 9712static unsigned short 9713SiS_SetSCLKLow(struct SiS_Private *SiS_Pr) 9714{ 9715 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9716 SiS_Pr->SiS_DDC_Index, 9717 SiS_Pr->SiS_DDC_NClk, 9718 0x00); /* SetSCLKLow() */ 9719 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9720 return 0; 9721} 9722 9723static unsigned short 9724SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr) 9725{ 9726 unsigned short temp, watchdog=1000; 9727 9728 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9729 SiS_Pr->SiS_DDC_Index, 9730 SiS_Pr->SiS_DDC_NClk, 9731 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */ 9732 do { 9733 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9734 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); 9735 if (!watchdog) { 9736 return 0xFFFF; 9737 } 9738 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9739 return 0; 9740} 9741 9742/* Check I2C acknowledge */ 9743/* Returns 0 if ack ok, non-0 if ack not ok */ 9744static unsigned short 9745SiS_CheckACK(struct SiS_Private *SiS_Pr) 9746{ 9747 unsigned short tempah; 9748 9749 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */ 9750 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9751 SiS_Pr->SiS_DDC_Index, 9752 SiS_Pr->SiS_DDC_NData, 9753 SiS_Pr->SiS_DDC_Data); /* (SD->high) */ 9754 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */ 9755 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */ 9756 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */ 9757 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */ 9758 return 0; 9759} 9760 9761/* End of I2C functions ----------------------- */ 9762 9763 9764/* =============== SiS 315/330 O.E.M. ================= */ 9765 9766#ifdef CONFIG_FB_SIS_315 9767 9768static unsigned short 9769GetRAMDACromptr(struct SiS_Private *SiS_Pr) 9770{ 9771 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9772 unsigned short romptr; 9773 9774 if(SiS_Pr->ChipType < SIS_330) { 9775 romptr = SISGETROMW(0x128); 9776 if(SiS_Pr->SiS_VBType & VB_SIS30xB) 9777 romptr = SISGETROMW(0x12a); 9778 } else { 9779 romptr = SISGETROMW(0x1a8); 9780 if(SiS_Pr->SiS_VBType & VB_SIS30xB) 9781 romptr = SISGETROMW(0x1aa); 9782 } 9783 return romptr; 9784} 9785 9786static unsigned short 9787GetLCDromptr(struct SiS_Private *SiS_Pr) 9788{ 9789 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9790 unsigned short romptr; 9791 9792 if(SiS_Pr->ChipType < SIS_330) { 9793 romptr = SISGETROMW(0x120); 9794 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9795 romptr = SISGETROMW(0x122); 9796 } else { 9797 romptr = SISGETROMW(0x1a0); 9798 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9799 romptr = SISGETROMW(0x1a2); 9800 } 9801 return romptr; 9802} 9803 9804static unsigned short 9805GetTVromptr(struct SiS_Private *SiS_Pr) 9806{ 9807 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9808 unsigned short romptr; 9809 9810 if(SiS_Pr->ChipType < SIS_330) { 9811 romptr = SISGETROMW(0x114); 9812 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9813 romptr = SISGETROMW(0x11a); 9814 } else { 9815 romptr = SISGETROMW(0x194); 9816 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9817 romptr = SISGETROMW(0x19a); 9818 } 9819 return romptr; 9820} 9821 9822static unsigned short 9823GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr) 9824{ 9825 unsigned short index; 9826 9827 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 9828 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 9829 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) { 9830 index >>= 4; 9831 index *= 3; 9832 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9833 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9834 return index; 9835 } 9836 } 9837 } 9838 9839 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F; 9840 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5; 9841 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */ 9842 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5; 9843 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5; 9844 } else { 9845 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6; 9846 } 9847 index--; 9848 index *= 3; 9849 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9850 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9851 return index; 9852} 9853 9854static unsigned short 9855GetLCDPtrIndex(struct SiS_Private *SiS_Pr) 9856{ 9857 unsigned short index; 9858 9859 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3; 9860 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9861 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9862 return index; 9863} 9864 9865static unsigned short 9866GetTVPtrIndex(struct SiS_Private *SiS_Pr) 9867{ 9868 unsigned short index; 9869 9870 index = 0; 9871 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1; 9872 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2; 9873 9874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0; 9875 9876 index <<= 1; 9877 9878 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && 9879 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 9880 index++; 9881 } 9882 9883 return index; 9884} 9885 9886static unsigned int 9887GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme) 9888{ 9889 unsigned short index = 0, temp = 0; 9890 9891 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1; 9892 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2; 9893 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3; 9894 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6; 9895 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 9896 index = 4; 9897 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++; 9898 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7; 9899 } 9900 9901 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 9902 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || 9903 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 9904 index += addme; 9905 temp++; 9906 } 9907 temp += 0x0100; 9908 } 9909 return (unsigned int)(index | (temp << 16)); 9910} 9911 9912static unsigned int 9913GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr) 9914{ 9915 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8)); 9916} 9917 9918#if 0 9919static unsigned int 9920GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr) 9921{ 9922 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6)); 9923} 9924#endif 9925 9926static int 9927GetOEMTVPtr661(struct SiS_Private *SiS_Pr) 9928{ 9929 int index = 0; 9930 9931 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2; 9932 if(SiS_Pr->SiS_ROMNew) { 9933 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4; 9934 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6; 9935 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8; 9936 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10; 9937 } else { 9938 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4; 9939 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6; 9940 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8; 9941 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10; 9942 } 9943 9944 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++; 9945 9946 return index; 9947} 9948 9949static void 9950SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 9951{ 9952 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9953 unsigned short delay=0,index,myindex,temp,romptr=0; 9954 bool dochiptest = true; 9955 9956 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 9957 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf); 9958 } else { 9959 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f); 9960 } 9961 9962 /* Find delay (from ROM, internal tables, PCI subsystem) */ 9963 9964 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */ 9965 9966 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 9967 romptr = GetRAMDACromptr(SiS_Pr); 9968 } 9969 if(romptr) delay = ROMAddr[romptr]; 9970 else { 9971 delay = 0x04; 9972 if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 9973 if(IS_SIS650) { 9974 delay = 0x0a; 9975 } else if(IS_SIS740) { 9976 delay = 0x00; 9977 } else { 9978 delay = 0x0c; 9979 } 9980 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 9981 delay = 0x00; 9982 } 9983 } 9984 9985 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */ 9986 9987 bool gotitfrompci = false; 9988 9989 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */ 9990 9991 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 9992 if(SiS_Pr->PDC != -1) { 9993 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f)); 9994 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7)); 9995 return; 9996 } 9997 } else { 9998 if(SiS_Pr->PDCA != -1) { 9999 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0)); 10000 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6)); 10001 return; 10002 } 10003 } 10004 10005 /* Custom Panel? */ 10006 10007 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) { 10008 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10009 delay = 0x00; 10010 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) { 10011 delay = 0x20; 10012 } 10013 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay); 10014 } else { 10015 delay = 0x0c; 10016 if(SiS_Pr->SiS_VBType & VB_SIS301C) { 10017 delay = 0x03; 10018 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) { 10019 delay = 0x00; 10020 } 10021 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10022 if(IS_SIS740) delay = 0x01; 10023 else delay = 0x03; 10024 } 10025 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay); 10026 } 10027 return; 10028 } 10029 10030 /* This is a piece of typical SiS crap: They code the OEM LCD 10031 * delay into the code, at no defined place in the BIOS. 10032 * We now have to start doing a PCI subsystem check here. 10033 */ 10034 10035 switch(SiS_Pr->SiS_CustomT) { 10036 case CUT_COMPAQ1280: 10037 case CUT_COMPAQ12802: 10038 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 10039 gotitfrompci = true; 10040 dochiptest = false; 10041 delay = 0x03; 10042 } 10043 break; 10044 case CUT_CLEVO1400: 10045 case CUT_CLEVO14002: 10046 gotitfrompci = true; 10047 dochiptest = false; 10048 delay = 0x02; 10049 break; 10050 case CUT_CLEVO1024: 10051 case CUT_CLEVO10242: 10052 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10053 gotitfrompci = true; 10054 dochiptest = false; 10055 delay = 0x33; 10056 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay); 10057 delay &= 0x0f; 10058 } 10059 break; 10060 } 10061 10062 /* Could we find it through the PCI ID? If no, use ROM or table */ 10063 10064 if(!gotitfrompci) { 10065 10066 index = GetLCDPtrIndexBIOS(SiS_Pr); 10067 myindex = GetLCDPtrIndex(SiS_Pr); 10068 10069 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10070 10071 if(SiS_IsNotM650orLater(SiS_Pr)) { 10072 10073 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10074 /* Always use the second pointer on 650; some BIOSes */ 10075 /* still carry old 301 data at the first location */ 10076 /* romptr = SISGETROMW(0x120); */ 10077 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */ 10078 romptr = SISGETROMW(0x122); 10079 if(!romptr) return; 10080 delay = ROMAddr[(romptr + index)]; 10081 } else { 10082 delay = SiS310_LCDDelayCompensation_650301LV[myindex]; 10083 } 10084 10085 } else { 10086 10087 delay = SiS310_LCDDelayCompensation_651301LV[myindex]; 10088 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) 10089 delay = SiS310_LCDDelayCompensation_651302LV[myindex]; 10090 10091 } 10092 10093 } else if(SiS_Pr->SiS_UseROM && 10094 (!(SiS_Pr->SiS_ROMNew)) && 10095 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) && 10096 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) && 10097 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) && 10098 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) && 10099 ((romptr = GetLCDromptr(SiS_Pr)))) { 10100 10101 /* Data for 1280x1024 wrong in 301B BIOS */ 10102 /* Data for 1600x1200 wrong in 301C BIOS */ 10103 delay = ROMAddr[(romptr + index)]; 10104 10105 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 10106 10107 if(IS_SIS740) delay = 0x03; 10108 else delay = 0x00; 10109 10110 } else { 10111 10112 delay = SiS310_LCDDelayCompensation_301[myindex]; 10113 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10114 if(IS_SIS740) delay = 0x01; 10115 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex]; 10116 else delay = SiS310_LCDDelayCompensation_650301LV[myindex]; 10117 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) { 10118 if(IS_SIS740) delay = 0x01; /* ? */ 10119 else delay = 0x03; 10120 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */ 10121 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 10122 if(IS_SIS740) delay = 0x01; 10123 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex]; 10124 } 10125 10126 } 10127 10128 } /* got it from PCI */ 10129 10130 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10131 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0)); 10132 dochiptest = false; 10133 } 10134 10135 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */ 10136 10137 index = GetTVPtrIndex(SiS_Pr); 10138 10139 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10140 10141 if(SiS_IsNotM650orLater(SiS_Pr)) { 10142 10143 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10144 /* Always use the second pointer on 650; some BIOSes */ 10145 /* still carry old 301 data at the first location */ 10146 /* romptr = SISGETROMW(0x114); */ 10147 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */ 10148 romptr = SISGETROMW(0x11a); 10149 if(!romptr) return; 10150 delay = ROMAddr[romptr + index]; 10151 10152 } else { 10153 10154 delay = SiS310_TVDelayCompensation_301B[index]; 10155 10156 } 10157 10158 } else { 10159 10160 switch(SiS_Pr->SiS_CustomT) { 10161 case CUT_COMPAQ1280: 10162 case CUT_COMPAQ12802: 10163 case CUT_CLEVO1400: 10164 case CUT_CLEVO14002: 10165 delay = 0x02; 10166 dochiptest = false; 10167 break; 10168 case CUT_CLEVO1024: 10169 case CUT_CLEVO10242: 10170 delay = 0x03; 10171 dochiptest = false; 10172 break; 10173 default: 10174 delay = SiS310_TVDelayCompensation_651301LV[index]; 10175 if(SiS_Pr->SiS_VBType & VB_SIS302LV) { 10176 delay = SiS310_TVDelayCompensation_651302LV[index]; 10177 } 10178 } 10179 } 10180 10181 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10182 10183 romptr = GetTVromptr(SiS_Pr); 10184 if(!romptr) return; 10185 delay = ROMAddr[romptr + index]; 10186 10187 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 10188 10189 delay = SiS310_TVDelayCompensation_LVDS[index]; 10190 10191 } else { 10192 10193 delay = SiS310_TVDelayCompensation_301[index]; 10194 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10195 if(IS_SIS740) { 10196 delay = SiS310_TVDelayCompensation_740301B[index]; 10197 /* LV: use 301 data? BIOS bug? */ 10198 } else { 10199 delay = SiS310_TVDelayCompensation_301B[index]; 10200 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02; 10201 } 10202 } 10203 10204 } 10205 10206 if(SiS_LCDAEnabled(SiS_Pr)) { 10207 delay &= 0x0f; 10208 dochiptest = false; 10209 } 10210 10211 } else return; 10212 10213 /* Write delay */ 10214 10215 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10216 10217 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) { 10218 10219 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4; 10220 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */ 10221 delay &= 0x0f; 10222 delay |= 0xb0; 10223 } else if(temp == 6) { 10224 delay &= 0x0f; 10225 delay |= 0xc0; 10226 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */ 10227 delay = 0x35; 10228 } 10229 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay); 10230 10231 } else { 10232 10233 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10234 10235 } 10236 10237 } else { /* LVDS */ 10238 10239 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10240 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10241 } else { 10242 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) { 10243 delay <<= 4; 10244 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay); 10245 } else { 10246 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10247 } 10248 } 10249 10250 } 10251 10252} 10253 10254static void 10255SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10256{ 10257 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10258 unsigned short index,temp,temp1,romptr=0; 10259 10260 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return; 10261 10262 if(ModeNo<=0x13) 10263 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; 10264 else 10265 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; 10266 10267 temp = GetTVPtrIndex(SiS_Pr); 10268 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10269 temp1 = temp; 10270 10271 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10272 if(SiS_Pr->ChipType >= SIS_661) { 10273 temp1 = GetOEMTVPtr661(SiS_Pr); 10274 temp1 >>= 1; 10275 romptr = SISGETROMW(0x260); 10276 if(SiS_Pr->ChipType >= SIS_760) { 10277 romptr = SISGETROMW(0x360); 10278 } 10279 } else if(SiS_Pr->ChipType >= SIS_330) { 10280 romptr = SISGETROMW(0x192); 10281 } else { 10282 romptr = SISGETROMW(0x112); 10283 } 10284 } 10285 10286 if(romptr) { 10287 temp1 <<= 1; 10288 temp = ROMAddr[romptr + temp1 + index]; 10289 } else { 10290 temp = SiS310_TVAntiFlick1[temp][index]; 10291 } 10292 temp <<= 4; 10293 10294 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */ 10295} 10296 10297static void 10298SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 10299{ 10300 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10301 unsigned short index,temp,temp1,romptr=0; 10302 10303 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10304 10305 if(ModeNo <= 0x13) 10306 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; 10307 else 10308 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; 10309 10310 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10311 if(SiS_Pr->ChipType >= SIS_661) { 10312 romptr = SISGETROMW(0x26c); 10313 if(SiS_Pr->ChipType >= SIS_760) { 10314 romptr = SISGETROMW(0x36c); 10315 } 10316 temp1 = GetOEMTVPtr661(SiS_Pr); 10317 temp1 >>= 1; 10318 } else if(SiS_Pr->ChipType >= SIS_330) { 10319 romptr = SISGETROMW(0x1a4); 10320 } else { 10321 romptr = SISGETROMW(0x124); 10322 } 10323 } 10324 10325 if(romptr) { 10326 temp1 <<= 1; 10327 temp = ROMAddr[romptr + temp1 + index]; 10328 } else { 10329 temp = SiS310_TVEdge1[temp][index]; 10330 } 10331 temp <<= 5; 10332 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */ 10333} 10334 10335static void 10336SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 10337{ 10338 unsigned short index, temp, i, j; 10339 10340 if(ModeNo <= 0x13) { 10341 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex; 10342 } else { 10343 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; 10344 } 10345 10346 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10347 10348 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */ 10349 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */ 10350 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */ 10351 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */ 10352 10353 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10354 for(i=0x35, j=0; i<=0x38; i++, j++) { 10355 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); 10356 } 10357 for(i=0x48; i<=0x4A; i++, j++) { 10358 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); 10359 } 10360 } else { 10361 for(i=0x35, j=0; i<=0x38; i++, j++) { 10362 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]); 10363 } 10364 } 10365} 10366 10367static void 10368SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10369{ 10370 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10371 unsigned short index,temp,i,j,resinfo,romptr=0; 10372 unsigned int lindex; 10373 10374 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 10375 10376 /* NTSC-J data not in BIOS, and already set in SetGroup2 */ 10377 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return; 10378 10379 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) { 10380 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff; 10381 lindex <<= 2; 10382 for(j=0, i=0x31; i<=0x34; i++, j++) { 10383 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]); 10384 } 10385 return; 10386 } 10387 10388 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */ 10389 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return; 10390 10391 if(ModeNo<=0x13) { 10392 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 10393 } else { 10394 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 10395 } 10396 10397 temp = GetTVPtrIndex(SiS_Pr); 10398 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics, 10399 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text 10400 */ 10401 if(SiS_Pr->SiS_UseROM) { 10402 romptr = SISGETROMW(0x116); 10403 if(SiS_Pr->ChipType >= SIS_330) { 10404 romptr = SISGETROMW(0x196); 10405 } 10406 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10407 romptr = SISGETROMW(0x11c); 10408 if(SiS_Pr->ChipType >= SIS_330) { 10409 romptr = SISGETROMW(0x19c); 10410 } 10411 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) { 10412 romptr = SISGETROMW(0x116); 10413 if(SiS_Pr->ChipType >= SIS_330) { 10414 romptr = SISGETROMW(0x196); 10415 } 10416 } 10417 } 10418 } 10419 if(romptr) { 10420 romptr += (temp << 2); 10421 for(j=0, i=0x31; i<=0x34; i++, j++) { 10422 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 10423 } 10424 } else { 10425 index = temp % 2; 10426 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */ 10427 for(j=0, i=0x31; i<=0x34; i++, j++) { 10428 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) 10429 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); 10430 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) 10431 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]); 10432 else 10433 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); 10434 } 10435 } 10436 10437 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) { 10438 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) { 10439 if((resinfo == SIS_RI_640x480) || 10440 (resinfo == SIS_RI_800x600)) { 10441 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21); 10442 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0); 10443 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5); 10444 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f); 10445 } else if(resinfo == SIS_RI_1024x768) { 10446 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e); 10447 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b); 10448 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb); 10449 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b); 10450 } 10451 } 10452 } 10453} 10454 10455static void 10456SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 10457 unsigned short ModeIdIndex, unsigned short RTI) 10458{ 10459 unsigned short delay = 0, romptr = 0, index, lcdpdcindex; 10460 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10461 10462 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC))) 10463 return; 10464 10465 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */ 10466 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */ 10467 10468 if(SiS_Pr->SiS_ROMNew) { 10469 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) || 10470 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && 10471 (SiS_Pr->SiS_LCDInfo & LCDPass11))) { 10472 index = 25; 10473 if(SiS_Pr->UseCustomMode) { 10474 index = SiS_Pr->CSRClock; 10475 } else if(ModeNo > 0x13) { 10476 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI); 10477 index = SiS_Pr->SiS_VCLKData[index].CLOCK; 10478 } 10479 if(index < 25) index = 25; 10480 index = ((index / 25) - 1) << 1; 10481 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) { 10482 index++; 10483 } 10484 romptr = SISGETROMW(0x104); 10485 delay = ROMAddr[romptr + index]; 10486 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) { 10487 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f)); 10488 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7)); 10489 } else { 10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0)); 10491 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6)); 10492 } 10493 return; 10494 } 10495 } 10496 10497 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */ 10498 10499 if(SiS_Pr->UseCustomMode) delay = 0x04; 10500 else if(ModeNo <= 0x13) delay = 0x04; 10501 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4); 10502 delay |= (delay << 8); 10503 10504 if(SiS_Pr->ChipType >= XGI_20) { 10505 10506 delay = 0x0606; 10507 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10508 10509 delay = 0x0404; 10510 if(SiS_Pr->SiS_XGIROM) { 10511 index = GetTVPtrIndex(SiS_Pr); 10512 if((romptr = SISGETROMW(0x35e))) { 10513 delay = (ROMAddr[romptr + index] & 0x0f) << 1; 10514 delay |= (delay << 8); 10515 } 10516 } 10517 10518 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 10519 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) { 10520 delay -= 0x0404; 10521 } 10522 } 10523 } 10524 10525 } else if(SiS_Pr->ChipType >= SIS_340) { 10526 10527 delay = 0x0606; 10528 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10529 delay = 0x0404; 10530 } 10531 /* TODO (eventually) */ 10532 10533 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10534 10535 /* 3. TV */ 10536 10537 index = GetOEMTVPtr661(SiS_Pr); 10538 if(SiS_Pr->SiS_ROMNew) { 10539 romptr = SISGETROMW(0x106); 10540 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12; 10541 delay = ROMAddr[romptr + index]; 10542 } else { 10543 delay = 0x04; 10544 if(index > 3) delay = 0; 10545 } 10546 10547 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10548 10549 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */ 10550 10551 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) && 10552 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) { 10553 10554 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12; 10555 10556 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */ 10557 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */ 10558 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */ 10559 10560 } else { 10561 10562 /* TMDS: Set our own, since BIOS has no idea */ 10563 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */ 10564 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 10565 switch(SiS_Pr->SiS_LCDResInfo) { 10566 case Panel_1024x768: delay = 0x0008; break; 10567 case Panel_1280x720: delay = 0x0004; break; 10568 case Panel_1280x768: 10569 case Panel_1280x768_2:delay = 0x0004; break; 10570 case Panel_1280x800: 10571 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */ 10572 case Panel_1280x854: delay = 0x0004; break; /* FIXME */ 10573 case Panel_1280x1024: delay = 0x1e04; break; 10574 case Panel_1400x1050: delay = 0x0004; break; 10575 case Panel_1600x1200: delay = 0x0400; break; 10576 case Panel_1680x1050: delay = 0x0e04; break; 10577 default: 10578 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) { 10579 delay = 0x0008; 10580 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) { 10581 delay = 0x1e04; 10582 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) { 10583 delay = 0x0004; 10584 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) { 10585 delay = 0x0400; 10586 } else 10587 delay = 0x0e04; 10588 break; 10589 } 10590 } 10591 10592 /* Override by detected or user-set values */ 10593 /* (but only if, for some reason, we can't read value from BIOS) */ 10594 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) { 10595 delay = SiS_Pr->PDC & 0x1f; 10596 } 10597 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) { 10598 delay = (SiS_Pr->PDCA & 0x1f) << 8; 10599 } 10600 10601 } 10602 10603 } 10604 10605 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10606 delay >>= 8; 10607 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0)); 10608 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6)); 10609 } else { 10610 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f)); 10611 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7)); 10612 } 10613} 10614 10615static void 10616SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI) 10617{ 10618 unsigned short infoflag; 10619 unsigned char temp; 10620 10621 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10622 10623 if(ModeNo <= 0x13) { 10624 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2); 10625 } else if(SiS_Pr->UseCustomMode) { 10626 infoflag = SiS_Pr->CInfoFlag; 10627 } else { 10628 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag; 10629 } 10630 10631 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 10632 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */ 10633 } 10634 10635 infoflag &= 0xc0; 10636 10637 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 10638 temp = (infoflag >> 6) | 0x0c; 10639 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 10640 temp ^= 0x04; 10641 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10; 10642 } 10643 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp); 10644 } else { 10645 temp = 0x30; 10646 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20; 10647 temp |= infoflag; 10648 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp); 10649 temp = 0; 10650 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 10651 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80; 10652 } 10653 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp); 10654 } 10655 10656 } 10657} 10658 10659static void 10660SetPanelParms661(struct SiS_Private *SiS_Pr) 10661{ 10662 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10663 unsigned short romptr, temp1, temp2; 10664 10665 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) { 10666 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f); 10667 } 10668 10669 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10670 if(SiS_Pr->LVDSHL != -1) { 10671 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL); 10672 } 10673 } 10674 10675 if(SiS_Pr->SiS_ROMNew) { 10676 10677 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) { 10678 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10679 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c; 10680 temp2 = 0xfc; 10681 if(SiS_Pr->LVDSHL != -1) { 10682 temp1 &= 0xfc; 10683 temp2 = 0xf3; 10684 } 10685 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1); 10686 } 10687 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 10688 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1; 10689 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1); 10690 } 10691 } 10692 10693 } 10694} 10695 10696static void 10697SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI) 10698{ 10699 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10700 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 10701 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10702 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI); 10703 SetPanelParms661(SiS_Pr); 10704 } 10705 } else { 10706 SetDelayComp(SiS_Pr,ModeNo); 10707 } 10708 10709 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 10710 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex); 10711 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex); 10712 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex); 10713 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10714 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex); 10715 } 10716 } 10717} 10718 10719static void 10720SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 10721 unsigned short ModeIdIndex, unsigned short RRTI) 10722{ 10723 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10724 10725 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 10726 10727 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10728 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI); 10729 SetPanelParms661(SiS_Pr); 10730 } 10731 10732 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10733 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex); 10734 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex); 10735 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex); 10736 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10737 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex); 10738 } 10739 } 10740 } 10741} 10742 10743/* FinalizeLCD 10744 * This finalizes some CRT2 registers for the very panel used. 10745 * If we have a backup if these registers, we use it; otherwise 10746 * we set the register according to most BIOSes. However, this 10747 * function looks quite different in every BIOS, so you better 10748 * pray that we have a backup... 10749 */ 10750static void 10751SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10752{ 10753 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp; 10754 unsigned short resinfo,modeflag; 10755 10756 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return; 10757 if(SiS_Pr->SiS_ROMNew) return; 10758 10759 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10760 if(SiS_Pr->LVDSHL != -1) { 10761 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL); 10762 } 10763 } 10764 10765 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return; 10766 if(SiS_Pr->UseCustomMode) return; 10767 10768 switch(SiS_Pr->SiS_CustomT) { 10769 case CUT_COMPAQ1280: 10770 case CUT_COMPAQ12802: 10771 case CUT_CLEVO1400: 10772 case CUT_CLEVO14002: 10773 return; 10774 } 10775 10776 if(ModeNo <= 0x13) { 10777 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 10778 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 10779 } else { 10780 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 10781 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 10782 } 10783 10784 if(IS_SIS650) { 10785 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) { 10786 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { 10787 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02); 10788 } else { 10789 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); 10790 } 10791 } 10792 } 10793 10794 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { 10795 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10796 /* Maybe all panels? */ 10797 if(SiS_Pr->LVDSHL == -1) { 10798 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10799 } 10800 return; 10801 } 10802 } 10803 10804 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) { 10805 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10806 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10807 if(SiS_Pr->LVDSHL == -1) { 10808 /* Maybe all panels? */ 10809 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10810 } 10811 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10812 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 10813 if(tempch == 3) { 10814 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10815 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25); 10816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00); 10817 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b); 10818 } 10819 } 10820 return; 10821 } 10822 } 10823 } 10824 10825 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10826 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10827 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 10828 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00); 10829#ifdef SET_EMI 10830 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 10831#endif 10832 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 10833 } 10834 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 10835 if(SiS_Pr->LVDSHL == -1) { 10836 /* Maybe ACER only? */ 10837 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10838 } 10839 } 10840 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 10841 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10842 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) { 10843 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76); 10844 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10845 if(tempch == 0x03) { 10846 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10847 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25); 10848 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00); 10849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b); 10850 } 10851 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) { 10852 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14); 10853 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15); 10854 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16); 10855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17); 10856 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18); 10857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19); 10858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a); 10859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b); 10860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c); 10861 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d); 10862 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */ 10863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90); 10864 if(ModeNo <= 0x13) { 10865 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11); 10866 if((resinfo == 0) || (resinfo == 2)) return; 10867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18); 10868 if((resinfo == 1) || (resinfo == 3)) return; 10869 } 10870 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10871 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) { 10872 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */ 10873#if 0 10874 tempbx = 806; /* 0x326 */ /* other older BIOSes */ 10875 tempbx--; 10876 temp = tempbx & 0xff; 10877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); 10878 temp = (tempbx >> 8) & 0x03; 10879 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp); 10880#endif 10881 } 10882 } else if(ModeNo <= 0x13) { 10883 if(ModeNo <= 1) { 10884 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70); 10885 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff); 10886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48); 10887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12); 10888 } 10889 if(!(modeflag & HalfDCLK)) { 10890 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20); 10891 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a); 10892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28); 10893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00); 10894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c); 10895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc); 10896 if(ModeNo == 0x12) { 10897 switch(tempch) { 10898 case 0: 10899 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95); 10900 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc); 10901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10); 10902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95); 10903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48); 10904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12); 10905 break; 10906 case 2: 10907 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95); 10908 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48); 10909 break; 10910 case 3: 10911 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95); 10912 break; 10913 } 10914 } 10915 } 10916 } 10917 } 10918 } else { 10919 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01); 10920 tempcl &= 0x0f; 10921 tempbh &= 0x70; 10922 tempbh >>= 4; 10923 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04); 10924 tempbx = (tempbh << 8) | tempbl; 10925 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10926 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) { 10927 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 10928 tempbx = 770; 10929 } else { 10930 if(tempbx > 770) tempbx = 770; 10931 if(SiS_Pr->SiS_VGAVDE < 600) { 10932 tempax = 768 - SiS_Pr->SiS_VGAVDE; 10933 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */ 10934 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */ 10935 tempbx -= tempax; 10936 } 10937 } 10938 } else return; 10939 } 10940 temp = tempbx & 0xff; 10941 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp); 10942 temp = ((tempbx & 0xff00) >> 4) | tempcl; 10943 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp); 10944 } 10945 } 10946} 10947 10948#endif 10949 10950/* ================= SiS 300 O.E.M. ================== */ 10951 10952#ifdef CONFIG_FB_SIS_300 10953 10954static void 10955SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, 10956 unsigned short RefTabIndex) 10957{ 10958 unsigned short crt2crtc=0, modeflag, myindex=0; 10959 unsigned char temp; 10960 int i; 10961 10962 if(ModeNo <= 0x13) { 10963 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 10964 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 10965 } else { 10966 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 10967 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC; 10968 } 10969 10970 crt2crtc &= 0x3f; 10971 10972 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 10973 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf); 10974 } 10975 10976 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 10977 if(modeflag & HalfDCLK) myindex = 1; 10978 10979 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 10980 for(i=0; i<7; i++) { 10981 if(barco_p1[myindex][crt2crtc][i][0]) { 10982 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 10983 barco_p1[myindex][crt2crtc][i][0], 10984 barco_p1[myindex][crt2crtc][i][2], 10985 barco_p1[myindex][crt2crtc][i][1]); 10986 } 10987 } 10988 } 10989 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 10990 if(temp & 0x80) { 10991 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18); 10992 temp++; 10993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); 10994 } 10995 } 10996} 10997 10998static unsigned short 10999GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag) 11000{ 11001 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11002 unsigned short tempbx=0,romptr=0; 11003 static const unsigned char customtable300[] = { 11004 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 11005 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 11006 }; 11007 static const unsigned char customtable630[] = { 11008 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 11009 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 11010 }; 11011 11012 if(SiS_Pr->ChipType == SIS_300) { 11013 11014 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f; 11015 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07; 11016 tempbx -= 2; 11017 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4; 11018 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 11019 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3; 11020 } 11021 if(SiS_Pr->SiS_UseROM) { 11022 if(ROMAddr[0x235] & 0x80) { 11023 tempbx = SiS_Pr->SiS_LCDTypeInfo; 11024 if(Flag) { 11025 romptr = SISGETROMW(0x255); 11026 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; 11027 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo]; 11028 if(tempbx == 0xFF) return 0xFFFF; 11029 } 11030 tempbx <<= 1; 11031 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; 11032 } 11033 } 11034 11035 } else { 11036 11037 if(Flag) { 11038 if(SiS_Pr->SiS_UseROM) { 11039 romptr = SISGETROMW(0x255); 11040 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; 11041 else tempbx = 0xff; 11042 } else { 11043 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo]; 11044 } 11045 if(tempbx == 0xFF) return 0xFFFF; 11046 tempbx <<= 2; 11047 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; 11048 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 11049 return tempbx; 11050 } 11051 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2; 11052 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; 11053 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 11054 11055 } 11056 11057 return tempbx; 11058} 11059 11060static void 11061SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 11062{ 11063 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11064 unsigned short index,temp,romptr=0; 11065 11066 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return; 11067 11068 if(SiS_Pr->SiS_UseROM) { 11069 if(!(ROMAddr[0x237] & 0x01)) return; 11070 if(!(ROMAddr[0x237] & 0x02)) return; 11071 romptr = SISGETROMW(0x24b); 11072 } 11073 11074 /* The Panel Compensation Delay should be set according to tables 11075 * here. Unfortunately, various BIOS versions don't care about 11076 * a uniform way using eg. ROM byte 0x220, but use different 11077 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). 11078 * Thus we don't set this if the user selected a custom pdc or if 11079 * we otherwise detected a valid pdc. 11080 */ 11081 if(SiS_Pr->PDC != -1) return; 11082 11083 temp = GetOEMLCDPtr(SiS_Pr, 0); 11084 11085 if(SiS_Pr->UseCustomMode) 11086 index = 0; 11087 else 11088 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex; 11089 11090 if(SiS_Pr->ChipType != SIS_300) { 11091 if(romptr) { 11092 romptr += (temp * 2); 11093 romptr = SISGETROMW(romptr); 11094 romptr += index; 11095 temp = ROMAddr[romptr]; 11096 } else { 11097 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11098 temp = SiS300_OEMLCDDelay2[temp][index]; 11099 } else { 11100 temp = SiS300_OEMLCDDelay3[temp][index]; 11101 } 11102 } 11103 } else { 11104 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) { 11105 if(romptr) { 11106 romptr += (temp * 2); 11107 romptr = SISGETROMW(romptr); 11108 romptr += index; 11109 temp = ROMAddr[romptr]; 11110 } else { 11111 temp = SiS300_OEMLCDDelay5[temp][index]; 11112 } 11113 } else { 11114 if(SiS_Pr->SiS_UseROM) { 11115 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8); 11116 if(romptr) { 11117 romptr += (temp * 2); 11118 romptr = SISGETROMW(romptr); 11119 romptr += index; 11120 temp = ROMAddr[romptr]; 11121 } else { 11122 temp = SiS300_OEMLCDDelay4[temp][index]; 11123 } 11124 } else { 11125 temp = SiS300_OEMLCDDelay4[temp][index]; 11126 } 11127 } 11128 } 11129 temp &= 0x3c; 11130 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */ 11131} 11132 11133static void 11134SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11135{ 11136#if 0 /* Unfinished; Data table missing */ 11137 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11138 unsigned short index,temp; 11139 11140 if((SiS_Pr->SiS_UseROM) { 11141 if(!(ROMAddr[0x237] & 0x01)) return; 11142 if(!(ROMAddr[0x237] & 0x04)) return; 11143 /* No rom pointer in BIOS header! */ 11144 } 11145 11146 temp = GetOEMLCDPtr(SiS_Pr, 1); 11147 if(temp == 0xFFFF) return; 11148 11149 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex; 11150 for(i=0x14, j=0; i<=0x17; i++, j++) { 11151 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]); 11152 } 11153 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07)); 11154 11155 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex; 11156 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]); 11157 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]); 11158 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38)); 11159 for(i=0x1b, j=3; i<=0x1d; i++, j++) { 11160 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]); 11161 } 11162#endif 11163} 11164 11165static unsigned short 11166GetOEMTVPtr(struct SiS_Private *SiS_Pr) 11167{ 11168 unsigned short index; 11169 11170 index = 0; 11171 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4; 11172 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11173 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2; 11174 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3; 11175 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1; 11176 } else { 11177 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2; 11178 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1; 11179 } 11180 return index; 11181} 11182 11183static void 11184SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11185{ 11186 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11187 unsigned short index,temp,romptr=0; 11188 11189 if(SiS_Pr->SiS_UseROM) { 11190 if(!(ROMAddr[0x238] & 0x01)) return; 11191 if(!(ROMAddr[0x238] & 0x02)) return; 11192 romptr = SISGETROMW(0x241); 11193 } 11194 11195 temp = GetOEMTVPtr(SiS_Pr); 11196 11197 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex; 11198 11199 if(romptr) { 11200 romptr += (temp * 2); 11201 romptr = SISGETROMW(romptr); 11202 romptr += index; 11203 temp = ROMAddr[romptr]; 11204 } else { 11205 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11206 temp = SiS300_OEMTVDelay301[temp][index]; 11207 } else { 11208 temp = SiS300_OEMTVDelayLVDS[temp][index]; 11209 } 11210 } 11211 temp &= 0x3c; 11212 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); 11213} 11214 11215static void 11216SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11217{ 11218 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11219 unsigned short index,temp,romptr=0; 11220 11221 if(SiS_Pr->SiS_UseROM) { 11222 if(!(ROMAddr[0x238] & 0x01)) return; 11223 if(!(ROMAddr[0x238] & 0x04)) return; 11224 romptr = SISGETROMW(0x243); 11225 } 11226 11227 temp = GetOEMTVPtr(SiS_Pr); 11228 11229 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex; 11230 11231 if(romptr) { 11232 romptr += (temp * 2); 11233 romptr = SISGETROMW(romptr); 11234 romptr += index; 11235 temp = ROMAddr[romptr]; 11236 } else { 11237 temp = SiS300_OEMTVFlicker[temp][index]; 11238 } 11239 temp &= 0x70; 11240 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp); 11241} 11242 11243static void 11244SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 11245{ 11246 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11247 unsigned short index,i,j,temp,romptr=0; 11248 11249 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return; 11250 11251 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return; 11252 11253 if(SiS_Pr->SiS_UseROM) { 11254 if(!(ROMAddr[0x238] & 0x01)) return; 11255 if(!(ROMAddr[0x238] & 0x08)) return; 11256 romptr = SISGETROMW(0x245); 11257 } 11258 11259 temp = GetOEMTVPtr(SiS_Pr); 11260 11261 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex; 11262 11263 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 11264 for(i=0x31, j=0; i<=0x34; i++, j++) { 11265 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]); 11266 } 11267 } else { 11268 if(romptr) { 11269 romptr += (temp * 2); 11270 romptr = SISGETROMW(romptr); 11271 romptr += (index * 4); 11272 for(i=0x31, j=0; i<=0x34; i++, j++) { 11273 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 11274 } 11275 } else { 11276 for(i=0x31, j=0; i<=0x34; i++, j++) { 11277 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]); 11278 } 11279 } 11280 } 11281} 11282 11283static void 11284SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11285{ 11286 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11287 unsigned short index,temp,i,j,romptr=0; 11288 11289 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return; 11290 11291 if(SiS_Pr->SiS_UseROM) { 11292 if(!(ROMAddr[0x238] & 0x01)) return; 11293 if(!(ROMAddr[0x238] & 0x10)) return; 11294 romptr = SISGETROMW(0x247); 11295 } 11296 11297 temp = GetOEMTVPtr(SiS_Pr); 11298 11299 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8; 11300 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9; 11301 /* NTSCJ uses NTSC filters */ 11302 11303 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex; 11304 11305 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 11306 for(i=0x35, j=0; i<=0x38; i++, j++) { 11307 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); 11308 } 11309 for(i=0x48; i<=0x4A; i++, j++) { 11310 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); 11311 } 11312 } else { 11313 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) { 11314 romptr += (temp * 2); 11315 romptr = SISGETROMW(romptr); 11316 romptr += (index * 4); 11317 for(i=0x35, j=0; i<=0x38; i++, j++) { 11318 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 11319 } 11320 } else { 11321 for(i=0x35, j=0; i<=0x38; i++, j++) { 11322 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]); 11323 } 11324 } 11325 } 11326} 11327 11328static unsigned short 11329SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo) 11330{ 11331 unsigned short ModeIdIndex; 11332 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO; 11333 11334 if(*ModeNo <= 5) *ModeNo |= 1; 11335 11336 for(ModeIdIndex=0; ; ModeIdIndex++) { 11337 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break; 11338 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0; 11339 } 11340 11341 if(*ModeNo != 0x07) { 11342 if(*ModeNo > 0x03) return ModeIdIndex; 11343 if(VGAINFO & 0x80) return ModeIdIndex; 11344 ModeIdIndex++; 11345 } 11346 11347 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */ 11348 /* else 350 lines */ 11349 return ModeIdIndex; 11350} 11351 11352static void 11353SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 11354 unsigned short RefTableIndex) 11355{ 11356 unsigned short OEMModeIdIndex = 0; 11357 11358 if(!SiS_Pr->UseCustomMode) { 11359 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo); 11360 if(!(OEMModeIdIndex)) return; 11361 } 11362 11363 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 11364 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex); 11365 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 11366 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex); 11367 } 11368 } 11369 if(SiS_Pr->UseCustomMode) return; 11370 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 11371 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex); 11372 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11373 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex); 11374 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex); 11375 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex); 11376 } 11377 } 11378} 11379#endif 11380