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 85 static 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 130 static 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 152 static 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 163 static 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 176 static 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 184 static 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 192 static 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 211 static 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 230 static 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 239 static 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) */ 250 static 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 291 static 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 367 static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr); 368 static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr); 369 static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr); 370 static void SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr); 371 #endif /* 315 */ 372 373 #ifdef CONFIG_FB_SIS_300 374 static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr); 375 #endif 376 377 static 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); 380 static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr); 381 static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, 382 unsigned char *buffer); 383 static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr); 384 static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr); 385 static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr); 386 static unsigned short SiS_SetSCLKLow(struct SiS_Private *SiS_Pr); 387 static unsigned short SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr); 388 static unsigned short SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr); 389 static unsigned short SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax); 390 static unsigned short SiS_CheckACK(struct SiS_Private *SiS_Pr); 391 static unsigned short SiS_WriteDABDDC(struct SiS_Private *SiS_Pr); 392 static unsigned short SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr); 393 static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr); 394 static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno); 395 static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr); 396 397 #ifdef CONFIG_FB_SIS_300 398 static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr, 399 unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex); 400 static 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 404 static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr, 405 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI); 406 static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr, 407 unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI); 408 static void SiS_FinalizeLCD(struct SiS_Private *, unsigned short, unsigned short); 409 #endif 410 411 static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr); 412 static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val); 413 414 /*********************************************/ 415 /* HELPER: Lock/Unlock CRT2 */ 416 /*********************************************/ 417 418 void 419 SiS_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 429 static 430 void 431 SiS_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 445 static void 446 SiS_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 460 static unsigned char * 461 GetLCDStructPtr661(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 494 static unsigned short 495 GetLCDStructPtr661_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 521 static bool 522 SiS_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 609 unsigned short 610 SiS_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 709 static void 710 SiS_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 726 static bool 727 SiS_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 742 static bool 743 SiS_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 763 void 764 SiS_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) 771 static void 772 SiS_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 779 static void 780 SiS_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) 789 static void 790 SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay) 791 { 792 while(delay--) { 793 SiS_GenericDelay(SiS_Pr, 66); 794 } 795 } 796 #endif 797 798 static void 799 SiS_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) /* || 852 (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || 853 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */ 854 855 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 856 PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 857 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) { 858 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1b) & 0x10)) PanelID = 0x12; 859 } 860 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 861 DelayIndex = PanelID & 0x0f; 862 } else { 863 DelayIndex = PanelID >> 4; 864 } 865 if((DelayTime >= 2) && ((PanelID & 0x0f) == 1)) { 866 Delay = 3; 867 } else { 868 if(DelayTime >= 2) DelayTime -= 2; 869 if(!(DelayTime & 0x01)) { 870 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0]; 871 } else { 872 Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1]; 873 } 874 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 875 if(ROMAddr[0x13c] & 0x40) { 876 if(!(DelayTime & 0x01)) { 877 Delay = (unsigned short)ROMAddr[0x17e]; 878 } else { 879 Delay = (unsigned short)ROMAddr[0x17f]; 880 } 881 } 882 } 883 } 884 SiS_ShortDelay(SiS_Pr, Delay); 885 } 886 887 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */ 888 889 DelayIndex = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 890 if(!(DelayTime & 0x01)) { 891 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0]; 892 } else { 893 Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1]; 894 } 895 Delay <<= 8; 896 SiS_DDC2Delay(SiS_Pr, Delay); 897 898 } 899 900 #endif /* CONFIG_FB_SIS_315 */ 901 902 } 903 } 904 905 #ifdef CONFIG_FB_SIS_315 906 static void 907 SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop) 908 { 909 int i; 910 for(i = 0; i < DelayLoop; i++) { 911 SiS_PanelDelay(SiS_Pr, DelayTime); 912 } 913 } 914 #endif 915 916 /*********************************************/ 917 /* HELPER: WAIT-FOR-RETRACE FUNCTIONS */ 918 /*********************************************/ 919 920 void 921 SiS_WaitRetrace1(struct SiS_Private *SiS_Pr) 922 { 923 unsigned short watchdog; 924 925 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return; 926 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return; 927 928 watchdog = 65535; 929 while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog); 930 watchdog = 65535; 931 while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog); 932 } 933 934 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 935 static void 936 SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg) 937 { 938 unsigned short watchdog; 939 940 watchdog = 65535; 941 while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog); 942 watchdog = 65535; 943 while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog); 944 } 945 #endif 946 947 static void 948 SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr) 949 { 950 if(SiS_Pr->ChipType < SIS_315H) { 951 #ifdef CONFIG_FB_SIS_300 952 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 953 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return; 954 } 955 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) { 956 SiS_WaitRetrace1(SiS_Pr); 957 } else { 958 SiS_WaitRetrace2(SiS_Pr, 0x25); 959 } 960 #endif 961 } else { 962 #ifdef CONFIG_FB_SIS_315 963 if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) { 964 SiS_WaitRetrace1(SiS_Pr); 965 } else { 966 SiS_WaitRetrace2(SiS_Pr, 0x30); 967 } 968 #endif 969 } 970 } 971 972 static void 973 SiS_VBWait(struct SiS_Private *SiS_Pr) 974 { 975 unsigned short tempal,temp,i,j; 976 977 temp = 0; 978 for(i = 0; i < 3; i++) { 979 for(j = 0; j < 100; j++) { 980 tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da); 981 if(temp & 0x01) { 982 if((tempal & 0x08)) continue; 983 else break; 984 } else { 985 if(!(tempal & 0x08)) continue; 986 else break; 987 } 988 } 989 temp ^= 0x01; 990 } 991 } 992 993 static void 994 SiS_VBLongWait(struct SiS_Private *SiS_Pr) 995 { 996 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 997 SiS_VBWait(SiS_Pr); 998 } else { 999 SiS_WaitRetrace1(SiS_Pr); 1000 } 1001 } 1002 1003 /*********************************************/ 1004 /* HELPER: MISC */ 1005 /*********************************************/ 1006 1007 #ifdef CONFIG_FB_SIS_300 1008 static bool 1009 SiS_Is301B(struct SiS_Private *SiS_Pr) 1010 { 1011 if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true; 1012 return false; 1013 } 1014 #endif 1015 1016 static bool 1017 SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr) 1018 { 1019 if(SiS_Pr->ChipType == SIS_730) { 1020 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true; 1021 } 1022 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true; 1023 return false; 1024 } 1025 1026 bool 1027 SiS_IsDualEdge(struct SiS_Private *SiS_Pr) 1028 { 1029 #ifdef CONFIG_FB_SIS_315 1030 if(SiS_Pr->ChipType >= SIS_315H) { 1031 if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) { 1032 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true; 1033 } 1034 } 1035 #endif 1036 return false; 1037 } 1038 1039 bool 1040 SiS_IsVAMode(struct SiS_Private *SiS_Pr) 1041 { 1042 #ifdef CONFIG_FB_SIS_315 1043 unsigned short flag; 1044 1045 if(SiS_Pr->ChipType >= SIS_315H) { 1046 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1047 if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true; 1048 } 1049 #endif 1050 return false; 1051 } 1052 1053 #ifdef CONFIG_FB_SIS_315 1054 static bool 1055 SiS_IsVAorLCD(struct SiS_Private *SiS_Pr) 1056 { 1057 if(SiS_IsVAMode(SiS_Pr)) return true; 1058 if(SiS_CRT2IsLCD(SiS_Pr)) return true; 1059 return false; 1060 } 1061 #endif 1062 1063 static bool 1064 SiS_IsDualLink(struct SiS_Private *SiS_Pr) 1065 { 1066 #ifdef CONFIG_FB_SIS_315 1067 if(SiS_Pr->ChipType >= SIS_315H) { 1068 if((SiS_CRT2IsLCD(SiS_Pr)) || 1069 (SiS_IsVAMode(SiS_Pr))) { 1070 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true; 1071 } 1072 } 1073 #endif 1074 return false; 1075 } 1076 1077 #ifdef CONFIG_FB_SIS_315 1078 static bool 1079 SiS_TVEnabled(struct SiS_Private *SiS_Pr) 1080 { 1081 if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true; 1082 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1083 if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true; 1084 } 1085 return false; 1086 } 1087 #endif 1088 1089 #ifdef CONFIG_FB_SIS_315 1090 static bool 1091 SiS_LCDAEnabled(struct SiS_Private *SiS_Pr) 1092 { 1093 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true; 1094 return false; 1095 } 1096 #endif 1097 1098 #ifdef CONFIG_FB_SIS_315 1099 static bool 1100 SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr) 1101 { 1102 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) { 1103 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true; 1104 } 1105 return false; 1106 } 1107 #endif 1108 1109 #ifdef CONFIG_FB_SIS_315 1110 static bool 1111 SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr) 1112 { 1113 unsigned short flag; 1114 1115 if(SiS_Pr->ChipType == SIS_650) { 1116 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0; 1117 /* Check for revision != A0 only */ 1118 if((flag == 0xe0) || (flag == 0xc0) || 1119 (flag == 0xb0) || (flag == 0x90)) return false; 1120 } else if(SiS_Pr->ChipType >= SIS_661) return false; 1121 return true; 1122 } 1123 #endif 1124 1125 #ifdef CONFIG_FB_SIS_315 1126 static bool 1127 SiS_IsYPbPr(struct SiS_Private *SiS_Pr) 1128 { 1129 if(SiS_Pr->ChipType >= SIS_315H) { 1130 /* YPrPb = 0x08 */ 1131 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true; 1132 } 1133 return false; 1134 } 1135 #endif 1136 1137 #ifdef CONFIG_FB_SIS_315 1138 static bool 1139 SiS_IsChScart(struct SiS_Private *SiS_Pr) 1140 { 1141 if(SiS_Pr->ChipType >= SIS_315H) { 1142 /* Scart = 0x04 */ 1143 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true; 1144 } 1145 return false; 1146 } 1147 #endif 1148 1149 #ifdef CONFIG_FB_SIS_315 1150 static bool 1151 SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr) 1152 { 1153 unsigned short flag; 1154 1155 if(SiS_Pr->ChipType >= SIS_315H) { 1156 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1157 if(flag & SetCRT2ToTV) return true; 1158 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1159 if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */ 1160 if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */ 1161 } else { 1162 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1163 if(flag & SetCRT2ToTV) return true; 1164 } 1165 return false; 1166 } 1167 #endif 1168 1169 #ifdef CONFIG_FB_SIS_315 1170 static bool 1171 SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr) 1172 { 1173 unsigned short flag; 1174 1175 if(SiS_Pr->ChipType >= SIS_315H) { 1176 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1177 if(flag & SetCRT2ToLCD) return true; 1178 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1179 if(flag & SetToLCDA) return true; 1180 } else { 1181 flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1182 if(flag & SetCRT2ToLCD) return true; 1183 } 1184 return false; 1185 } 1186 #endif 1187 1188 static bool 1189 SiS_HaveBridge(struct SiS_Private *SiS_Pr) 1190 { 1191 unsigned short flag; 1192 1193 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1194 return true; 1195 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 1196 flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); 1197 if((flag == 1) || (flag == 2)) return true; 1198 } 1199 return false; 1200 } 1201 1202 static bool 1203 SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr) 1204 { 1205 unsigned short flag; 1206 1207 if(SiS_HaveBridge(SiS_Pr)) { 1208 flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 1209 if(SiS_Pr->ChipType < SIS_315H) { 1210 flag &= 0xa0; 1211 if((flag == 0x80) || (flag == 0x20)) return true; 1212 } else { 1213 flag &= 0x50; 1214 if((flag == 0x40) || (flag == 0x10)) return true; 1215 } 1216 } 1217 return false; 1218 } 1219 1220 static bool 1221 SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr) 1222 { 1223 unsigned short flag1; 1224 1225 flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31); 1226 if(flag1 & (SetInSlaveMode >> 8)) return true; 1227 return false; 1228 } 1229 1230 /*********************************************/ 1231 /* GET VIDEO BRIDGE CONFIG INFO */ 1232 /*********************************************/ 1233 1234 /* Setup general purpose IO for Chrontel communication */ 1235 #ifdef CONFIG_FB_SIS_300 1236 void 1237 SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo) 1238 { 1239 unsigned int acpibase; 1240 unsigned short temp; 1241 1242 if(!(SiS_Pr->SiS_ChSW)) return; 1243 1244 acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74); 1245 acpibase &= 0xFFFF; 1246 if(!acpibase) return; 1247 temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */ 1248 temp &= 0xFEFF; 1249 SiS_SetRegShort((acpibase + 0x3c), temp); 1250 temp = SiS_GetRegShort((acpibase + 0x3c)); 1251 temp = SiS_GetRegShort((acpibase + 0x3a)); /* ACPI register 0x3a: GP Pin Level (low/high) */ 1252 temp &= 0xFEFF; 1253 if(!(myvbinfo & SetCRT2ToTV)) temp |= 0x0100; 1254 SiS_SetRegShort((acpibase + 0x3a), temp); 1255 temp = SiS_GetRegShort((acpibase + 0x3a)); 1256 } 1257 #endif 1258 1259 void 1260 SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 1261 unsigned short ModeIdIndex, int checkcrt2mode) 1262 { 1263 unsigned short tempax, tempbx, temp; 1264 unsigned short modeflag, resinfo = 0; 1265 1266 SiS_Pr->SiS_SetFlag = 0; 1267 1268 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 1269 1270 SiS_Pr->SiS_ModeType = modeflag & ModeTypeMask; 1271 1272 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) { 1273 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1274 } 1275 1276 tempbx = 0; 1277 1278 if(SiS_HaveBridge(SiS_Pr)) { 1279 1280 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 1281 tempbx |= temp; 1282 tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8; 1283 tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV); 1284 tempbx |= tempax; 1285 1286 #ifdef CONFIG_FB_SIS_315 1287 if(SiS_Pr->ChipType >= SIS_315H) { 1288 if(SiS_Pr->SiS_VBType & VB_SISLCDA) { 1289 if(ModeNo == 0x03) { 1290 /* Mode 0x03 is never in driver mode */ 1291 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf); 1292 } 1293 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) { 1294 /* Reset LCDA setting if not driver mode */ 1295 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc); 1296 } 1297 if(IS_SIS650) { 1298 if(SiS_Pr->SiS_UseLCDA) { 1299 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) { 1300 if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) { 1301 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA)); 1302 } 1303 } 1304 } 1305 } 1306 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1307 if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) { 1308 tempbx |= SetCRT2ToLCDA; 1309 } 1310 } 1311 1312 if(SiS_Pr->ChipType >= SIS_661) { /* New CR layout */ 1313 tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision); 1314 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & 0x04) { 1315 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35) & 0xe0; 1316 if(temp == 0x60) tempbx |= SetCRT2ToHiVision; 1317 else if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1318 tempbx |= SetCRT2ToYPbPr525750; 1319 } 1320 } 1321 } 1322 1323 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1324 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1325 if(temp & SetToLCDA) { 1326 tempbx |= SetCRT2ToLCDA; 1327 } 1328 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1329 if(temp & EnableCHYPbPr) { 1330 tempbx |= SetCRT2ToCHYPbPr; 1331 } 1332 } 1333 } 1334 } 1335 1336 #endif /* CONFIG_FB_SIS_315 */ 1337 1338 if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) { 1339 tempbx &= ~(SetCRT2ToRAMDAC); 1340 } 1341 1342 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1343 temp = SetCRT2ToSVIDEO | 1344 SetCRT2ToAVIDEO | 1345 SetCRT2ToSCART | 1346 SetCRT2ToLCDA | 1347 SetCRT2ToLCD | 1348 SetCRT2ToRAMDAC | 1349 SetCRT2ToHiVision | 1350 SetCRT2ToYPbPr525750; 1351 } else { 1352 if(SiS_Pr->ChipType >= SIS_315H) { 1353 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1354 temp = SetCRT2ToAVIDEO | 1355 SetCRT2ToSVIDEO | 1356 SetCRT2ToSCART | 1357 SetCRT2ToLCDA | 1358 SetCRT2ToLCD | 1359 SetCRT2ToCHYPbPr; 1360 } else { 1361 temp = SetCRT2ToLCDA | 1362 SetCRT2ToLCD; 1363 } 1364 } else { 1365 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1366 temp = SetCRT2ToTV | SetCRT2ToLCD; 1367 } else { 1368 temp = SetCRT2ToLCD; 1369 } 1370 } 1371 } 1372 1373 if(!(tempbx & temp)) { 1374 tempax = DisableCRT2Display; 1375 tempbx = 0; 1376 } 1377 1378 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1379 1380 unsigned short clearmask = ( DriverMode | 1381 DisableCRT2Display | 1382 LoadDACFlag | 1383 SetNotSimuMode | 1384 SetInSlaveMode | 1385 SetPALTV | 1386 SwitchCRT2 | 1387 SetSimuScanMode ); 1388 1389 if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA); 1390 if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC); 1391 if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD); 1392 if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART); 1393 if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision); 1394 if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750); 1395 1396 } else { 1397 1398 if(SiS_Pr->ChipType >= SIS_315H) { 1399 if(tempbx & SetCRT2ToLCDA) { 1400 tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode); 1401 } 1402 } 1403 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1404 if(tempbx & SetCRT2ToTV) { 1405 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode); 1406 } 1407 } 1408 if(tempbx & SetCRT2ToLCD) { 1409 tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode); 1410 } 1411 if(SiS_Pr->ChipType >= SIS_315H) { 1412 if(tempbx & SetCRT2ToLCDA) { 1413 tempbx |= SetCRT2ToLCD; 1414 } 1415 } 1416 1417 } 1418 1419 if(tempax & DisableCRT2Display) { 1420 if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) { 1421 tempbx = SetSimuScanMode | DisableCRT2Display; 1422 } 1423 } 1424 1425 if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode; 1426 1427 /* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */ 1428 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 1429 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 1430 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) { 1431 modeflag &= (~CRT2Mode); 1432 } 1433 } 1434 1435 if(!(tempbx & SetSimuScanMode)) { 1436 if(tempbx & SwitchCRT2) { 1437 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { 1438 if(resinfo != SIS_RI_1600x1200) { 1439 tempbx |= SetSimuScanMode; 1440 } 1441 } 1442 } else { 1443 if(SiS_BridgeIsEnabled(SiS_Pr)) { 1444 if(!(tempbx & DriverMode)) { 1445 if(SiS_BridgeInSlavemode(SiS_Pr)) { 1446 tempbx |= SetSimuScanMode; 1447 } 1448 } 1449 } 1450 } 1451 } 1452 1453 if(!(tempbx & DisableCRT2Display)) { 1454 if(tempbx & DriverMode) { 1455 if(tempbx & SetSimuScanMode) { 1456 if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) { 1457 if(resinfo != SIS_RI_1600x1200) { 1458 tempbx |= SetInSlaveMode; 1459 } 1460 } 1461 } 1462 } else { 1463 tempbx |= SetInSlaveMode; 1464 } 1465 } 1466 1467 } 1468 1469 SiS_Pr->SiS_VBInfo = tempbx; 1470 1471 #ifdef CONFIG_FB_SIS_300 1472 if(SiS_Pr->ChipType == SIS_630) { 1473 SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo); 1474 } 1475 #endif 1476 1477 #if 0 1478 printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n", 1479 SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag); 1480 #endif 1481 } 1482 1483 /*********************************************/ 1484 /* DETERMINE YPbPr MODE */ 1485 /*********************************************/ 1486 1487 void 1488 SiS_SetYPbPr(struct SiS_Private *SiS_Pr) 1489 { 1490 1491 unsigned char temp; 1492 1493 /* Note: This variable is only used on 30xLV systems. 1494 * CR38 has a different meaning on LVDS/CH7019 systems. 1495 * On 661 and later, these bits moved to CR35. 1496 * 1497 * On 301, 301B, only HiVision 1080i is supported. 1498 * On 30xLV, 301C, only YPbPr 1080i is supported. 1499 */ 1500 1501 SiS_Pr->SiS_YPbPr = 0; 1502 if(SiS_Pr->ChipType >= SIS_661) return; 1503 1504 if(SiS_Pr->SiS_VBType) { 1505 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1506 SiS_Pr->SiS_YPbPr = YPbPrHiVision; 1507 } 1508 } 1509 1510 if(SiS_Pr->ChipType >= SIS_315H) { 1511 if(SiS_Pr->SiS_VBType & VB_SISYPBPR) { 1512 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1513 if(temp & 0x08) { 1514 switch((temp >> 4)) { 1515 case 0x00: SiS_Pr->SiS_YPbPr = YPbPr525i; break; 1516 case 0x01: SiS_Pr->SiS_YPbPr = YPbPr525p; break; 1517 case 0x02: SiS_Pr->SiS_YPbPr = YPbPr750p; break; 1518 case 0x03: SiS_Pr->SiS_YPbPr = YPbPrHiVision; break; 1519 } 1520 } 1521 } 1522 } 1523 1524 } 1525 1526 /*********************************************/ 1527 /* DETERMINE TVMode flag */ 1528 /*********************************************/ 1529 1530 void 1531 SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 1532 { 1533 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 1534 unsigned short temp, temp1, resinfo = 0, romindex = 0; 1535 unsigned char OutputSelect = *SiS_Pr->pSiS_OutputSelect; 1536 1537 SiS_Pr->SiS_TVMode = 0; 1538 1539 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 1540 if(SiS_Pr->UseCustomMode) return; 1541 1542 if(ModeNo > 0x13) { 1543 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1544 } 1545 1546 if(SiS_Pr->ChipType < SIS_661) { 1547 1548 if(SiS_Pr->SiS_VBInfo & SetPALTV) SiS_Pr->SiS_TVMode |= TVSetPAL; 1549 1550 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1551 temp = 0; 1552 if((SiS_Pr->ChipType == SIS_630) || 1553 (SiS_Pr->ChipType == SIS_730)) { 1554 temp = 0x35; 1555 romindex = 0xfe; 1556 } else if(SiS_Pr->ChipType >= SIS_315H) { 1557 temp = 0x38; 1558 if(SiS_Pr->ChipType < XGI_20) { 1559 romindex = 0xf3; 1560 if(SiS_Pr->ChipType >= SIS_330) romindex = 0x11b; 1561 } 1562 } 1563 if(temp) { 1564 if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 1565 OutputSelect = ROMAddr[romindex]; 1566 if(!(OutputSelect & EnablePALMN)) { 1567 SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F); 1568 } 1569 } 1570 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp); 1571 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1572 if(temp1 & EnablePALM) { /* 0x40 */ 1573 SiS_Pr->SiS_TVMode |= TVSetPALM; 1574 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1575 } else if(temp1 & EnablePALN) { /* 0x80 */ 1576 SiS_Pr->SiS_TVMode |= TVSetPALN; 1577 } 1578 } else { 1579 if(temp1 & EnableNTSCJ) { /* 0x40 */ 1580 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1581 } 1582 } 1583 } 1584 /* Translate HiVision/YPbPr to our new flags */ 1585 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1586 if(SiS_Pr->SiS_YPbPr == YPbPr750p) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1587 else if(SiS_Pr->SiS_YPbPr == YPbPr525p) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1588 else if(SiS_Pr->SiS_YPbPr == YPbPrHiVision) SiS_Pr->SiS_TVMode |= TVSetHiVision; 1589 else SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1590 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p | TVSetYPbPr525i)) { 1591 SiS_Pr->SiS_VBInfo &= ~SetCRT2ToHiVision; 1592 SiS_Pr->SiS_VBInfo |= SetCRT2ToYPbPr525750; 1593 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) { 1594 SiS_Pr->SiS_TVMode |= TVSetPAL; 1595 } 1596 } 1597 } else if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 1598 if(SiS_Pr->SiS_CHOverScan) { 1599 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 1600 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1601 if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) { 1602 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1603 } 1604 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1605 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79); 1606 if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) { 1607 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1608 } 1609 } 1610 if(SiS_Pr->SiS_CHSOverScan) { 1611 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1612 } 1613 } 1614 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1615 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38); 1616 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 1617 if(temp & EnablePALM) SiS_Pr->SiS_TVMode |= TVSetPALM; 1618 else if(temp & EnablePALN) SiS_Pr->SiS_TVMode |= TVSetPALN; 1619 } else { 1620 if(temp & EnableNTSCJ) { 1621 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1622 } 1623 } 1624 } 1625 } 1626 1627 } else { /* 661 and later */ 1628 1629 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1630 if(temp1 & 0x01) { 1631 SiS_Pr->SiS_TVMode |= TVSetPAL; 1632 if(temp1 & 0x08) { 1633 SiS_Pr->SiS_TVMode |= TVSetPALN; 1634 } else if(temp1 & 0x04) { 1635 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1636 SiS_Pr->SiS_TVMode &= ~TVSetPAL; 1637 } 1638 SiS_Pr->SiS_TVMode |= TVSetPALM; 1639 } 1640 } else { 1641 if(temp1 & 0x02) { 1642 SiS_Pr->SiS_TVMode |= TVSetNTSCJ; 1643 } 1644 } 1645 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 1646 if(SiS_Pr->SiS_CHOverScan) { 1647 if((temp1 & 0x10) || (SiS_Pr->SiS_CHOverScan == 1)) { 1648 SiS_Pr->SiS_TVMode |= TVSetCHOverScan; 1649 } 1650 } 1651 } 1652 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1653 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1654 temp1 &= 0xe0; 1655 if(temp1 == 0x00) SiS_Pr->SiS_TVMode |= TVSetYPbPr525i; 1656 else if(temp1 == 0x20) SiS_Pr->SiS_TVMode |= TVSetYPbPr525p; 1657 else if(temp1 == 0x40) SiS_Pr->SiS_TVMode |= TVSetYPbPr750p; 1658 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1659 SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL); 1660 } 1661 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) { 1662 if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) { 1663 SiS_Pr->SiS_TVMode |= TVAspect169; 1664 } else { 1665 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39); 1666 if(temp1 & 0x02) { 1667 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) { 1668 SiS_Pr->SiS_TVMode |= TVAspect169; 1669 } else { 1670 SiS_Pr->SiS_TVMode |= TVAspect43LB; 1671 } 1672 } else { 1673 SiS_Pr->SiS_TVMode |= TVAspect43; 1674 } 1675 } 1676 } 1677 } 1678 } 1679 1680 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) SiS_Pr->SiS_TVMode |= TVSetPAL; 1681 1682 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1683 1684 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 1685 SiS_Pr->SiS_TVMode |= TVSetPAL; 1686 SiS_Pr->SiS_TVMode &= ~(TVSetPALM | TVSetPALN | TVSetNTSCJ); 1687 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 1688 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525i | TVSetYPbPr525p | TVSetYPbPr750p)) { 1689 SiS_Pr->SiS_TVMode &= ~(TVSetPAL | TVSetNTSCJ | TVSetPALM | TVSetPALN); 1690 } 1691 } 1692 1693 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 1694 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 1695 SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 1696 } 1697 } 1698 1699 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 1700 if(resinfo == SIS_RI_1024x768) { 1701 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 1702 SiS_Pr->SiS_TVMode |= TVSet525p1024; 1703 } else if(!(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p))) { 1704 SiS_Pr->SiS_TVMode |= TVSetNTSC1024; 1705 } 1706 } 1707 } 1708 1709 SiS_Pr->SiS_TVMode |= TVRPLLDIV2XO; 1710 if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && 1711 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 1712 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1713 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) { 1714 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1715 } else if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) { 1716 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 1717 SiS_Pr->SiS_TVMode &= ~TVRPLLDIV2XO; 1718 } 1719 } 1720 1721 } 1722 1723 SiS_Pr->SiS_VBInfo &= ~SetPALTV; 1724 } 1725 1726 /*********************************************/ 1727 /* GET LCD INFO */ 1728 /*********************************************/ 1729 1730 static unsigned short 1731 SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr) 1732 { 1733 unsigned short temp = SiS_Pr->SiS_LCDResInfo; 1734 /* Translate my LCDResInfo to BIOS value */ 1735 switch(temp) { 1736 case Panel_1280x768_2: temp = Panel_1280x768; break; 1737 case Panel_1280x800_2: temp = Panel_1280x800; break; 1738 case Panel_1280x854: temp = Panel661_1280x854; break; 1739 } 1740 return temp; 1741 } 1742 1743 static void 1744 SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr) 1745 { 1746 #ifdef CONFIG_FB_SIS_315 1747 unsigned char *ROMAddr; 1748 unsigned short temp; 1749 1750 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { 1751 if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) { 1752 SiS_Pr->SiS_NeedRomModeData = true; 1753 SiS_Pr->PanelHT = temp; 1754 } 1755 if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) { 1756 SiS_Pr->SiS_NeedRomModeData = true; 1757 SiS_Pr->PanelVT = temp; 1758 } 1759 SiS_Pr->PanelHRS = SISGETROMW(10); 1760 SiS_Pr->PanelHRE = SISGETROMW(12); 1761 SiS_Pr->PanelVRS = SISGETROMW(14); 1762 SiS_Pr->PanelVRE = SISGETROMW(16); 1763 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 1764 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK = 1765 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (unsigned short)((unsigned char)ROMAddr[18]); 1766 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B = 1767 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19]; 1768 SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C = 1769 SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20]; 1770 1771 } 1772 #endif 1773 } 1774 1775 static void 1776 SiS_CheckScaling(struct SiS_Private *SiS_Pr, unsigned short resinfo, 1777 const unsigned char *nonscalingmodes) 1778 { 1779 int i = 0; 1780 while(nonscalingmodes[i] != 0xff) { 1781 if(nonscalingmodes[i++] == resinfo) { 1782 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || 1783 (SiS_Pr->UsePanelScaler == -1)) { 1784 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1785 } 1786 break; 1787 } 1788 } 1789 } 1790 1791 void 1792 SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 1793 { 1794 unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0; 1795 bool panelcanscale = false; 1796 #ifdef CONFIG_FB_SIS_300 1797 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 1798 static const unsigned char SiS300SeriesLCDRes[] = 1799 { 0, 1, 2, 3, 7, 4, 5, 8, 1800 0, 0, 10, 0, 0, 0, 0, 15 }; 1801 #endif 1802 #ifdef CONFIG_FB_SIS_315 1803 unsigned char *myptr = NULL; 1804 #endif 1805 1806 SiS_Pr->SiS_LCDResInfo = 0; 1807 SiS_Pr->SiS_LCDTypeInfo = 0; 1808 SiS_Pr->SiS_LCDInfo = 0; 1809 SiS_Pr->PanelHRS = 999; /* HSync start */ 1810 SiS_Pr->PanelHRE = 999; /* HSync end */ 1811 SiS_Pr->PanelVRS = 999; /* VSync start */ 1812 SiS_Pr->PanelVRE = 999; /* VSync end */ 1813 SiS_Pr->SiS_NeedRomModeData = false; 1814 1815 /* Alternative 1600x1200@60 timing for 1600x1200 LCDA */ 1816 SiS_Pr->Alternate1600x1200 = false; 1817 1818 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return; 1819 1820 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 1821 1822 if((ModeNo > 0x13) && (!SiS_Pr->UseCustomMode)) { 1823 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 1824 modexres = SiS_Pr->SiS_ModeResInfo[resinfo].HTotal; 1825 modeyres = SiS_Pr->SiS_ModeResInfo[resinfo].VTotal; 1826 } 1827 1828 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 1829 1830 /* For broken BIOSes: Assume 1024x768 */ 1831 if(temp == 0) temp = 0x02; 1832 1833 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 1834 SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2; 1835 } else if((SiS_Pr->ChipType < SIS_315H) || (SiS_Pr->ChipType >= SIS_661)) { 1836 SiS_Pr->SiS_LCDTypeInfo = temp >> 4; 1837 } else { 1838 SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1; 1839 } 1840 temp &= 0x0f; 1841 #ifdef CONFIG_FB_SIS_300 1842 if(SiS_Pr->ChipType < SIS_315H) { 1843 /* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */ 1844 if(SiS_Pr->SiS_VBType & VB_SIS301) { 1845 if(temp < 0x0f) temp &= 0x07; 1846 } 1847 /* Translate 300 series LCDRes to 315 series for unified usage */ 1848 temp = SiS300SeriesLCDRes[temp]; 1849 } 1850 #endif 1851 1852 /* Translate to our internal types */ 1853 #ifdef CONFIG_FB_SIS_315 1854 if(SiS_Pr->ChipType == SIS_550) { 1855 if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */ 1856 else if(temp == Panel310_320x240_2) temp = Panel_320x240_2; 1857 else if(temp == Panel310_320x240_3) temp = Panel_320x240_3; 1858 } else if(SiS_Pr->ChipType >= SIS_661) { 1859 if(temp == Panel661_1280x854) temp = Panel_1280x854; 1860 } 1861 #endif 1862 1863 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* SiS LVDS */ 1864 if(temp == Panel310_1280x768) { 1865 temp = Panel_1280x768_2; 1866 } 1867 if(SiS_Pr->SiS_ROMNew) { 1868 if(temp == Panel661_1280x800) { 1869 temp = Panel_1280x800_2; 1870 } 1871 } 1872 } 1873 1874 SiS_Pr->SiS_LCDResInfo = temp; 1875 1876 #ifdef CONFIG_FB_SIS_300 1877 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 1878 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 1879 SiS_Pr->SiS_LCDResInfo = Panel_Barco1366; 1880 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) { 1881 SiS_Pr->SiS_LCDResInfo = Panel_848x480; 1882 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL856) { 1883 SiS_Pr->SiS_LCDResInfo = Panel_856x480; 1884 } 1885 } 1886 #endif 1887 1888 if(SiS_Pr->SiS_VBType & VB_SISVB) { 1889 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301) 1890 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301; 1891 } else { 1892 if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS) 1893 SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS; 1894 } 1895 1896 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 1897 SiS_Pr->SiS_LCDInfo = temp & ~0x000e; 1898 /* Need temp below! */ 1899 1900 /* These must/can't scale no matter what */ 1901 switch(SiS_Pr->SiS_LCDResInfo) { 1902 case Panel_320x240_1: 1903 case Panel_320x240_2: 1904 case Panel_320x240_3: 1905 case Panel_1280x960: 1906 SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; 1907 break; 1908 case Panel_640x480: 1909 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1910 } 1911 1912 panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD); 1913 1914 if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD; 1915 else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 1916 1917 /* Dual link, Pass 1:1 BIOS default, etc. */ 1918 #ifdef CONFIG_FB_SIS_315 1919 if(SiS_Pr->ChipType >= SIS_661) { 1920 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1921 if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1922 } 1923 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1924 if(SiS_Pr->SiS_ROMNew) { 1925 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1926 } else if((myptr = GetLCDStructPtr661(SiS_Pr))) { 1927 if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1928 } 1929 } 1930 } else if(SiS_Pr->ChipType >= SIS_315H) { 1931 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 1932 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1933 } 1934 if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) { 1935 SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit); 1936 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35); 1937 if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit; 1938 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1939 if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1940 } 1941 } else if(!(SiS_Pr->SiS_ROMNew)) { 1942 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 1943 if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) && 1944 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) { 1945 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1946 } 1947 if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 1948 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 1949 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 1950 (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) { 1951 SiS_Pr->SiS_LCDInfo |= LCDDualLink; 1952 } 1953 } 1954 } 1955 } 1956 #endif 1957 1958 /* Pass 1:1 */ 1959 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 1960 /* Always center screen on LVDS (if scaling is disabled) */ 1961 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1962 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 1963 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 1964 /* Always center screen on SiS LVDS (if scaling is disabled) */ 1965 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1966 } else { 1967 /* By default, pass 1:1 on SiS TMDS (if scaling is supported) */ 1968 if(panelcanscale) SiS_Pr->SiS_LCDInfo |= LCDPass11; 1969 if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 1970 } 1971 } 1972 1973 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 1974 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 1975 1976 switch(SiS_Pr->SiS_LCDResInfo) { 1977 case Panel_320x240_1: 1978 case Panel_320x240_2: 1979 case Panel_320x240_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; 1980 SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3; 1981 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1982 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1983 break; 1984 case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; 1985 SiS_Pr->PanelVRE = 3; 1986 SiS_Pr->PanelVCLKIdx300 = VCLK28; 1987 SiS_Pr->PanelVCLKIdx315 = VCLK28; 1988 break; 1989 case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600; 1990 SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628; 1991 SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128; 1992 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4; 1993 SiS_Pr->PanelVCLKIdx300 = VCLK40; 1994 SiS_Pr->PanelVCLKIdx315 = VCLK40; 1995 break; 1996 case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600; 1997 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800; 1998 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 1999 SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6; 2000 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 2001 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 2002 break; 2003 case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 2004 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 2005 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 2006 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2007 if(SiS_Pr->ChipType < SIS_315H) { 2008 SiS_Pr->PanelHRS = 23; 2009 SiS_Pr->PanelVRE = 5; 2010 } 2011 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 2012 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 2013 SiS_GetLCDInfoBIOS(SiS_Pr); 2014 break; 2015 case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768; 2016 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 2017 SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136; 2018 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2019 if(SiS_Pr->ChipType < SIS_315H) { 2020 SiS_Pr->PanelHRS = 23; 2021 SiS_Pr->PanelVRE = 5; 2022 } 2023 SiS_Pr->PanelVCLKIdx300 = VCLK65_300; 2024 SiS_Pr->PanelVCLKIdx315 = VCLK65_315; 2025 break; 2026 case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864; 2027 break; 2028 case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720; 2029 SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750; 2030 SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40; 2031 SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5; 2032 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720; 2033 /* Data above for TMDS (projector); get from BIOS for LVDS */ 2034 SiS_GetLCDInfoBIOS(SiS_Pr); 2035 break; 2036 case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 2037 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2038 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806; 2039 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; /* ? */ 2040 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */ 2041 } else { 2042 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802; 2043 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2044 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2045 SiS_Pr->PanelVCLKIdx300 = VCLK81_300; 2046 SiS_Pr->PanelVCLKIdx315 = VCLK81_315; 2047 } 2048 break; 2049 case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; 2050 SiS_Pr->PanelHT = 1660; SiS_Pr->PanelVT = 806; 2051 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2052 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2053 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2; 2054 SiS_GetLCDInfoBIOS(SiS_Pr); 2055 break; 2056 case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 2057 SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 816; 2058 SiS_Pr->PanelHRS = 21; SiS_Pr->PanelHRE = 24; 2059 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 2060 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315; 2061 SiS_GetLCDInfoBIOS(SiS_Pr); 2062 break; 2063 case Panel_1280x800_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800; 2064 SiS_Pr->PanelHT = 1552; SiS_Pr->PanelVT = 812; 2065 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2066 SiS_Pr->PanelVRS = 4; SiS_Pr->PanelVRE = 3; 2067 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x800_315_2; 2068 SiS_GetLCDInfoBIOS(SiS_Pr); 2069 break; 2070 case Panel_1280x854: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 854; 2071 SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 861; 2072 SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 112; 2073 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2074 SiS_Pr->PanelVCLKIdx315 = VCLK_1280x854; 2075 SiS_GetLCDInfoBIOS(SiS_Pr); 2076 break; 2077 case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960; 2078 SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000; 2079 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 2080 SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315; 2081 if(resinfo == SIS_RI_1280x1024) { 2082 SiS_Pr->PanelVCLKIdx300 = VCLK100_300; 2083 SiS_Pr->PanelVCLKIdx315 = VCLK100_315; 2084 } 2085 break; 2086 case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; 2087 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 2088 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2089 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2090 SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300; 2091 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 2092 SiS_GetLCDInfoBIOS(SiS_Pr); 2093 break; 2094 case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; 2095 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 2096 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; 2097 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2098 SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315; 2099 SiS_GetLCDInfoBIOS(SiS_Pr); 2100 break; 2101 case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; 2102 SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250; 2103 SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192; 2104 SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3; 2105 SiS_Pr->PanelVCLKIdx315 = VCLK162_315; 2106 if(SiS_Pr->SiS_VBType & VB_SISTMDSLCDA) { 2107 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 2108 SiS_Pr->PanelHT = 1760; SiS_Pr->PanelVT = 1235; 2109 SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32; 2110 SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4; 2111 SiS_Pr->PanelVCLKIdx315 = VCLK130_315; 2112 SiS_Pr->Alternate1600x1200 = true; 2113 } 2114 } else if(SiS_Pr->SiS_IF_DEF_LVDS) { 2115 SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320; 2116 SiS_Pr->PanelHRS = SiS_Pr->PanelHRE = 999; 2117 SiS_Pr->PanelVRS = SiS_Pr->PanelVRE = 999; 2118 } 2119 SiS_GetLCDInfoBIOS(SiS_Pr); 2120 break; 2121 case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050; 2122 SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066; 2123 SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76; 2124 SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6; 2125 SiS_Pr->PanelVCLKIdx315 = VCLK121_315; 2126 SiS_GetLCDInfoBIOS(SiS_Pr); 2127 break; 2128 case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; 2129 SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066; 2130 break; 2131 case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480; 2132 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525; 2133 break; 2134 case Panel_856x480: SiS_Pr->PanelXRes = 856; SiS_Pr->PanelYRes = 480; 2135 SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525; 2136 break; 2137 case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX; 2138 SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY; 2139 SiS_Pr->PanelHT = SiS_Pr->CHTotal; 2140 SiS_Pr->PanelVT = SiS_Pr->CVTotal; 2141 if(SiS_Pr->CP_PreferredIndex != -1) { 2142 SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex]; 2143 SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex]; 2144 SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex]; 2145 SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex]; 2146 SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex]; 2147 SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex]; 2148 SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex]; 2149 SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex]; 2150 SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes; 2151 SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS; 2152 SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes; 2153 SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS; 2154 if(SiS_Pr->CP_PrefClock) { 2155 int idx; 2156 SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315; 2157 SiS_Pr->PanelVCLKIdx300 = VCLK_CUSTOM_300; 2158 if(SiS_Pr->ChipType < SIS_315H) idx = VCLK_CUSTOM_300; 2159 else idx = VCLK_CUSTOM_315; 2160 SiS_Pr->SiS_VCLKData[idx].CLOCK = 2161 SiS_Pr->SiS_VBVCLKData[idx].CLOCK = SiS_Pr->CP_PrefClock; 2162 SiS_Pr->SiS_VCLKData[idx].SR2B = 2163 SiS_Pr->SiS_VBVCLKData[idx].Part4_A = SiS_Pr->CP_PrefSR2B; 2164 SiS_Pr->SiS_VCLKData[idx].SR2C = 2165 SiS_Pr->SiS_VBVCLKData[idx].Part4_B = SiS_Pr->CP_PrefSR2C; 2166 } 2167 } 2168 break; 2169 default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; 2170 SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806; 2171 break; 2172 } 2173 2174 /* Special cases */ 2175 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 2176 (SiS_Pr->SiS_IF_DEF_DSTN) || 2177 (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 2178 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 2179 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 2180 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 2181 SiS_Pr->PanelHRS = 999; 2182 SiS_Pr->PanelHRE = 999; 2183 } 2184 2185 if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 2186 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 2187 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 2188 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 2189 SiS_Pr->PanelVRS = 999; 2190 SiS_Pr->PanelVRE = 999; 2191 } 2192 2193 /* DontExpand overrule */ 2194 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 2195 2196 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (modeflag & NoSupportLCDScale)) { 2197 /* No scaling for this mode on any panel (LCD=CRT2)*/ 2198 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2199 } 2200 2201 switch(SiS_Pr->SiS_LCDResInfo) { 2202 2203 case Panel_Custom: 2204 case Panel_1152x864: 2205 case Panel_1280x768: /* TMDS only */ 2206 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2207 break; 2208 2209 case Panel_800x600: { 2210 static const unsigned char nonscalingmodes[] = { 2211 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, 0xff 2212 }; 2213 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2214 break; 2215 } 2216 case Panel_1024x768: { 2217 static const unsigned char nonscalingmodes[] = { 2218 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2219 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2220 0xff 2221 }; 2222 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2223 break; 2224 } 2225 case Panel_1280x720: { 2226 static const unsigned char nonscalingmodes[] = { 2227 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2228 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2229 0xff 2230 }; 2231 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2232 if(SiS_Pr->PanelHT == 1650) { 2233 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2234 } 2235 break; 2236 } 2237 case Panel_1280x768_2: { /* LVDS only */ 2238 static const unsigned char nonscalingmodes[] = { 2239 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2240 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2241 SIS_RI_1152x768,0xff 2242 }; 2243 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2244 switch(resinfo) { 2245 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 2246 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2247 } 2248 break; 2249 } 2250 break; 2251 } 2252 case Panel_1280x800: { /* SiS TMDS special (Averatec 6200 series) */ 2253 static const unsigned char nonscalingmodes[] = { 2254 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2255 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2256 SIS_RI_1152x768,SIS_RI_1280x720,SIS_RI_1280x768,0xff 2257 }; 2258 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2259 break; 2260 } 2261 case Panel_1280x800_2: { /* SiS LVDS */ 2262 static const unsigned char nonscalingmodes[] = { 2263 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2264 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2265 SIS_RI_1152x768,0xff 2266 }; 2267 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2268 switch(resinfo) { 2269 case SIS_RI_1280x720: 2270 case SIS_RI_1280x768: if(SiS_Pr->UsePanelScaler == -1) { 2271 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2272 } 2273 break; 2274 } 2275 break; 2276 } 2277 case Panel_1280x854: { /* SiS LVDS */ 2278 static const unsigned char nonscalingmodes[] = { 2279 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2280 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2281 SIS_RI_1152x768,0xff 2282 }; 2283 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2284 switch(resinfo) { 2285 case SIS_RI_1280x720: 2286 case SIS_RI_1280x768: 2287 case SIS_RI_1280x800: if(SiS_Pr->UsePanelScaler == -1) { 2288 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2289 } 2290 break; 2291 } 2292 break; 2293 } 2294 case Panel_1280x960: { 2295 static const unsigned char nonscalingmodes[] = { 2296 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2297 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2298 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2299 SIS_RI_1280x854,0xff 2300 }; 2301 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2302 break; 2303 } 2304 case Panel_1280x1024: { 2305 static const unsigned char nonscalingmodes[] = { 2306 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2307 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2308 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2309 SIS_RI_1280x854,SIS_RI_1280x960,0xff 2310 }; 2311 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2312 break; 2313 } 2314 case Panel_1400x1050: { 2315 static const unsigned char nonscalingmodes[] = { 2316 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2317 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2318 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x768,SIS_RI_1280x800,SIS_RI_1280x854, 2319 SIS_RI_1280x960,0xff 2320 }; 2321 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2322 switch(resinfo) { 2323 case SIS_RI_1280x720: if(SiS_Pr->UsePanelScaler == -1) { 2324 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2325 } 2326 break; 2327 case SIS_RI_1280x1024: SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 2328 break; 2329 } 2330 break; 2331 } 2332 case Panel_1600x1200: { 2333 static const unsigned char nonscalingmodes[] = { 2334 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2335 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2336 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x720,SIS_RI_1280x768,SIS_RI_1280x800, 2337 SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768,SIS_RI_1360x1024,0xff 2338 }; 2339 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2340 break; 2341 } 2342 case Panel_1680x1050: { 2343 static const unsigned char nonscalingmodes[] = { 2344 SIS_RI_720x480, SIS_RI_720x576, SIS_RI_768x576, SIS_RI_800x480, SIS_RI_848x480, 2345 SIS_RI_856x480, SIS_RI_960x540, SIS_RI_960x600, SIS_RI_1024x576,SIS_RI_1024x600, 2346 SIS_RI_1152x768,SIS_RI_1152x864,SIS_RI_1280x854,SIS_RI_1280x960,SIS_RI_1360x768, 2347 SIS_RI_1360x1024,0xff 2348 }; 2349 SiS_CheckScaling(SiS_Pr, resinfo, nonscalingmodes); 2350 break; 2351 } 2352 } 2353 } 2354 2355 #ifdef CONFIG_FB_SIS_300 2356 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2357 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 2358 SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */ 2359 } 2360 } 2361 2362 if(SiS_Pr->ChipType < SIS_315H) { 2363 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2364 if(SiS_Pr->SiS_UseROM) { 2365 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 2366 if(!(ROMAddr[0x235] & 0x02)) { 2367 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2368 } 2369 } 2370 } 2371 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2372 if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) { 2373 SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD); 2374 } 2375 } 2376 } 2377 #endif 2378 2379 /* Special cases */ 2380 2381 if(modexres == SiS_Pr->PanelXRes && modeyres == SiS_Pr->PanelYRes) { 2382 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2383 } 2384 2385 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 2386 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2387 } 2388 2389 switch(SiS_Pr->SiS_LCDResInfo) { 2390 case Panel_640x480: 2391 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2392 break; 2393 case Panel_1280x800: 2394 /* Don't pass 1:1 by default (TMDS special) */ 2395 if(SiS_Pr->CenterScreen == -1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2396 break; 2397 case Panel_1280x960: 2398 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2399 break; 2400 case Panel_Custom: 2401 if((!SiS_Pr->CP_PrefClock) || 2402 (modexres > SiS_Pr->PanelXRes) || (modeyres > SiS_Pr->PanelYRes)) { 2403 SiS_Pr->SiS_LCDInfo |= LCDPass11; 2404 } 2405 break; 2406 } 2407 2408 if((SiS_Pr->UseCustomMode) || (SiS_Pr->SiS_CustomT == CUT_UNKNOWNLCD)) { 2409 SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11); 2410 } 2411 2412 /* (In)validate LCDPass11 flag */ 2413 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2414 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 2415 } 2416 2417 /* LVDS DDA */ 2418 if(!((SiS_Pr->ChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) { 2419 2420 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 2421 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) { 2422 if(ModeNo == 0x12) { 2423 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 2424 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2425 } 2426 } else if(ModeNo > 0x13) { 2427 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) { 2428 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 2429 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) { 2430 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2431 } 2432 } 2433 } 2434 } 2435 } 2436 } 2437 2438 if(modeflag & HalfDCLK) { 2439 if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) { 2440 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2441 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 2442 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2443 } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) { 2444 SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2445 } else if(ModeNo > 0x13) { 2446 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 2447 if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2448 } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) { 2449 if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA; 2450 } 2451 } 2452 } 2453 2454 } 2455 2456 /* VESA timing */ 2457 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2458 if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) { 2459 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2460 } 2461 } else { 2462 SiS_Pr->SiS_SetFlag |= LCDVESATiming; 2463 } 2464 2465 #if 0 2466 printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n", 2467 SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo); 2468 #endif 2469 } 2470 2471 /*********************************************/ 2472 /* GET VCLK */ 2473 /*********************************************/ 2474 2475 unsigned short 2476 SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 2477 unsigned short RefreshRateTableIndex) 2478 { 2479 unsigned short CRT2Index, VCLKIndex = 0, VCLKIndexGEN = 0, VCLKIndexGENCRT = 0; 2480 unsigned short resinfo, tempbx; 2481 const unsigned char *CHTVVCLKPtr = NULL; 2482 2483 if(ModeNo <= 0x13) { 2484 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 2485 CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 2486 VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03; 2487 VCLKIndexGENCRT = VCLKIndexGEN; 2488 } else { 2489 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 2490 CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 2491 VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; 2492 VCLKIndexGENCRT = SiS_GetRefCRTVCLK(SiS_Pr, RefreshRateTableIndex, 2493 (SiS_Pr->SiS_SetFlag & ProgrammingCRT2) ? SiS_Pr->SiS_UseWideCRT2 : SiS_Pr->SiS_UseWide); 2494 } 2495 2496 if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */ 2497 2498 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2499 2500 CRT2Index >>= 6; 2501 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */ 2502 2503 if(SiS_Pr->ChipType < SIS_315H) { 2504 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2505 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2506 VCLKIndex = VCLKIndexGEN; 2507 } 2508 } else { 2509 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2510 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) { 2511 switch(resinfo) { 2512 /* Correct those whose IndexGEN doesn't match VBVCLK array */ 2513 case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break; 2514 case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break; 2515 case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break; 2516 case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break; 2517 case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break; 2518 case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break; 2519 case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break; 2520 case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break; 2521 case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720; break; 2522 case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break; 2523 default: VCLKIndex = VCLKIndexGEN; 2524 } 2525 2526 if(ModeNo <= 0x13) { 2527 if(SiS_Pr->ChipType <= SIS_315PRO) { 2528 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42; 2529 } else { 2530 if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00; 2531 } 2532 } 2533 if(SiS_Pr->ChipType <= SIS_315PRO) { 2534 if(VCLKIndex == 0) VCLKIndex = 0x41; 2535 if(VCLKIndex == 1) VCLKIndex = 0x43; 2536 if(VCLKIndex == 4) VCLKIndex = 0x44; 2537 } 2538 } 2539 } 2540 2541 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */ 2542 2543 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 2544 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2; 2545 else VCLKIndex = HiTVVCLK; 2546 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) VCLKIndex = HiTVSimuVCLK; 2547 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK; 2548 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2; 2549 else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2; 2550 else VCLKIndex = TVVCLK; 2551 2552 if(SiS_Pr->ChipType < SIS_315H) VCLKIndex += TVCLKBASE_300; 2553 else VCLKIndex += TVCLKBASE_315; 2554 2555 } else { /* VGA2 */ 2556 2557 VCLKIndex = VCLKIndexGENCRT; 2558 if(SiS_Pr->ChipType < SIS_315H) { 2559 if(ModeNo > 0x13) { 2560 if( (SiS_Pr->ChipType == SIS_630) && 2561 (SiS_Pr->ChipRevision >= 0x30)) { 2562 if(VCLKIndex == 0x14) VCLKIndex = 0x34; 2563 } 2564 /* Better VGA2 clock for 1280x1024@75 */ 2565 if(VCLKIndex == 0x17) VCLKIndex = 0x45; 2566 } 2567 } 2568 } 2569 2570 } else { /* If not programming CRT2 */ 2571 2572 VCLKIndex = VCLKIndexGENCRT; 2573 if(SiS_Pr->ChipType < SIS_315H) { 2574 if(ModeNo > 0x13) { 2575 if( (SiS_Pr->ChipType != SIS_630) && 2576 (SiS_Pr->ChipType != SIS_300) ) { 2577 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2578 } 2579 } 2580 } 2581 } 2582 2583 } else { /* LVDS */ 2584 2585 VCLKIndex = CRT2Index; 2586 2587 if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { 2588 2589 if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) { 2590 2591 VCLKIndex &= 0x1f; 2592 tempbx = 0; 2593 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2594 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 2595 tempbx += 2; 2596 if(SiS_Pr->SiS_ModeType > ModeVGA) { 2597 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8; 2598 } 2599 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 2600 tempbx = 4; 2601 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2602 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 2603 tempbx = 6; 2604 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1; 2605 } 2606 } 2607 switch(tempbx) { 2608 case 0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC; break; 2609 case 1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC; break; 2610 case 2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL; break; 2611 case 3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2612 case 4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM; break; 2613 case 5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM; break; 2614 case 6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN; break; 2615 case 7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN; break; 2616 case 8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL; break; 2617 default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL; break; 2618 } 2619 VCLKIndex = CHTVVCLKPtr[VCLKIndex]; 2620 2621 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 2622 2623 if(SiS_Pr->ChipType < SIS_315H) { 2624 VCLKIndex = SiS_Pr->PanelVCLKIdx300; 2625 } else { 2626 VCLKIndex = SiS_Pr->PanelVCLKIdx315; 2627 } 2628 2629 #ifdef CONFIG_FB_SIS_300 2630 /* Special Timing: Barco iQ Pro R series */ 2631 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44; 2632 2633 /* Special Timing: 848x480 and 856x480 parallel lvds panels */ 2634 if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 2635 if(SiS_Pr->ChipType < SIS_315H) { 2636 VCLKIndex = VCLK34_300; 2637 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2638 } else { 2639 VCLKIndex = VCLK34_315; 2640 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */ 2641 } 2642 } 2643 #endif 2644 2645 } else { 2646 2647 VCLKIndex = VCLKIndexGENCRT; 2648 if(SiS_Pr->ChipType < SIS_315H) { 2649 if(ModeNo > 0x13) { 2650 if( (SiS_Pr->ChipType == SIS_630) && 2651 (SiS_Pr->ChipRevision >= 0x30) ) { 2652 if(VCLKIndex == 0x14) VCLKIndex = 0x2e; 2653 } 2654 } 2655 } 2656 } 2657 2658 } else { /* if not programming CRT2 */ 2659 2660 VCLKIndex = VCLKIndexGENCRT; 2661 if(SiS_Pr->ChipType < SIS_315H) { 2662 if(ModeNo > 0x13) { 2663 if( (SiS_Pr->ChipType != SIS_630) && 2664 (SiS_Pr->ChipType != SIS_300) ) { 2665 if(VCLKIndex == 0x1b) VCLKIndex = 0x48; 2666 } 2667 #if 0 2668 if(SiS_Pr->ChipType == SIS_730) { 2669 if(VCLKIndex == 0x0b) VCLKIndex = 0x40; /* 1024x768-70 */ 2670 if(VCLKIndex == 0x0d) VCLKIndex = 0x41; /* 1024x768-75 */ 2671 } 2672 #endif 2673 } 2674 } 2675 2676 } 2677 2678 } 2679 2680 return VCLKIndex; 2681 } 2682 2683 /*********************************************/ 2684 /* SET CRT2 MODE TYPE REGISTERS */ 2685 /*********************************************/ 2686 2687 static void 2688 SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 2689 { 2690 unsigned short i, j, modeflag, tempah=0; 2691 short tempcl; 2692 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 2693 unsigned short tempbl; 2694 #endif 2695 #ifdef CONFIG_FB_SIS_315 2696 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 2697 unsigned short tempah2, tempbl2; 2698 #endif 2699 2700 modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); 2701 2702 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 2703 2704 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); 2705 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7); 2706 2707 } else { 2708 2709 for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0); 2710 if(SiS_Pr->ChipType >= SIS_315H) { 2711 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F); 2712 } 2713 2714 tempcl = SiS_Pr->SiS_ModeType; 2715 2716 if(SiS_Pr->ChipType < SIS_315H) { 2717 2718 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */ 2719 2720 /* For 301BDH: (with LCD via LVDS) */ 2721 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 2722 tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32); 2723 tempbl &= 0xef; 2724 tempbl |= 0x02; 2725 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 2726 tempbl |= 0x10; 2727 tempbl &= 0xfd; 2728 } 2729 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl); 2730 } 2731 2732 if(ModeNo > 0x13) { 2733 tempcl -= ModeVGA; 2734 if(tempcl >= 0) { 2735 tempah = ((0x10 >> tempcl) | 0x80); 2736 } 2737 } else tempah = 0x80; 2738 2739 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0; 2740 2741 #endif /* CONFIG_FB_SIS_300 */ 2742 2743 } else { 2744 2745 #ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */ 2746 2747 if(ModeNo > 0x13) { 2748 tempcl -= ModeVGA; 2749 if(tempcl >= 0) { 2750 tempah = (0x08 >> tempcl); 2751 if (tempah == 0) tempah = 1; 2752 tempah |= 0x40; 2753 } 2754 } else tempah = 0x40; 2755 2756 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50; 2757 2758 #endif /* CONFIG_FB_SIS_315 */ 2759 2760 } 2761 2762 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2763 2764 if(SiS_Pr->ChipType < SIS_315H) { 2765 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2766 } else { 2767 #ifdef CONFIG_FB_SIS_315 2768 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 2769 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2770 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 2771 if(IS_SIS740) { 2772 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah); 2773 } else { 2774 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah); 2775 } 2776 } 2777 #endif 2778 } 2779 2780 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2781 2782 tempah = 0x01; 2783 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 2784 tempah |= 0x02; 2785 } 2786 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 2787 tempah ^= 0x05; 2788 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 2789 tempah ^= 0x01; 2790 } 2791 } 2792 2793 if(SiS_Pr->ChipType < SIS_315H) { 2794 2795 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2796 2797 tempah = (tempah << 5) & 0xFF; 2798 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2799 tempah = (tempah >> 5) & 0xFF; 2800 2801 } else { 2802 2803 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x08; 2804 else if(!(SiS_IsDualEdge(SiS_Pr))) tempah |= 0x08; 2805 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF0,tempah); 2806 tempah &= ~0x08; 2807 2808 } 2809 2810 if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 2811 tempah |= 0x10; 2812 } 2813 2814 tempah |= 0x80; 2815 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2816 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah &= ~0x80; 2817 } 2818 2819 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2820 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetYPbPr525p))) { 2821 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 2822 tempah |= 0x20; 2823 } 2824 } 2825 } 2826 2827 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah); 2828 2829 tempah = 0x80; 2830 if(SiS_Pr->SiS_VBType & VB_SIS301) { 2831 if(SiS_Pr->PanelXRes < 1280 && SiS_Pr->PanelYRes < 960) tempah = 0; 2832 } 2833 2834 if(SiS_IsDualLink(SiS_Pr)) tempah |= 0x40; 2835 2836 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 2837 if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) { 2838 tempah |= 0x40; 2839 } 2840 } 2841 2842 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah); 2843 2844 } else { /* LVDS */ 2845 2846 if(SiS_Pr->ChipType >= SIS_315H) { 2847 2848 #ifdef CONFIG_FB_SIS_315 2849 /* LVDS can only be slave in 8bpp modes */ 2850 tempah = 0x80; 2851 if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) { 2852 if(SiS_Pr->SiS_VBInfo & DriverMode) { 2853 tempah |= 0x02; 2854 } 2855 } 2856 2857 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) tempah |= 0x02; 2858 2859 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah ^= 0x01; 2860 2861 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 1; 2862 2863 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah); 2864 #endif 2865 2866 } else { 2867 2868 #ifdef CONFIG_FB_SIS_300 2869 tempah = 0; 2870 if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) { 2871 tempah |= 0x02; 2872 } 2873 tempah <<= 5; 2874 2875 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0; 2876 2877 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah); 2878 #endif 2879 2880 } 2881 2882 } 2883 2884 } /* LCDA */ 2885 2886 if(SiS_Pr->SiS_VBType & VB_SISVB) { 2887 2888 if(SiS_Pr->ChipType >= SIS_315H) { 2889 2890 #ifdef CONFIG_FB_SIS_315 2891 /* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */ 2892 2893 /* The following is nearly unpreditable and varies from machine 2894 * to machine. Especially the 301DH seems to be a real trouble 2895 * maker. Some BIOSes simply set the registers (like in the 2896 * NoLCD-if-statements here), some set them according to the 2897 * LCDA stuff. It is very likely that some machines are not 2898 * treated correctly in the following, very case-orientated 2899 * code. What do I do then...? 2900 */ 2901 2902 /* 740 variants match for 30xB, 301B-DH, 30xLV */ 2903 2904 if(!(IS_SIS740)) { 2905 tempah = 0x04; /* For all bridges */ 2906 tempbl = 0xfb; 2907 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2908 tempah = 0x00; 2909 if(SiS_IsDualEdge(SiS_Pr)) { 2910 tempbl = 0xff; 2911 } 2912 } 2913 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 2914 } 2915 2916 /* The following two are responsible for eventually wrong colors 2917 * in TV output. The DH (VB_NoLCD) conditions are unknown; the 2918 * b0 was found in some 651 machine (Pim; P4_23=0xe5); the b1 version 2919 * in a 650 box (Jake). What is the criteria? 2920 * Addendum: Another combination 651+301B-DH(b1) (Rapo) needs same 2921 * treatment like the 651+301B-DH(b0) case. Seems more to be the 2922 * chipset than the bridge revision. 2923 */ 2924 2925 if((IS_SIS740) || (SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 2926 tempah = 0x30; 2927 tempbl = 0xc0; 2928 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2929 ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) { 2930 tempah = 0x00; 2931 tempbl = 0x00; 2932 } 2933 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,tempah); 2934 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,tempbl); 2935 } else if(SiS_Pr->SiS_VBType & VB_SIS301) { 2936 /* Fixes "TV-blue-bug" on 315+301 */ 2937 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xcf); /* For 301 */ 2938 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2939 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 2940 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); /* For 30xLV */ 2941 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x21,0xc0); 2942 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* For 301B-DH */ 2943 tempah = 0x30; tempah2 = 0xc0; 2944 tempbl = 0xcf; tempbl2 = 0x3f; 2945 if(SiS_Pr->SiS_TVBlue == 0) { 2946 tempah = tempah2 = 0x00; 2947 } else if(SiS_Pr->SiS_TVBlue == -1) { 2948 /* Set on 651/M650, clear on 315/650 */ 2949 if(!(IS_SIS65x)) /* (bridgerev != 0xb0) */ { 2950 tempah = tempah2 = 0x00; 2951 } 2952 } 2953 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); 2954 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2); 2955 } else { 2956 tempah = 0x30; tempah2 = 0xc0; /* For 30xB, 301C */ 2957 tempbl = 0xcf; tempbl2 = 0x3f; 2958 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2959 tempah = tempah2 = 0x00; 2960 if(SiS_IsDualEdge(SiS_Pr)) { 2961 tempbl = tempbl2 = 0xff; 2962 } 2963 } 2964 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah); 2965 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl2,tempah2); 2966 } 2967 2968 if(IS_SIS740) { 2969 tempah = 0x80; 2970 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00; 2971 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah); 2972 } else { 2973 tempah = 0x00; 2974 tempbl = 0x7f; 2975 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 2976 tempbl = 0xff; 2977 if(!(SiS_IsDualEdge(SiS_Pr))) tempah = 0x80; 2978 } 2979 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah); 2980 } 2981 2982 #endif /* CONFIG_FB_SIS_315 */ 2983 2984 } else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 2985 2986 #ifdef CONFIG_FB_SIS_300 2987 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f); 2988 2989 if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) || 2990 ((SiS_Pr->SiS_VBType & VB_NoLCD) && 2991 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) { 2992 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F); 2993 } else { 2994 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80); 2995 } 2996 #endif 2997 2998 } 2999 3000 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 3001 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x0D,0x80); 3002 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 3003 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3A,0xC0); 3004 } 3005 } 3006 3007 } else { /* LVDS */ 3008 3009 #ifdef CONFIG_FB_SIS_315 3010 if(SiS_Pr->ChipType >= SIS_315H) { 3011 3012 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 3013 3014 tempah = 0x04; 3015 tempbl = 0xfb; 3016 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3017 tempah = 0x00; 3018 if(SiS_IsDualEdge(SiS_Pr)) tempbl = 0xff; 3019 } 3020 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah); 3021 3022 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 3023 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 3024 } 3025 3026 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 3027 3028 } else if(SiS_Pr->ChipType == SIS_550) { 3029 3030 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 3031 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2c,0x30); 3032 3033 } 3034 3035 } 3036 #endif 3037 3038 } 3039 3040 } 3041 3042 /*********************************************/ 3043 /* GET RESOLUTION DATA */ 3044 /*********************************************/ 3045 3046 unsigned short 3047 SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 3048 { 3049 if(ModeNo <= 0x13) 3050 return ((unsigned short)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo); 3051 else 3052 return ((unsigned short)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO); 3053 } 3054 3055 static void 3056 SiS_GetCRT2ResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 3057 { 3058 unsigned short xres, yres, modeflag=0, resindex; 3059 3060 if(SiS_Pr->UseCustomMode) { 3061 xres = SiS_Pr->CHDisplay; 3062 if(SiS_Pr->CModeFlag & HalfDCLK) xres <<= 1; 3063 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 3064 /* DoubleScanMode-check done in CheckCalcCustomMode()! */ 3065 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay; 3066 return; 3067 } 3068 3069 resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex); 3070 3071 if(ModeNo <= 0x13) { 3072 xres = SiS_Pr->SiS_StResInfo[resindex].HTotal; 3073 yres = SiS_Pr->SiS_StResInfo[resindex].VTotal; 3074 } else { 3075 xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal; 3076 yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal; 3077 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3078 } 3079 3080 if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) { 3081 3082 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) { 3083 if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) { 3084 if(yres == 350) yres = 400; 3085 } 3086 if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) { 3087 if(ModeNo == 0x12) yres = 400; 3088 } 3089 } 3090 3091 if(modeflag & HalfDCLK) xres <<= 1; 3092 if(modeflag & DoubleScanMode) yres <<= 1; 3093 3094 } 3095 3096 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 3097 3098 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3099 switch(SiS_Pr->SiS_LCDResInfo) { 3100 case Panel_1024x768: 3101 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3102 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3103 if(yres == 350) yres = 357; 3104 if(yres == 400) yres = 420; 3105 if(yres == 480) yres = 525; 3106 } 3107 } 3108 break; 3109 case Panel_1280x1024: 3110 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3111 /* BIOS bug - does this regardless of scaling */ 3112 if(yres == 400) yres = 405; 3113 } 3114 if(yres == 350) yres = 360; 3115 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 3116 if(yres == 360) yres = 375; 3117 } 3118 break; 3119 case Panel_1600x1200: 3120 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3121 if(yres == 1024) yres = 1056; 3122 } 3123 break; 3124 } 3125 } 3126 3127 } else { 3128 3129 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3130 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) { 3131 if(xres == 720) xres = 640; 3132 } 3133 } else if(xres == 720) xres = 640; 3134 3135 if(SiS_Pr->SiS_SetFlag & SetDOSMode) { 3136 yres = 400; 3137 if(SiS_Pr->ChipType >= SIS_315H) { 3138 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480; 3139 } else { 3140 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480; 3141 } 3142 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480; 3143 } 3144 3145 } 3146 SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres; 3147 SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres; 3148 } 3149 3150 /*********************************************/ 3151 /* GET CRT2 TIMING DATA */ 3152 /*********************************************/ 3153 3154 static void 3155 SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3156 unsigned short RefreshRateTableIndex, unsigned short *CRT2Index, 3157 unsigned short *ResIndex) 3158 { 3159 unsigned short tempbx=0, tempal=0, resinfo=0; 3160 3161 if(ModeNo <= 0x13) { 3162 tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3163 } else { 3164 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 3165 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 3166 } 3167 3168 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_IF_DEF_LVDS == 0)) { 3169 3170 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */ 3171 3172 tempbx = SiS_Pr->SiS_LCDResInfo; 3173 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32; 3174 3175 /* patch index */ 3176 if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) { 3177 if (resinfo == SIS_RI_1280x800) tempal = 9; 3178 else if(resinfo == SIS_RI_1400x1050) tempal = 11; 3179 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x800) || 3180 (SiS_Pr->SiS_LCDResInfo == Panel_1280x800_2) || 3181 (SiS_Pr->SiS_LCDResInfo == Panel_1280x854)) { 3182 if (resinfo == SIS_RI_1280x768) tempal = 9; 3183 } 3184 3185 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3186 /* Pass 1:1 only (center-screen handled outside) */ 3187 /* This is never called for the panel's native resolution */ 3188 /* since Pass1:1 will not be set in this case */ 3189 tempbx = 100; 3190 if(ModeNo >= 0x13) { 3191 tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS; 3192 } 3193 } 3194 3195 #ifdef CONFIG_FB_SIS_315 3196 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 3197 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 3198 if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 3199 tempbx = 200; 3200 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; 3201 } 3202 } 3203 } 3204 #endif 3205 3206 } else { /* TV */ 3207 3208 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 3209 /* if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_TVMode &= (~TVSetTVSimuMode); */ 3210 tempbx = 2; 3211 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 3212 tempbx = 13; 3213 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) tempbx = 14; 3214 } 3215 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3216 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempbx = 7; 3217 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempbx = 6; 3218 else tempbx = 5; 3219 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 3220 } else { 3221 if(SiS_Pr->SiS_TVMode & TVSetPAL) tempbx = 3; 3222 else tempbx = 4; 3223 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) tempbx += 5; 3224 } 3225 3226 } 3227 3228 tempal &= 0x3F; 3229 3230 if(ModeNo > 0x13) { 3231 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) { 3232 switch(resinfo) { 3233 case SIS_RI_720x480: 3234 tempal = 6; 3235 if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) tempal = 9; 3236 break; 3237 case SIS_RI_720x576: 3238 case SIS_RI_768x576: 3239 case SIS_RI_1024x576: /* Not in NTSC or YPBPR mode (except 1080i)! */ 3240 tempal = 6; 3241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3242 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 8; 3243 } 3244 break; 3245 case SIS_RI_800x480: 3246 tempal = 4; 3247 break; 3248 case SIS_RI_512x384: 3249 case SIS_RI_1024x768: 3250 tempal = 7; 3251 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3252 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tempal = 8; 3253 } 3254 break; 3255 case SIS_RI_1280x720: 3256 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3257 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempal = 9; 3258 } 3259 break; 3260 } 3261 } 3262 } 3263 3264 *CRT2Index = tempbx; 3265 *ResIndex = tempal; 3266 3267 } else { /* LVDS, 301B-DH (if running on LCD) */ 3268 3269 tempbx = 0; 3270 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 3271 3272 tempbx = 90; 3273 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 3274 tempbx = 92; 3275 if(SiS_Pr->SiS_ModeType > ModeVGA) { 3276 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99; 3277 } 3278 if(SiS_Pr->SiS_TVMode & TVSetPALM) tempbx = 94; 3279 else if(SiS_Pr->SiS_TVMode & TVSetPALN) tempbx = 96; 3280 } 3281 if(tempbx != 99) { 3282 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++; 3283 } 3284 3285 } else { 3286 3287 switch(SiS_Pr->SiS_LCDResInfo) { 3288 case Panel_640x480: tempbx = 12; break; 3289 case Panel_320x240_1: tempbx = 10; break; 3290 case Panel_320x240_2: 3291 case Panel_320x240_3: tempbx = 14; break; 3292 case Panel_800x600: tempbx = 16; break; 3293 case Panel_1024x600: tempbx = 18; break; 3294 case Panel_1152x768: 3295 case Panel_1024x768: tempbx = 20; break; 3296 case Panel_1280x768: tempbx = 22; break; 3297 case Panel_1280x1024: tempbx = 24; break; 3298 case Panel_1400x1050: tempbx = 26; break; 3299 case Panel_1600x1200: tempbx = 28; break; 3300 #ifdef CONFIG_FB_SIS_300 3301 case Panel_Barco1366: tempbx = 80; break; 3302 #endif 3303 } 3304 3305 switch(SiS_Pr->SiS_LCDResInfo) { 3306 case Panel_320x240_1: 3307 case Panel_320x240_2: 3308 case Panel_320x240_3: 3309 case Panel_640x480: 3310 break; 3311 default: 3312 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3313 } 3314 3315 if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30; 3316 3317 #ifdef CONFIG_FB_SIS_300 3318 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 3319 tempbx = 82; 3320 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3321 } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) { 3322 tempbx = 84; 3323 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 3324 } 3325 #endif 3326 3327 } 3328 3329 (*CRT2Index) = tempbx; 3330 (*ResIndex) = tempal & 0x1F; 3331 } 3332 } 3333 3334 static void 3335 SiS_GetRAMDAC2DATA(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3336 unsigned short RefreshRateTableIndex) 3337 { 3338 unsigned short tempax=0, tempbx=0, index, dotclock; 3339 unsigned short temp1=0, modeflag=0, tempcx=0; 3340 3341 SiS_Pr->SiS_RVBHCMAX = 1; 3342 SiS_Pr->SiS_RVBHCFACT = 1; 3343 3344 if(ModeNo <= 0x13) { 3345 3346 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3347 index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex); 3348 3349 tempax = SiS_Pr->SiS_StandTable[index].CRTC[0]; 3350 tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6]; 3351 temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7]; 3352 3353 dotclock = (modeflag & Charx8Dot) ? 8 : 9; 3354 3355 } else { 3356 3357 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3358 index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2); 3359 3360 tempax = SiS_Pr->SiS_CRT1Table[index].CR[0]; 3361 tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8); 3362 tempax &= 0x03FF; 3363 tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6]; 3364 tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8; 3365 tempcx &= 0x0100; 3366 tempcx <<= 2; 3367 tempbx |= tempcx; 3368 temp1 = SiS_Pr->SiS_CRT1Table[index].CR[7]; 3369 3370 dotclock = 8; 3371 3372 } 3373 3374 if(temp1 & 0x01) tempbx |= 0x0100; 3375 if(temp1 & 0x20) tempbx |= 0x0200; 3376 3377 tempax += 5; 3378 tempax *= dotclock; 3379 if(modeflag & HalfDCLK) tempax <<= 1; 3380 3381 tempbx++; 3382 3383 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3384 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx; 3385 } 3386 3387 static void 3388 SiS_CalcPanelLinkTiming(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 3389 unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex) 3390 { 3391 unsigned short ResIndex; 3392 3393 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3394 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 3395 if(SiS_Pr->UseCustomMode) { 3396 ResIndex = SiS_Pr->CHTotal; 3397 if(SiS_Pr->CModeFlag & HalfDCLK) ResIndex <<= 1; 3398 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = ResIndex; 3399 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3400 } else { 3401 if(ModeNo < 0x13) { 3402 ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3403 } else { 3404 ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS; 3405 } 3406 if(ResIndex == 0x09) { 3407 if(SiS_Pr->Alternate1600x1200) ResIndex = 0x20; /* 1600x1200 LCDA */ 3408 else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) ResIndex = 0x21; /* 1600x1200 LVDS */ 3409 } 3410 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT; 3411 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT; 3412 SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT; 3413 SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT; 3414 } 3415 } else { 3416 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3417 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3418 } 3419 } else { 3420 /* This handles custom modes and custom panels */ 3421 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; 3422 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; 3423 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3424 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3425 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE); 3426 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE); 3427 } 3428 } 3429 3430 static void 3431 SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3432 unsigned short RefreshRateTableIndex) 3433 { 3434 unsigned short CRT2Index, ResIndex, backup; 3435 const struct SiS_LVDSData *LVDSData = NULL; 3436 3437 SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex); 3438 3439 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3440 SiS_Pr->SiS_RVBHCMAX = 1; 3441 SiS_Pr->SiS_RVBHCFACT = 1; 3442 SiS_Pr->SiS_NewFlickerMode = 0; 3443 SiS_Pr->SiS_RVBHRS = 50; 3444 SiS_Pr->SiS_RY1COE = 0; 3445 SiS_Pr->SiS_RY2COE = 0; 3446 SiS_Pr->SiS_RY3COE = 0; 3447 SiS_Pr->SiS_RY4COE = 0; 3448 SiS_Pr->SiS_RVBHRS2 = 0; 3449 } 3450 3451 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3452 3453 #ifdef CONFIG_FB_SIS_315 3454 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3455 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); 3456 #endif 3457 3458 } else { 3459 3460 /* 301BDH needs LVDS Data */ 3461 backup = SiS_Pr->SiS_IF_DEF_LVDS; 3462 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3463 SiS_Pr->SiS_IF_DEF_LVDS = 1; 3464 } 3465 3466 SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 3467 &CRT2Index, &ResIndex); 3468 3469 SiS_Pr->SiS_IF_DEF_LVDS = backup; 3470 3471 switch(CRT2Index) { 3472 case 10: LVDSData = SiS_Pr->SiS_LVDS320x240Data_1; break; 3473 case 14: LVDSData = SiS_Pr->SiS_LVDS320x240Data_2; break; 3474 case 12: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break; 3475 case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break; 3476 case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break; 3477 case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break; 3478 #ifdef CONFIG_FB_SIS_300 3479 case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break; 3480 case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break; 3481 case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break; 3482 case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break; 3483 case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break; 3484 #endif 3485 case 90: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break; 3486 case 91: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break; 3487 case 92: LVDSData = SiS_Pr->SiS_CHTVUPALData; break; 3488 case 93: LVDSData = SiS_Pr->SiS_CHTVOPALData; break; 3489 case 94: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break; 3490 case 95: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break; 3491 case 96: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break; 3492 case 97: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break; 3493 case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; 3494 } 3495 3496 if(LVDSData) { 3497 SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT; 3498 SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT; 3499 SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT; 3500 SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT; 3501 } else { 3502 SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3503 } 3504 3505 if( (!(SiS_Pr->SiS_VBType & VB_SISVB)) && 3506 (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && 3507 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) ) { 3508 if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || 3509 (SiS_Pr->SiS_SetFlag & SetDOSMode) ) { 3510 SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes; 3511 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes; 3512 #ifdef CONFIG_FB_SIS_300 3513 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 3514 if(ResIndex < 0x08) { 3515 SiS_Pr->SiS_HDE = 1280; 3516 SiS_Pr->SiS_VDE = 1024; 3517 } 3518 } 3519 #endif 3520 } 3521 } 3522 } 3523 } 3524 3525 static void 3526 SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3527 unsigned short RefreshRateTableIndex) 3528 { 3529 unsigned char *ROMAddr = NULL; 3530 unsigned short tempax, tempbx, modeflag, romptr=0; 3531 unsigned short resinfo, CRT2Index, ResIndex; 3532 const struct SiS_LCDData *LCDPtr = NULL; 3533 const struct SiS_TVData *TVPtr = NULL; 3534 #ifdef CONFIG_FB_SIS_315 3535 short resinfo661; 3536 #endif 3537 3538 if(ModeNo <= 0x13) { 3539 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 3540 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 3541 } else if(SiS_Pr->UseCustomMode) { 3542 modeflag = SiS_Pr->CModeFlag; 3543 resinfo = 0; 3544 } else { 3545 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 3546 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 3547 #ifdef CONFIG_FB_SIS_315 3548 resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661; 3549 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && 3550 (SiS_Pr->SiS_SetFlag & LCDVESATiming) && 3551 (resinfo661 >= 0) && 3552 (SiS_Pr->SiS_NeedRomModeData) ) { 3553 if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) { 3554 if((romptr = (SISGETROMW(21)))) { 3555 romptr += (resinfo661 * 10); 3556 ROMAddr = SiS_Pr->VirtualRomBase; 3557 } 3558 } 3559 } 3560 #endif 3561 } 3562 3563 SiS_Pr->SiS_NewFlickerMode = 0; 3564 SiS_Pr->SiS_RVBHRS = 50; 3565 SiS_Pr->SiS_RY1COE = 0; 3566 SiS_Pr->SiS_RY2COE = 0; 3567 SiS_Pr->SiS_RY3COE = 0; 3568 SiS_Pr->SiS_RY4COE = 0; 3569 SiS_Pr->SiS_RVBHRS2 = 0; 3570 3571 SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex); 3572 3573 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 3574 3575 if(SiS_Pr->UseCustomMode) { 3576 3577 SiS_Pr->SiS_RVBHCMAX = 1; 3578 SiS_Pr->SiS_RVBHCFACT = 1; 3579 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3580 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3581 3582 tempax = SiS_Pr->CHTotal; 3583 if(modeflag & HalfDCLK) tempax <<= 1; 3584 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3585 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3586 3587 } else { 3588 3589 SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3590 3591 } 3592 3593 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 3594 3595 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3596 &CRT2Index,&ResIndex); 3597 3598 switch(CRT2Index) { 3599 case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break; 3600 case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break; 3601 case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break; 3602 case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break; 3603 case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break; 3604 case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break; 3605 case 8: TVPtr = SiS_Pr->SiS_StPALData; break; 3606 case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break; 3607 case 10: TVPtr = SiS_Pr->SiS_St525iData; break; 3608 case 11: TVPtr = SiS_Pr->SiS_St525pData; break; 3609 case 12: TVPtr = SiS_Pr->SiS_St750pData; break; 3610 case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break; 3611 case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break; 3612 default: TVPtr = SiS_Pr->SiS_StPALData; break; 3613 } 3614 3615 SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX; 3616 SiS_Pr->SiS_RVBHCFACT = (TVPtr+ResIndex)->RVBHCFACT; 3617 SiS_Pr->SiS_VGAHT = (TVPtr+ResIndex)->VGAHT; 3618 SiS_Pr->SiS_VGAVT = (TVPtr+ResIndex)->VGAVT; 3619 SiS_Pr->SiS_HDE = (TVPtr+ResIndex)->TVHDE; 3620 SiS_Pr->SiS_VDE = (TVPtr+ResIndex)->TVVDE; 3621 SiS_Pr->SiS_RVBHRS2 = (TVPtr+ResIndex)->RVBHRS2 & 0x0fff; 3622 if(modeflag & HalfDCLK) { 3623 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS; 3624 if(SiS_Pr->SiS_RVBHRS2) { 3625 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3; 3626 tempax = ((TVPtr+ResIndex)->RVBHRS2 >> 12) & 0x07; 3627 if((TVPtr+ResIndex)->RVBHRS2 & 0x8000) SiS_Pr->SiS_RVBHRS2 -= tempax; 3628 else SiS_Pr->SiS_RVBHRS2 += tempax; 3629 } 3630 } else { 3631 SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->RVBHRS; 3632 } 3633 SiS_Pr->SiS_NewFlickerMode = ((TVPtr+ResIndex)->FlickerMode) << 7; 3634 3635 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 3636 3637 if((resinfo == SIS_RI_960x600) || 3638 (resinfo == SIS_RI_1024x768) || 3639 (resinfo == SIS_RI_1280x1024) || 3640 (resinfo == SIS_RI_1280x720)) { 3641 SiS_Pr->SiS_NewFlickerMode = 0x40; 3642 } 3643 3644 if(SiS_Pr->SiS_VGAVDE == 350) SiS_Pr->SiS_TVMode |= TVSetTVSimuMode; 3645 3646 SiS_Pr->SiS_HT = ExtHiTVHT; 3647 SiS_Pr->SiS_VT = ExtHiTVVT; 3648 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 3649 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 3650 SiS_Pr->SiS_HT = StHiTVHT; 3651 SiS_Pr->SiS_VT = StHiTVVT; 3652 } 3653 } 3654 3655 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 3656 3657 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 3658 SiS_Pr->SiS_HT = 1650; 3659 SiS_Pr->SiS_VT = 750; 3660 } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 3661 SiS_Pr->SiS_HT = NTSCHT; 3662 if(SiS_Pr->SiS_TVMode & TVSet525p1024) SiS_Pr->SiS_HT = NTSC2HT; 3663 SiS_Pr->SiS_VT = NTSCVT; 3664 } else { 3665 SiS_Pr->SiS_HT = NTSCHT; 3666 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3667 SiS_Pr->SiS_VT = NTSCVT; 3668 } 3669 3670 } else { 3671 3672 SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE; 3673 SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE; 3674 SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE; 3675 SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE; 3676 3677 if(modeflag & HalfDCLK) { 3678 SiS_Pr->SiS_RY1COE = 0x00; 3679 SiS_Pr->SiS_RY2COE = 0xf4; 3680 SiS_Pr->SiS_RY3COE = 0x10; 3681 SiS_Pr->SiS_RY4COE = 0x38; 3682 } 3683 3684 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 3685 SiS_Pr->SiS_HT = NTSCHT; 3686 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) SiS_Pr->SiS_HT = NTSC2HT; 3687 SiS_Pr->SiS_VT = NTSCVT; 3688 } else { 3689 SiS_Pr->SiS_HT = PALHT; 3690 SiS_Pr->SiS_VT = PALVT; 3691 } 3692 3693 } 3694 3695 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3696 3697 SiS_Pr->SiS_RVBHCMAX = 1; 3698 SiS_Pr->SiS_RVBHCFACT = 1; 3699 3700 if(SiS_Pr->UseCustomMode) { 3701 3702 SiS_Pr->SiS_HDE = SiS_Pr->SiS_VGAHDE; 3703 SiS_Pr->SiS_VDE = SiS_Pr->SiS_VGAVDE; 3704 3705 tempax = SiS_Pr->CHTotal; 3706 if(modeflag & HalfDCLK) tempax <<= 1; 3707 SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax; 3708 SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal; 3709 3710 } else { 3711 3712 bool gotit = false; 3713 3714 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 3715 3716 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3717 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3718 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3719 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3720 gotit = true; 3721 3722 } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) { 3723 3724 #ifdef CONFIG_FB_SIS_315 3725 SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr]; 3726 SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1]; 3727 SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8); 3728 SiS_Pr->SiS_VGAVT = (ROMAddr[romptr+4] << 4) | ((ROMAddr[romptr+3] & 0xf0) >> 4); 3729 SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8); 3730 SiS_Pr->SiS_VT = (ROMAddr[romptr+7] << 4) | ((ROMAddr[romptr+6] & 0xf0) >> 4); 3731 SiS_Pr->SiS_RVBHRS2 = ROMAddr[romptr+8] | ((ROMAddr[romptr+9] & 0x0f) << 8); 3732 if((SiS_Pr->SiS_RVBHRS2) && (modeflag & HalfDCLK)) { 3733 SiS_Pr->SiS_RVBHRS2 = ((SiS_Pr->SiS_RVBHRS2 + 3) >> 1) - 3; 3734 tempax = (ROMAddr[romptr+9] >> 4) & 0x07; 3735 if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax; 3736 else SiS_Pr->SiS_RVBHRS2 += tempax; 3737 } 3738 if(SiS_Pr->SiS_VGAHT) gotit = true; 3739 else { 3740 SiS_Pr->SiS_LCDInfo |= DontExpandLCD; 3741 SiS_Pr->SiS_LCDInfo &= ~LCDPass11; 3742 SiS_Pr->SiS_RVBHCMAX = 1; 3743 SiS_Pr->SiS_RVBHCFACT = 1; 3744 SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT; 3745 SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT; 3746 SiS_Pr->SiS_HT = SiS_Pr->PanelHT; 3747 SiS_Pr->SiS_VT = SiS_Pr->PanelVT; 3748 SiS_Pr->SiS_RVBHRS2 = 0; 3749 gotit = true; 3750 } 3751 #endif 3752 3753 } 3754 3755 if(!gotit) { 3756 3757 SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex, 3758 &CRT2Index,&ResIndex); 3759 3760 switch(CRT2Index) { 3761 case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3762 case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; 3763 case Panel_1280x720 : 3764 case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break; 3765 case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break; 3766 case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break; 3767 case Panel_1280x800 : 3768 case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break; 3769 case Panel_1280x800_2 : 3770 case Panel_1280x800_2+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x800_2Data; break; 3771 case Panel_1280x854 : 3772 case Panel_1280x854 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x854Data; break; 3773 case Panel_1280x960 : 3774 case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; 3775 case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; 3776 case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3777 case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; 3778 case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; 3779 case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; 3780 case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; 3781 case Panel_1680x1050 : 3782 case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break; 3783 case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break; 3784 #ifdef CONFIG_FB_SIS_315 3785 case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break; 3786 case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; 3787 #endif 3788 default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; 3789 } 3790 3791 SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX; 3792 SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT; 3793 SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT; 3794 SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT; 3795 SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT; 3796 SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT; 3797 3798 } 3799 3800 tempax = SiS_Pr->PanelXRes; 3801 tempbx = SiS_Pr->PanelYRes; 3802 3803 switch(SiS_Pr->SiS_LCDResInfo) { 3804 case Panel_1024x768: 3805 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 3806 if(SiS_Pr->ChipType < SIS_315H) { 3807 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3808 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3809 } 3810 } else { 3811 if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527; 3812 else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620; 3813 else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775; 3814 else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775; 3815 else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560; 3816 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640; 3817 } 3818 break; 3819 case Panel_1280x960: 3820 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700; 3821 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800; 3822 else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960; 3823 break; 3824 case Panel_1280x1024: 3825 if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768; 3826 else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800; 3827 else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864; 3828 break; 3829 case Panel_1600x1200: 3830 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 3831 if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875; 3832 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000; 3833 } 3834 break; 3835 } 3836 3837 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3838 tempax = SiS_Pr->SiS_VGAHDE; 3839 tempbx = SiS_Pr->SiS_VGAVDE; 3840 } 3841 3842 SiS_Pr->SiS_HDE = tempax; 3843 SiS_Pr->SiS_VDE = tempbx; 3844 } 3845 } 3846 } 3847 3848 static void 3849 SiS_GetCRT2Data(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3850 unsigned short RefreshRateTableIndex) 3851 { 3852 3853 if(SiS_Pr->SiS_VBType & VB_SISVB) { 3854 3855 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 3856 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3857 } else { 3858 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 3859 /* Need LVDS Data for LCD on 301B-DH */ 3860 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3861 } else { 3862 SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3863 } 3864 } 3865 3866 } else { 3867 3868 SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 3869 3870 } 3871 } 3872 3873 /*********************************************/ 3874 /* GET LVDS DES (SKEW) DATA */ 3875 /*********************************************/ 3876 3877 static const struct SiS_LVDSDes * 3878 SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr) 3879 { 3880 const struct SiS_LVDSDes *PanelDesPtr = NULL; 3881 3882 #ifdef CONFIG_FB_SIS_300 3883 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3884 3885 if(SiS_Pr->ChipType < SIS_315H) { 3886 if(SiS_Pr->SiS_LCDTypeInfo == 4) { 3887 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 3888 PanelDesPtr = SiS_Pr->SiS_PanelType04_1a; 3889 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3890 PanelDesPtr = SiS_Pr->SiS_PanelType04_2a; 3891 } 3892 } else if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 3893 PanelDesPtr = SiS_Pr->SiS_PanelType04_1b; 3894 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3895 PanelDesPtr = SiS_Pr->SiS_PanelType04_2b; 3896 } 3897 } 3898 } 3899 } 3900 } 3901 #endif 3902 return PanelDesPtr; 3903 } 3904 3905 static void 3906 SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 3907 unsigned short RefreshRateTableIndex) 3908 { 3909 unsigned short modeflag, ResIndex; 3910 const struct SiS_LVDSDes *PanelDesPtr = NULL; 3911 3912 SiS_Pr->SiS_LCDHDES = 0; 3913 SiS_Pr->SiS_LCDVDES = 0; 3914 3915 /* Some special cases */ 3916 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 3917 3918 /* Trumpion */ 3919 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 3920 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3921 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3922 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3923 } 3924 } 3925 return; 3926 } 3927 3928 /* 640x480 on LVDS */ 3929 if(SiS_Pr->ChipType < SIS_315H) { 3930 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480 && SiS_Pr->SiS_LCDTypeInfo == 3) { 3931 SiS_Pr->SiS_LCDHDES = 8; 3932 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512; 3933 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436; 3934 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440; 3935 return; 3936 } 3937 } 3938 3939 } /* LCD */ 3940 3941 if( (SiS_Pr->UseCustomMode) || 3942 (SiS_Pr->SiS_LCDResInfo == Panel_Custom) || 3943 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 3944 (SiS_Pr->SiS_CustomT == CUT_PANEL856) || 3945 (SiS_Pr->SiS_LCDInfo & LCDPass11) ) { 3946 return; 3947 } 3948 3949 if(ModeNo <= 0x13) ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 3950 else ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 3951 3952 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 3953 3954 #ifdef CONFIG_FB_SIS_315 3955 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 3956 /* non-pass 1:1 only, see above */ 3957 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { 3958 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2); 3959 } 3960 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) { 3961 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2); 3962 } 3963 } 3964 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 3965 switch(SiS_Pr->SiS_CustomT) { 3966 case CUT_UNIWILL1024: 3967 case CUT_UNIWILL10242: 3968 case CUT_CLEVO1400: 3969 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 3970 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3971 } 3972 break; 3973 } 3974 switch(SiS_Pr->SiS_LCDResInfo) { 3975 case Panel_1280x1024: 3976 if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) { 3977 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3978 } 3979 break; 3980 case Panel_1280x800: /* Verified for Averatec 6240 */ 3981 case Panel_1280x800_2: /* Verified for Asus A4L */ 3982 case Panel_1280x854: /* Not verified yet FIXME */ 3983 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 3984 break; 3985 } 3986 } 3987 #endif 3988 3989 } else { 3990 3991 if((SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 3992 3993 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) { 3994 if(ResIndex <= 3) SiS_Pr->SiS_LCDHDES = 256; 3995 } 3996 3997 } else if((PanelDesPtr = SiS_GetLVDSDesPtr(SiS_Pr))) { 3998 3999 SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES; 4000 SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES; 4001 4002 } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 4003 4004 if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) { 4005 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2); 4006 } 4007 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) { 4008 SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2); 4009 } else { 4010 if(SiS_Pr->ChipType < SIS_315H) { 4011 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4012 } else { 4013 switch(SiS_Pr->SiS_LCDResInfo) { 4014 case Panel_800x600: 4015 case Panel_1024x768: 4016 case Panel_1280x1024: 4017 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT; 4018 break; 4019 case Panel_1400x1050: 4020 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4021 break; 4022 } 4023 } 4024 } 4025 4026 } else { 4027 4028 if(SiS_Pr->ChipType < SIS_315H) { 4029 #ifdef CONFIG_FB_SIS_300 4030 switch(SiS_Pr->SiS_LCDResInfo) { 4031 case Panel_800x600: 4032 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 4033 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4034 } else { 4035 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT + 3; 4036 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT; 4037 if(SiS_Pr->SiS_VGAVDE == 400) SiS_Pr->SiS_LCDVDES -= 2; 4038 else SiS_Pr->SiS_LCDVDES -= 4; 4039 } 4040 break; 4041 case Panel_1024x768: 4042 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 4043 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4044 } else { 4045 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1; 4046 if(SiS_Pr->SiS_VGAVDE <= 400) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 8; 4047 if(SiS_Pr->SiS_VGAVDE <= 350) SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 12; 4048 } 4049 break; 4050 case Panel_1024x600: 4051 default: 4052 if( (SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) && 4053 (SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) ) { 4054 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4055 } else { 4056 SiS_Pr->SiS_LCDHDES = SiS_Pr->PanelHT - 1; 4057 } 4058 break; 4059 } 4060 4061 switch(SiS_Pr->SiS_LCDTypeInfo) { 4062 case 1: 4063 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; 4064 break; 4065 case 3: /* 640x480 only? */ 4066 SiS_Pr->SiS_LCDHDES = 8; 4067 if (SiS_Pr->SiS_VGAVDE >= 480) SiS_Pr->SiS_LCDVDES = 512; 4068 else if(SiS_Pr->SiS_VGAVDE >= 400) SiS_Pr->SiS_LCDVDES = 436; 4069 else if(SiS_Pr->SiS_VGAVDE >= 350) SiS_Pr->SiS_LCDVDES = 440; 4070 break; 4071 } 4072 #endif 4073 } else { 4074 #ifdef CONFIG_FB_SIS_315 4075 switch(SiS_Pr->SiS_LCDResInfo) { 4076 case Panel_1024x768: 4077 case Panel_1280x1024: 4078 if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) { 4079 SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1; 4080 } 4081 break; 4082 case Panel_320x240_1: 4083 case Panel_320x240_2: 4084 case Panel_320x240_3: 4085 SiS_Pr->SiS_LCDVDES = 524; 4086 break; 4087 } 4088 #endif 4089 } 4090 } 4091 4092 if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { 4093 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 4094 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 4095 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632; 4096 } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) { 4097 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) { 4098 if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) { 4099 if(SiS_Pr->ChipType < SIS_315H) { 4100 if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320; 4101 } else { 4102 #ifdef CONFIG_FB_SIS_315 4103 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480; 4104 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804; 4105 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704; 4106 if(!(modeflag & HalfDCLK)) { 4107 SiS_Pr->SiS_LCDHDES = 320; 4108 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632; 4109 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542; 4110 } 4111 #endif 4112 } 4113 } 4114 } 4115 } 4116 } 4117 } 4118 } 4119 4120 /*********************************************/ 4121 /* DISABLE VIDEO BRIDGE */ 4122 /*********************************************/ 4123 4124 #ifdef CONFIG_FB_SIS_315 4125 static int 4126 SiS_HandlePWD(struct SiS_Private *SiS_Pr) 4127 { 4128 int ret = 0; 4129 #ifdef SET_PWD 4130 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 4131 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr); 4132 unsigned char drivermode = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40; 4133 unsigned short temp; 4134 4135 if( (SiS_Pr->SiS_VBType & VB_SISPWD) && 4136 (romptr) && 4137 (SiS_Pr->SiS_PWDOffset) ) { 4138 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2b,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 0]); 4139 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2c,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 1]); 4140 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2d,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 2]); 4141 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2e,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 3]); 4142 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2f,ROMAddr[romptr + SiS_Pr->SiS_PWDOffset + 4]); 4143 temp = 0x00; 4144 if((ROMAddr[romptr + 2] & (0x06 << 1)) && !drivermode) { 4145 temp = 0x80; 4146 ret = 1; 4147 } 4148 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp); 4149 } 4150 #endif 4151 return ret; 4152 } 4153 #endif 4154 4155 /* NEVER use any variables (VBInfo), this will be called 4156 * from outside the context of modeswitch! 4157 * MUST call getVBType before calling this 4158 */ 4159 void 4160 SiS_DisableBridge(struct SiS_Private *SiS_Pr) 4161 { 4162 #ifdef CONFIG_FB_SIS_315 4163 unsigned short tempah, pushax=0, modenum; 4164 #endif 4165 unsigned short temp=0; 4166 4167 if(SiS_Pr->SiS_VBType & VB_SISVB) { 4168 4169 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ===== For 30xB/C/LV ===== */ 4170 4171 if(SiS_Pr->ChipType < SIS_315H) { 4172 4173 #ifdef CONFIG_FB_SIS_300 /* 300 series */ 4174 4175 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4176 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4177 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 4178 } else { 4179 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4180 } 4181 SiS_PanelDelay(SiS_Pr, 3); 4182 } 4183 if(SiS_Is301B(SiS_Pr)) { 4184 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f); 4185 SiS_ShortDelay(SiS_Pr,1); 4186 } 4187 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); 4188 SiS_DisplayOff(SiS_Pr); 4189 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4190 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4191 SiS_UnLockCRT2(SiS_Pr); 4192 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) { 4193 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 4194 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 4195 } 4196 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4197 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4198 SiS_PanelDelay(SiS_Pr, 2); 4199 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4200 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 4201 } else { 4202 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4203 } 4204 } 4205 4206 #endif /* CONFIG_FB_SIS_300 */ 4207 4208 } else { 4209 4210 #ifdef CONFIG_FB_SIS_315 /* 315 series */ 4211 4212 int didpwd = 0; 4213 bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) || 4214 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400); 4215 4216 modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f; 4217 4218 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4219 4220 #ifdef SET_EMI 4221 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4222 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 4223 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4224 } 4225 } 4226 #endif 4227 4228 didpwd = SiS_HandlePWD(SiS_Pr); 4229 4230 if( (modenum <= 0x13) || 4231 (SiS_IsVAMode(SiS_Pr)) || 4232 (!(SiS_IsDualEdge(SiS_Pr))) ) { 4233 if(!didpwd) { 4234 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfe); 4235 if(custom1) SiS_PanelDelay(SiS_Pr, 3); 4236 } else { 4237 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xfc); 4238 } 4239 } 4240 4241 if(!custom1) { 4242 SiS_DDC2Delay(SiS_Pr,0xff00); 4243 SiS_DDC2Delay(SiS_Pr,0xe000); 4244 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 4245 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06); 4246 if(IS_SIS740) { 4247 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4248 } 4249 SiS_PanelDelay(SiS_Pr, 3); 4250 } 4251 4252 } 4253 4254 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4255 /* if(SiS_Pr->ChipType < SIS_340) {*/ 4256 tempah = 0xef; 4257 if(SiS_IsVAMode(SiS_Pr)) tempah = 0xf7; 4258 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4259 /*}*/ 4260 } 4261 4262 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4263 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10); 4264 } 4265 4266 tempah = 0x3f; 4267 if(SiS_IsDualEdge(SiS_Pr)) { 4268 tempah = 0x7f; 4269 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0xbf; 4270 } 4271 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4272 4273 if((SiS_IsVAMode(SiS_Pr)) || 4274 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) { 4275 4276 SiS_DisplayOff(SiS_Pr); 4277 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4278 SiS_PanelDelay(SiS_Pr, 2); 4279 } 4280 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4281 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF); 4282 4283 } 4284 4285 if((!(SiS_IsVAMode(SiS_Pr))) || 4286 ((SiS_Pr->SiS_VBType & VB_SISLVDS) && (modenum <= 0x13))) { 4287 4288 if(!(SiS_IsDualEdge(SiS_Pr))) { 4289 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf); 4290 SiS_DisplayOff(SiS_Pr); 4291 } 4292 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4293 4294 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4295 SiS_PanelDelay(SiS_Pr, 2); 4296 } 4297 4298 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4299 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4300 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4301 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4302 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4303 4304 } 4305 4306 if(SiS_IsNotM650orLater(SiS_Pr)) { 4307 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4308 } 4309 4310 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4311 4312 if( (!(SiS_IsVAMode(SiS_Pr))) && 4313 (!(SiS_CRT2IsLCD(SiS_Pr))) && 4314 (!(SiS_IsDualEdge(SiS_Pr))) ) { 4315 4316 if(custom1) SiS_PanelDelay(SiS_Pr, 2); 4317 if(!didpwd) { 4318 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD); 4319 } 4320 if(custom1) SiS_PanelDelay(SiS_Pr, 4); 4321 } 4322 4323 if(!custom1) { 4324 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax); 4325 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4326 if(SiS_IsVAorLCD(SiS_Pr)) { 4327 SiS_PanelDelayLoop(SiS_Pr, 3, 20); 4328 } 4329 } 4330 } 4331 4332 } 4333 4334 #endif /* CONFIG_FB_SIS_315 */ 4335 4336 } 4337 4338 } else { /* ============ For 301 ================ */ 4339 4340 if(SiS_Pr->ChipType < SIS_315H) { 4341 #ifdef CONFIG_FB_SIS_300 4342 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4343 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4344 SiS_PanelDelay(SiS_Pr, 3); 4345 } 4346 #endif 4347 } 4348 4349 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */ 4350 SiS_DisplayOff(SiS_Pr); 4351 4352 if(SiS_Pr->ChipType >= SIS_315H) { 4353 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4354 } 4355 4356 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); /* disable lock mode */ 4357 4358 if(SiS_Pr->ChipType >= SIS_315H) { 4359 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 4360 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10); 4361 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4362 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp); 4363 } else { 4364 #ifdef CONFIG_FB_SIS_300 4365 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */ 4366 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4367 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4368 SiS_PanelDelay(SiS_Pr, 2); 4369 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4370 } 4371 #endif 4372 } 4373 4374 } 4375 4376 } else { /* ============ For LVDS =============*/ 4377 4378 if(SiS_Pr->ChipType < SIS_315H) { 4379 4380 #ifdef CONFIG_FB_SIS_300 /* 300 series */ 4381 4382 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 4383 SiS_SetCH700x(SiS_Pr,0x0E,0x09); 4384 } 4385 4386 if(SiS_Pr->ChipType == SIS_730) { 4387 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4388 SiS_WaitVBRetrace(SiS_Pr); 4389 } 4390 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4391 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4392 SiS_PanelDelay(SiS_Pr, 3); 4393 } 4394 } else { 4395 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) { 4396 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4397 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4398 SiS_WaitVBRetrace(SiS_Pr); 4399 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) { 4400 SiS_DisplayOff(SiS_Pr); 4401 } 4402 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4403 SiS_PanelDelay(SiS_Pr, 3); 4404 } 4405 } 4406 } 4407 } 4408 4409 SiS_DisplayOff(SiS_Pr); 4410 4411 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4412 4413 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4414 SiS_UnLockCRT2(SiS_Pr); 4415 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); 4416 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 4417 4418 if( (!(SiS_CRT2IsLCD(SiS_Pr))) || 4419 (!(SiS_CR36BIOSWord23d(SiS_Pr))) ) { 4420 SiS_PanelDelay(SiS_Pr, 2); 4421 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4422 } 4423 4424 #endif /* CONFIG_FB_SIS_300 */ 4425 4426 } else { 4427 4428 #ifdef CONFIG_FB_SIS_315 /* 315 series */ 4429 4430 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4431 /*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */ 4432 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18); 4433 /* } */ 4434 } 4435 4436 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4437 4438 if(SiS_Pr->ChipType == SIS_740) { 4439 temp = SiS_GetCH701x(SiS_Pr,0x61); 4440 if(temp < 1) { 4441 SiS_SetCH701x(SiS_Pr,0x76,0xac); 4442 SiS_SetCH701x(SiS_Pr,0x66,0x00); 4443 } 4444 4445 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4446 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) { 4447 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 4448 } 4449 } 4450 4451 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4452 (SiS_IsVAMode(SiS_Pr)) ) { 4453 SiS_Chrontel701xBLOff(SiS_Pr); 4454 SiS_Chrontel701xOff(SiS_Pr); 4455 } 4456 4457 if(SiS_Pr->ChipType != SIS_740) { 4458 if( (!(SiS_IsDualEdge(SiS_Pr))) || 4459 (SiS_IsTVOrYPbPrOrScart(SiS_Pr)) ) { 4460 SiS_SetCH701x(SiS_Pr,0x49,0x01); 4461 } 4462 } 4463 4464 } 4465 4466 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4467 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08); 4468 SiS_PanelDelay(SiS_Pr, 3); 4469 } 4470 4471 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4472 (!(SiS_IsDualEdge(SiS_Pr))) || 4473 (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr))) ) { 4474 SiS_DisplayOff(SiS_Pr); 4475 } 4476 4477 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4478 (!(SiS_IsDualEdge(SiS_Pr))) || 4479 (!(SiS_IsVAMode(SiS_Pr))) ) { 4480 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80); 4481 } 4482 4483 if(SiS_Pr->ChipType == SIS_740) { 4484 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4485 } 4486 4487 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF); 4488 4489 if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4490 (!(SiS_IsDualEdge(SiS_Pr))) || 4491 (!(SiS_IsVAMode(SiS_Pr))) ) { 4492 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); 4493 } 4494 4495 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4496 if(SiS_CRT2IsLCD(SiS_Pr)) { 4497 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4498 if(SiS_Pr->ChipType == SIS_550) { 4499 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf); 4500 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef); 4501 } 4502 } 4503 } else { 4504 if(SiS_Pr->ChipType == SIS_740) { 4505 if(SiS_IsLCDOrLCDA(SiS_Pr)) { 4506 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4507 } 4508 } else if(SiS_IsVAMode(SiS_Pr)) { 4509 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf); 4510 } 4511 } 4512 4513 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 4514 if(SiS_IsDualEdge(SiS_Pr)) { 4515 /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */ 4516 } else { 4517 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb); 4518 } 4519 } 4520 4521 SiS_UnLockCRT2(SiS_Pr); 4522 4523 if(SiS_Pr->ChipType == SIS_550) { 4524 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/ 4525 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */ 4526 } else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0) || 4527 (!(SiS_IsDualEdge(SiS_Pr))) || 4528 (!(SiS_IsVAMode(SiS_Pr))) ) { 4529 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 4530 } 4531 4532 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 4533 if(SiS_CRT2IsLCD(SiS_Pr)) { 4534 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4535 SiS_PanelDelay(SiS_Pr, 2); 4536 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04); 4537 } 4538 } 4539 } 4540 4541 #endif /* CONFIG_FB_SIS_315 */ 4542 4543 } /* 315 series */ 4544 4545 } /* LVDS */ 4546 4547 } 4548 4549 /*********************************************/ 4550 /* ENABLE VIDEO BRIDGE */ 4551 /*********************************************/ 4552 4553 /* NEVER use any variables (VBInfo), this will be called 4554 * from outside the context of a mode switch! 4555 * MUST call getVBType before calling this 4556 */ 4557 static 4558 void 4559 SiS_EnableBridge(struct SiS_Private *SiS_Pr) 4560 { 4561 unsigned short temp=0, tempah; 4562 #ifdef CONFIG_FB_SIS_315 4563 unsigned short temp1, pushax=0; 4564 bool delaylong = false; 4565 #endif 4566 4567 if(SiS_Pr->SiS_VBType & VB_SISVB) { 4568 4569 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* ====== For 301B et al ====== */ 4570 4571 if(SiS_Pr->ChipType < SIS_315H) { 4572 4573 #ifdef CONFIG_FB_SIS_300 /* 300 series */ 4574 4575 if(SiS_CRT2IsLCD(SiS_Pr)) { 4576 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4577 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4578 } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { 4579 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4580 } 4581 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_NoLCD)) { 4582 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) { 4583 SiS_PanelDelay(SiS_Pr, 0); 4584 } 4585 } 4586 } 4587 4588 if((SiS_Pr->SiS_VBType & VB_NoLCD) && 4589 (SiS_CRT2IsLCD(SiS_Pr))) { 4590 4591 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */ 4592 SiS_DisplayOn(SiS_Pr); 4593 SiS_UnLockCRT2(SiS_Pr); 4594 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 4595 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4596 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 4597 } else { 4598 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 4599 } 4600 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 4601 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4602 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4603 SiS_PanelDelay(SiS_Pr, 1); 4604 } 4605 SiS_WaitVBRetrace(SiS_Pr); 4606 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4607 } 4608 } 4609 4610 } else { 4611 4612 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4613 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4614 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4615 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4616 } 4617 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4618 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 4619 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ 4620 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0); 4621 SiS_DisplayOn(SiS_Pr); 4622 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4623 if(SiS_CRT2IsLCD(SiS_Pr)) { 4624 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 4625 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 4626 SiS_PanelDelay(SiS_Pr, 1); 4627 } 4628 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 4629 } 4630 } 4631 } 4632 4633 } 4634 4635 4636 #endif /* CONFIG_FB_SIS_300 */ 4637 4638 } else { 4639 4640 #ifdef CONFIG_FB_SIS_315 /* 315 series */ 4641 4642 #ifdef SET_EMI 4643 unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0; 4644 int didpwd = 0; 4645 /* unsigned short emidelay=0; */ 4646 #endif 4647 4648 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4649 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef); 4650 #ifdef SET_EMI 4651 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4652 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4653 } 4654 #endif 4655 } 4656 4657 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 4658 /*if(SiS_Pr->ChipType < SIS_340) { */ 4659 tempah = 0x10; 4660 if(SiS_LCDAEnabled(SiS_Pr)) { 4661 if(SiS_TVEnabled(SiS_Pr)) tempah = 0x18; 4662 else tempah = 0x08; 4663 } 4664 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah); 4665 /*}*/ 4666 } 4667 4668 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4669 4670 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00); 4671 SiS_DisplayOff(SiS_Pr); 4672 pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06); 4673 if(IS_SIS740) { 4674 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3); 4675 } 4676 4677 didpwd = SiS_HandlePWD(SiS_Pr); 4678 4679 if(SiS_IsVAorLCD(SiS_Pr)) { 4680 if(!didpwd) { 4681 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 4682 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4683 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 4684 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4685 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4686 SiS_GenericDelay(SiS_Pr, 17664); 4687 } 4688 } 4689 } else { 4690 SiS_PanelDelayLoop(SiS_Pr, 3, 2); 4691 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4692 SiS_GenericDelay(SiS_Pr, 17664); 4693 } 4694 } 4695 } 4696 4697 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) { 4698 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4699 delaylong = true; 4700 } 4701 4702 } 4703 4704 if(!(SiS_IsVAMode(SiS_Pr))) { 4705 4706 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; 4707 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4708 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4709 if(!(tempah & SetCRT2ToRAMDAC)) { 4710 if(!(SiS_LCDAEnabled(SiS_Pr))) temp |= 0x20; 4711 } 4712 } 4713 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4714 4715 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4716 4717 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 4718 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4719 4720 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4721 SiS_PanelDelay(SiS_Pr, 2); 4722 } 4723 4724 } else { 4725 4726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20); 4727 4728 } 4729 4730 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20); 4731 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4732 4733 if(SiS_Pr->SiS_VBType & VB_SISPOWER) { 4734 if( (SiS_LCDAEnabled(SiS_Pr)) || 4735 (SiS_CRT2IsLCD(SiS_Pr)) ) { 4736 /* Enable "LVDS PLL power on" (even on 301C) */ 4737 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f); 4738 /* Enable "LVDS Driver Power on" (even on 301C) */ 4739 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x7f); 4740 } 4741 } 4742 4743 tempah = 0xc0; 4744 if(SiS_IsDualEdge(SiS_Pr)) { 4745 tempah = 0x80; 4746 if(!(SiS_IsVAMode(SiS_Pr))) tempah = 0x40; 4747 } 4748 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah); 4749 4750 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 4751 4752 SiS_PanelDelay(SiS_Pr, 2); 4753 4754 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10); 4755 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80); 4756 4757 if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) { 4758 #ifdef SET_EMI 4759 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4760 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 4761 SiS_GenericDelay(SiS_Pr, 2048); 4762 } 4763 #endif 4764 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c); 4765 4766 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4767 #ifdef SET_EMI 4768 cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36); 4769 4770 if(SiS_Pr->SiS_ROMNew) { 4771 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 4772 unsigned short romptr = GetLCDStructPtr661_2(SiS_Pr); 4773 if(romptr) { 4774 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4775 SiS_Pr->EMI_30 = 0; 4776 SiS_Pr->EMI_31 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 0]; 4777 SiS_Pr->EMI_32 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 1]; 4778 SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2]; 4779 if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40; 4780 /* emidelay = SISGETROMW((romptr + 0x22)); */ 4781 SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true; 4782 } 4783 } 4784 4785 /* (P4_30|0x40) */ 4786 /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */ 4787 /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */ 4788 /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */ 4789 /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */ 4790 /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */ 4791 /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */ 4792 /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */ 4793 /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */ 4794 /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */ 4795 4796 if(SiS_Pr->HaveEMI) { 4797 r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31; 4798 r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33; 4799 } else { 4800 r30 = 0; 4801 } 4802 4803 /* EMI_30 is read at driver start; however, the BIOS sets this 4804 * (if it is used) only if the LCD is in use. In case we caught 4805 * the machine while on TV output, this bit is not set and we 4806 * don't know if it should be set - hence our detection is wrong. 4807 * Work-around this here: 4808 */ 4809 4810 if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) { 4811 switch((cr36 & 0x0f)) { 4812 case 2: 4813 r30 |= 0x40; 4814 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40; 4815 if(!SiS_Pr->HaveEMI) { 4816 r31 = 0x05; r32 = 0x60; r33 = 0x33; 4817 if((cr36 & 0xf0) == 0x30) { 4818 r31 = 0x0d; r32 = 0x70; r33 = 0x40; 4819 } 4820 } 4821 break; 4822 case 3: /* 1280x1024 */ 4823 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40; 4824 if(!SiS_Pr->HaveEMI) { 4825 r31 = 0x12; r32 = 0xd0; r33 = 0x6b; 4826 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 4827 r31 = 0x0d; r32 = 0x70; r33 = 0x6b; 4828 } 4829 } 4830 break; 4831 case 9: /* 1400x1050 */ 4832 r30 |= 0x40; 4833 if(!SiS_Pr->HaveEMI) { 4834 r31 = 0x05; r32 = 0x60; r33 = 0x00; 4835 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) { 4836 r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */ 4837 } 4838 } 4839 break; 4840 case 11: /* 1600x1200 - unknown */ 4841 r30 |= 0x40; 4842 if(!SiS_Pr->HaveEMI) { 4843 r31 = 0x05; r32 = 0x60; r33 = 0x00; 4844 } 4845 } 4846 } 4847 4848 /* BIOS values don't work so well sometimes */ 4849 if(!SiS_Pr->OverruleEMI) { 4850 #ifdef COMPAL_HACK 4851 if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) { 4852 if((cr36 & 0x0f) == 0x09) { 4853 r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00; 4854 } 4855 } 4856 #endif 4857 #ifdef COMPAQ_HACK 4858 if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) { 4859 if((cr36 & 0x0f) == 0x03) { 4860 r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b; 4861 } 4862 } 4863 #endif 4864 #ifdef ASUS_HACK 4865 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4866 if((cr36 & 0x0f) == 0x02) { 4867 /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */ 4868 /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */ 4869 /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */ 4870 /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */ 4871 } 4872 } 4873 #endif 4874 } 4875 4876 if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) { 4877 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20); /* Reset */ 4878 SiS_GenericDelay(SiS_Pr, 2048); 4879 } 4880 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31); 4881 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32); 4882 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33); 4883 #endif /* SET_EMI */ 4884 4885 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 4886 4887 #ifdef SET_EMI 4888 if( (SiS_LCDAEnabled(SiS_Pr)) || 4889 (SiS_CRT2IsLCD(SiS_Pr)) ) { 4890 if(r30 & 0x40) { 4891 /*SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x2a,0x80);*/ 4892 SiS_PanelDelayLoop(SiS_Pr, 3, 5); 4893 if(delaylong) { 4894 SiS_PanelDelayLoop(SiS_Pr, 3, 5); 4895 delaylong = false; 4896 } 4897 SiS_WaitVBRetrace(SiS_Pr); 4898 SiS_WaitVBRetrace(SiS_Pr); 4899 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 4900 SiS_GenericDelay(SiS_Pr, 1280); 4901 } 4902 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); /* Enable */ 4903 /*SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x2a,0x7f);*/ 4904 } 4905 } 4906 #endif 4907 } 4908 } 4909 4910 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4911 if(SiS_IsVAorLCD(SiS_Pr)) { 4912 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4913 if(delaylong) { 4914 SiS_PanelDelayLoop(SiS_Pr, 3, 10); 4915 } 4916 SiS_WaitVBRetrace(SiS_Pr); 4917 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 4918 SiS_GenericDelay(SiS_Pr, 2048); 4919 SiS_WaitVBRetrace(SiS_Pr); 4920 } 4921 if(!didpwd) { 4922 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 4923 } else { 4924 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x03); 4925 } 4926 } 4927 } 4928 4929 SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax); 4930 SiS_DisplayOn(SiS_Pr); 4931 SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff); 4932 4933 } 4934 4935 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 4936 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4937 } 4938 4939 #endif /* CONFIG_FB_SIS_315 */ 4940 4941 } 4942 4943 } else { /* ============ For 301 ================ */ 4944 4945 if(SiS_Pr->ChipType < SIS_315H) { 4946 if(SiS_CRT2IsLCD(SiS_Pr)) { 4947 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4948 SiS_PanelDelay(SiS_Pr, 0); 4949 } 4950 } 4951 4952 temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */ 4953 if(SiS_BridgeInSlavemode(SiS_Pr)) { 4954 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30); 4955 if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20; 4956 } 4957 SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp); 4958 4959 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */ 4960 4961 if(SiS_Pr->ChipType >= SIS_315H) { 4962 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 4963 if(!(temp & 0x80)) { 4964 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); /* BVBDOENABLE=1 */ 4965 } 4966 } 4967 4968 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */ 4969 4970 SiS_VBLongWait(SiS_Pr); 4971 SiS_DisplayOn(SiS_Pr); 4972 if(SiS_Pr->ChipType >= SIS_315H) { 4973 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 4974 } 4975 SiS_VBLongWait(SiS_Pr); 4976 4977 if(SiS_Pr->ChipType < SIS_315H) { 4978 if(SiS_CRT2IsLCD(SiS_Pr)) { 4979 SiS_PanelDelay(SiS_Pr, 1); 4980 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 4981 } 4982 } 4983 4984 } 4985 4986 } else { /* =================== For LVDS ================== */ 4987 4988 if(SiS_Pr->ChipType < SIS_315H) { 4989 4990 #ifdef CONFIG_FB_SIS_300 /* 300 series */ 4991 4992 if(SiS_CRT2IsLCD(SiS_Pr)) { 4993 if(SiS_Pr->ChipType == SIS_730) { 4994 SiS_PanelDelay(SiS_Pr, 1); 4995 SiS_PanelDelay(SiS_Pr, 1); 4996 SiS_PanelDelay(SiS_Pr, 1); 4997 } 4998 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 4999 if(!(SiS_CR36BIOSWord23d(SiS_Pr))) { 5000 SiS_PanelDelay(SiS_Pr, 0); 5001 } 5002 } 5003 5004 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 5005 SiS_DisplayOn(SiS_Pr); 5006 SiS_UnLockCRT2(SiS_Pr); 5007 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF); 5008 if(SiS_BridgeInSlavemode(SiS_Pr)) { 5009 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F); 5010 } else { 5011 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40); 5012 } 5013 5014 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 5015 if(!(SiS_CRT2IsLCD(SiS_Pr))) { 5016 SiS_WaitVBRetrace(SiS_Pr); 5017 SiS_SetCH700x(SiS_Pr,0x0E,0x0B); 5018 } 5019 } 5020 5021 if(SiS_CRT2IsLCD(SiS_Pr)) { 5022 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) { 5023 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) { 5024 if(!(SiS_CR36BIOSWord23b(SiS_Pr))) { 5025 SiS_PanelDelay(SiS_Pr, 1); 5026 SiS_PanelDelay(SiS_Pr, 1); 5027 } 5028 SiS_WaitVBRetrace(SiS_Pr); 5029 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 5030 } 5031 } 5032 } 5033 5034 #endif /* CONFIG_FB_SIS_300 */ 5035 5036 } else { 5037 5038 #ifdef CONFIG_FB_SIS_315 /* 315 series */ 5039 5040 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 5041 /*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */ 5042 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18); 5043 /*}*/ 5044 } 5045 5046 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 5047 if(SiS_CRT2IsLCD(SiS_Pr)) { 5048 SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x00); 5049 SiS_PanelDelay(SiS_Pr, 0); 5050 } 5051 } 5052 5053 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 5054 SiS_UnLockCRT2(SiS_Pr); 5055 5056 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7); 5057 5058 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5059 temp = SiS_GetCH701x(SiS_Pr,0x66); 5060 temp &= 0x20; 5061 SiS_Chrontel701xBLOff(SiS_Pr); 5062 } 5063 5064 if(SiS_Pr->ChipType != SIS_550) { 5065 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f); 5066 } 5067 5068 if(SiS_Pr->ChipType == SIS_740) { 5069 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5070 if(SiS_IsLCDOrLCDA(SiS_Pr)) { 5071 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 5072 } 5073 } 5074 } 5075 5076 temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E); 5077 if(!(temp1 & 0x80)) { 5078 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80); 5079 } 5080 5081 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5082 if(temp) { 5083 SiS_Chrontel701xBLOn(SiS_Pr); 5084 } 5085 } 5086 5087 if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 5088 if(SiS_CRT2IsLCD(SiS_Pr)) { 5089 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 5090 if(SiS_Pr->ChipType == SIS_550) { 5091 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40); 5092 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10); 5093 } 5094 } 5095 } else if(SiS_IsVAMode(SiS_Pr)) { 5096 if(SiS_Pr->ChipType != SIS_740) { 5097 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20); 5098 } 5099 } 5100 5101 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 5102 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f); 5103 } 5104 5105 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5106 if(SiS_IsTVOrYPbPrOrScart(SiS_Pr)) { 5107 SiS_Chrontel701xOn(SiS_Pr); 5108 } 5109 if( (SiS_IsVAMode(SiS_Pr)) || 5110 (SiS_IsLCDOrLCDA(SiS_Pr)) ) { 5111 SiS_ChrontelDoSomething1(SiS_Pr); 5112 } 5113 } 5114 5115 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 5116 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 5117 if( (SiS_IsVAMode(SiS_Pr)) || 5118 (SiS_IsLCDOrLCDA(SiS_Pr)) ) { 5119 SiS_Chrontel701xBLOn(SiS_Pr); 5120 SiS_ChrontelInitTVVSync(SiS_Pr); 5121 } 5122 } 5123 } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) { 5124 if(!(SiS_WeHaveBacklightCtrl(SiS_Pr))) { 5125 if(SiS_CRT2IsLCD(SiS_Pr)) { 5126 SiS_PanelDelay(SiS_Pr, 1); 5127 SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x00); 5128 } 5129 } 5130 } 5131 5132 #endif /* CONFIG_FB_SIS_315 */ 5133 5134 } /* 310 series */ 5135 5136 } /* LVDS */ 5137 5138 } 5139 5140 /*********************************************/ 5141 /* SET PART 1 REGISTER GROUP */ 5142 /*********************************************/ 5143 5144 /* Set CRT2 OFFSET / PITCH */ 5145 static void 5146 SiS_SetCRT2Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 5147 unsigned short RRTI) 5148 { 5149 unsigned short offset; 5150 unsigned char temp; 5151 5152 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return; 5153 5154 offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI); 5155 5156 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF)); 5157 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8)); 5158 5159 temp = (unsigned char)(((offset >> 3) & 0xFF) + 1); 5160 if(offset & 0x07) temp++; 5161 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp); 5162 } 5163 5164 /* Set CRT2 sync and PanelLink mode */ 5165 static void 5166 SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RefreshRateTableIndex) 5167 { 5168 unsigned short tempah=0, tempbl, infoflag; 5169 5170 tempbl = 0xC0; 5171 5172 if(SiS_Pr->UseCustomMode) { 5173 infoflag = SiS_Pr->CInfoFlag; 5174 } else { 5175 infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; 5176 } 5177 5178 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* LVDS */ 5179 5180 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5181 tempah = 0; 5182 } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) { 5183 tempah = SiS_Pr->SiS_LCDInfo; 5184 } else tempah = infoflag >> 8; 5185 tempah &= 0xC0; 5186 tempah |= 0x20; 5187 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5188 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5189 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 5190 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 5191 tempah |= 0xf0; 5192 } 5193 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 5194 (SiS_Pr->SiS_IF_DEF_DSTN) || 5195 (SiS_Pr->SiS_IF_DEF_TRUMPION) || 5196 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 5197 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) { 5198 tempah |= 0x30; 5199 } 5200 if( (SiS_Pr->SiS_IF_DEF_FSTN) || 5201 (SiS_Pr->SiS_IF_DEF_DSTN) ) { 5202 tempah &= ~0xc0; 5203 } 5204 } 5205 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5206 if(SiS_Pr->ChipType >= SIS_315H) { 5207 tempah >>= 3; 5208 tempah &= 0x18; 5209 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah); 5210 /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */ 5211 } else { 5212 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0); 5213 } 5214 } else { 5215 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5216 } 5217 5218 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5219 5220 if(SiS_Pr->ChipType < SIS_315H) { 5221 5222 #ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */ 5223 5224 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */ 5225 5226 tempah = infoflag >> 8; 5227 tempbl = 0; 5228 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5229 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5230 tempah = SiS_Pr->SiS_LCDInfo; 5231 tempbl = (tempah >> 6) & 0x03; 5232 } 5233 } 5234 tempah &= 0xC0; 5235 tempah |= 0x20; 5236 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5237 tempah |= 0xc0; 5238 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5239 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 5240 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5241 } 5242 5243 } else { /* 630 - 301 */ 5244 5245 tempah = ((infoflag >> 8) & 0xc0) | 0x20; 5246 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5247 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5248 5249 } 5250 5251 #endif /* CONFIG_FB_SIS_300 */ 5252 5253 } else { 5254 5255 #ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */ 5256 5257 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */ 5258 5259 tempbl = 0; 5260 if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) && 5261 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5262 tempah = infoflag >> 8; 5263 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5264 tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6); 5265 } 5266 } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) && 5267 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) { 5268 tempah = infoflag >> 8; 5269 tempbl = 0x03; 5270 } else { 5271 tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); 5272 tempbl = (tempah >> 6) & 0x03; 5273 tempbl |= 0x08; 5274 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04; 5275 } 5276 tempah &= 0xC0; 5277 tempah |= 0x20; 5278 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5279 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0; 5280 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5281 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 5282 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5283 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5284 } 5285 } 5286 5287 } else { /* 315 - TMDS */ 5288 5289 tempah = tempbl = infoflag >> 8; 5290 if(!SiS_Pr->UseCustomMode) { 5291 tempbl = 0; 5292 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5293 if(ModeNo <= 0x13) { 5294 tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5295 } 5296 } 5297 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5298 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5299 if(SiS_Pr->SiS_LCDInfo & LCDSync) { 5300 tempah = SiS_Pr->SiS_LCDInfo; 5301 tempbl = (tempah >> 6) & 0x03; 5302 } 5303 } 5304 } 5305 } 5306 tempah &= 0xC0; 5307 tempah |= 0x20; 5308 if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10; 5309 if(SiS_Pr->SiS_VBType & VB_NoLCD) { 5310 /* Imitate BIOS bug */ 5311 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0; 5312 } 5313 if((SiS_Pr->SiS_VBType & VB_SIS30xC) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) { 5314 tempah >>= 3; 5315 tempah &= 0x18; 5316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah); 5317 } else { 5318 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah); 5319 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 5320 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5321 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl); 5322 } 5323 } 5324 } 5325 5326 } 5327 #endif /* CONFIG_FB_SIS_315 */ 5328 } 5329 } 5330 } 5331 5332 /* Set CRT2 FIFO on 300/540/630/730 */ 5333 #ifdef CONFIG_FB_SIS_300 5334 static void 5335 SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo) 5336 { 5337 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 5338 unsigned short temp, index, modeidindex, refreshratetableindex; 5339 unsigned short VCLK = 0, MCLK, colorth = 0, data2 = 0; 5340 unsigned short tempbx, tempcl, CRT1ModeNo, CRT2ModeNo, SelectRate_backup; 5341 unsigned int data, pci50, pciA0; 5342 static const unsigned char colortharray[] = { 5343 1, 1, 2, 2, 3, 4 5344 }; 5345 5346 SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate; 5347 5348 if(!SiS_Pr->CRT1UsesCustomMode) { 5349 5350 CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */ 5351 SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex); 5352 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 5353 SiS_Pr->SiS_SelectCRT2Rate = 0; 5354 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex); 5355 5356 if(CRT1ModeNo >= 0x13) { 5357 /* Get VCLK */ 5358 index = SiS_GetRefCRTVCLK(SiS_Pr, refreshratetableindex, SiS_Pr->SiS_UseWide); 5359 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 5360 5361 /* Get colordepth */ 5362 colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex) >> 1; 5363 if(!colorth) colorth++; 5364 } 5365 5366 } else { 5367 5368 CRT1ModeNo = 0xfe; 5369 5370 /* Get VCLK */ 5371 VCLK = SiS_Pr->CSRClock_CRT1; 5372 5373 /* Get color depth */ 5374 colorth = colortharray[((SiS_Pr->CModeFlag_CRT1 & ModeTypeMask) - 2)]; 5375 5376 } 5377 5378 if(CRT1ModeNo >= 0x13) { 5379 /* Get MCLK */ 5380 if(SiS_Pr->ChipType == SIS_300) { 5381 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A); 5382 } else { 5383 index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A); 5384 } 5385 index &= 0x07; 5386 MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK; 5387 5388 temp = ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) >> 6) & 0x03) << 1; 5389 if(!temp) temp++; 5390 temp <<= 2; 5391 5392 data2 = temp - ((colorth * VCLK) / MCLK); 5393 5394 temp = (28 * 16) % data2; 5395 data2 = (28 * 16) / data2; 5396 if(temp) data2++; 5397 5398 if(SiS_Pr->ChipType == SIS_300) { 5399 5400 SiS_GetFIFOThresholdIndex300(SiS_Pr, &tempbx, &tempcl); 5401 data = SiS_GetFIFOThresholdB300(tempbx, tempcl); 5402 5403 } else { 5404 5405 pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50); 5406 pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0); 5407 5408 if(SiS_Pr->ChipType == SIS_730) { 5409 5410 index = (unsigned short)(((pciA0 >> 28) & 0x0f) * 3); 5411 index += (unsigned short)(((pci50 >> 9)) & 0x03); 5412 5413 /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */ 5414 index = 0; /* -- do it like the BIOS anyway... */ 5415 5416 } else { 5417 5418 pci50 >>= 24; 5419 pciA0 >>= 24; 5420 5421 index = (pci50 >> 1) & 0x07; 5422 5423 if(pci50 & 0x01) index += 6; 5424 if(!(pciA0 & 0x01)) index += 24; 5425 5426 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80) index += 12; 5427 5428 } 5429 5430 data = SiS_GetLatencyFactor630(SiS_Pr, index) + 15; 5431 if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x80)) data += 5; 5432 5433 } 5434 5435 data += data2; /* CRT1 Request Period */ 5436 5437 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5438 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; 5439 5440 if(!SiS_Pr->UseCustomMode) { 5441 5442 CRT2ModeNo = ModeNo; 5443 SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex); 5444 5445 refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex); 5446 5447 /* Get VCLK */ 5448 index = SiS_GetVCLK2Ptr(SiS_Pr, CRT2ModeNo, modeidindex, refreshratetableindex); 5449 VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; 5450 5451 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 5452 if(SiS_Pr->SiS_UseROM) { 5453 if(ROMAddr[0x220] & 0x01) { 5454 VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8); 5455 } 5456 } 5457 } 5458 5459 } else { 5460 5461 /* Get VCLK */ 5462 CRT2ModeNo = 0xfe; 5463 VCLK = SiS_Pr->CSRClock; 5464 5465 } 5466 5467 /* Get colordepth */ 5468 colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex) >> 1; 5469 if(!colorth) colorth++; 5470 5471 data = data * VCLK * colorth; 5472 temp = data % (MCLK << 4); 5473 data = data / (MCLK << 4); 5474 if(temp) data++; 5475 5476 if(data < 6) data = 6; 5477 else if(data > 0x14) data = 0x14; 5478 5479 if(SiS_Pr->ChipType == SIS_300) { 5480 temp = 0x16; 5481 if((data <= 0x0f) || (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) 5482 temp = 0x13; 5483 } else { 5484 temp = 0x16; 5485 if(( (SiS_Pr->ChipType == SIS_630) || 5486 (SiS_Pr->ChipType == SIS_730) ) && 5487 (SiS_Pr->ChipRevision >= 0x30)) 5488 temp = 0x1b; 5489 } 5490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp); 5491 5492 if((SiS_Pr->ChipType == SIS_630) && 5493 (SiS_Pr->ChipRevision >= 0x30)) { 5494 if(data > 0x13) data = 0x13; 5495 } 5496 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data); 5497 5498 } else { /* If mode <= 0x13, we just restore everything */ 5499 5500 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 5501 SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup; 5502 5503 } 5504 } 5505 #endif 5506 5507 /* Set CRT2 FIFO on 315/330 series */ 5508 #ifdef CONFIG_FB_SIS_315 5509 static void 5510 SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr) 5511 { 5512 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B); 5513 if( (SiS_Pr->ChipType == SIS_760) && 5514 (SiS_Pr->SiS_SysFlags & SF_760LFB) && 5515 (SiS_Pr->SiS_ModeType == Mode32Bpp) && 5516 (SiS_Pr->SiS_VGAHDE >= 1280) && 5517 (SiS_Pr->SiS_VGAVDE >= 1024) ) { 5518 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03); 5519 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b); 5520 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0); 5521 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01); 5522 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0); 5523 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e); 5524 } else { 5525 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04); 5526 } 5527 5528 } 5529 #endif 5530 5531 static unsigned short 5532 SiS_GetVGAHT2(struct SiS_Private *SiS_Pr) 5533 { 5534 unsigned int tempax,tempbx; 5535 5536 tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX; 5537 tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT; 5538 tempax = (tempax * SiS_Pr->SiS_HT) / tempbx; 5539 return (unsigned short)tempax; 5540 } 5541 5542 /* Set Part 1 / SiS bridge slave mode */ 5543 static void 5544 SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, 5545 unsigned short RefreshRateTableIndex) 5546 { 5547 unsigned short temp, modeflag, i, j, xres=0, VGAVDE; 5548 static const unsigned short CRTranslation[] = { 5549 /* CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7 */ 5550 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 5551 /* CR8 CR9 SR0A SR0B SR0C SR0D SR0E CR0F */ 5552 0x00, 0x0b, 0x17, 0x18, 0x19, 0x00, 0x1a, 0x00, 5553 /* CR10 CR11 CR12 CR13 CR14 CR15 CR16 CR17 */ 5554 0x0c, 0x0d, 0x0e, 0x00, 0x0f, 0x10, 0x11, 0x00 5555 }; 5556 5557 if(ModeNo <= 0x13) { 5558 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 5559 } else if(SiS_Pr->UseCustomMode) { 5560 modeflag = SiS_Pr->CModeFlag; 5561 xres = SiS_Pr->CHDisplay; 5562 } else { 5563 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5564 xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes; 5565 } 5566 5567 /* The following is only done if bridge is in slave mode: */ 5568 5569 if(SiS_Pr->ChipType >= SIS_315H) { 5570 if(xres >= 1600) { /* BIOS: == 1600 */ 5571 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04); 5572 } 5573 } 5574 5575 SiS_Pr->CHTotal = 8224; /* Max HT, 0x2020, results in 0x3ff in registers */ 5576 5577 SiS_Pr->CHDisplay = SiS_Pr->SiS_VGAHDE; 5578 if(modeflag & HalfDCLK) SiS_Pr->CHDisplay >>= 1; 5579 5580 SiS_Pr->CHBlankStart = SiS_Pr->CHDisplay; 5581 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 5582 SiS_Pr->CHBlankStart += 16; 5583 } 5584 5585 SiS_Pr->CHBlankEnd = 32; 5586 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 5587 if(xres == 1600) SiS_Pr->CHBlankEnd += 80; 5588 } 5589 5590 temp = SiS_Pr->SiS_VGAHT - 96; 5591 if(!(modeflag & HalfDCLK)) temp -= 32; 5592 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 5593 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x04); 5594 temp |= ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x0b) & 0xc0) << 2); 5595 temp -= 3; 5596 temp <<= 3; 5597 } else { 5598 if(SiS_Pr->SiS_RVBHRS2) temp = SiS_Pr->SiS_RVBHRS2; 5599 } 5600 SiS_Pr->CHSyncStart = temp; 5601 5602 SiS_Pr->CHSyncEnd = 0xffe8; /* results in 0x2000 in registers */ 5603 5604 SiS_Pr->CVTotal = 2049; /* Max VT, 0x0801, results in 0x7ff in registers */ 5605 5606 VGAVDE = SiS_Pr->SiS_VGAVDE; 5607 if (VGAVDE == 357) VGAVDE = 350; 5608 else if(VGAVDE == 360) VGAVDE = 350; 5609 else if(VGAVDE == 375) VGAVDE = 350; 5610 else if(VGAVDE == 405) VGAVDE = 400; 5611 else if(VGAVDE == 420) VGAVDE = 400; 5612 else if(VGAVDE == 525) VGAVDE = 480; 5613 else if(VGAVDE == 1056) VGAVDE = 1024; 5614 SiS_Pr->CVDisplay = VGAVDE; 5615 5616 SiS_Pr->CVBlankStart = SiS_Pr->CVDisplay; 5617 5618 SiS_Pr->CVBlankEnd = 1; 5619 if(ModeNo == 0x3c) SiS_Pr->CVBlankEnd = 226; 5620 5621 temp = (SiS_Pr->SiS_VGAVT - VGAVDE) >> 1; 5622 SiS_Pr->CVSyncStart = VGAVDE + temp; 5623 5624 temp >>= 3; 5625 SiS_Pr->CVSyncEnd = SiS_Pr->CVSyncStart + temp; 5626 5627 SiS_CalcCRRegisters(SiS_Pr, 0); 5628 SiS_Pr->CCRT1CRTC[16] &= ~0xE0; 5629 5630 for(i = 0; i <= 7; i++) { 5631 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[i]); 5632 } 5633 for(i = 0x10, j = 8; i <= 0x12; i++, j++) { 5634 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5635 } 5636 for(i = 0x15, j = 11; i <= 0x16; i++, j++) { 5637 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5638 } 5639 for(i = 0x0a, j = 13; i <= 0x0c; i++, j++) { 5640 SiS_SetReg(SiS_Pr->SiS_Part1Port,CRTranslation[i],SiS_Pr->CCRT1CRTC[j]); 5641 } 5642 5643 temp = SiS_Pr->CCRT1CRTC[16] & 0xE0; 5644 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x0E],0x1F,temp); 5645 5646 temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5; 5647 if(modeflag & DoubleScanMode) temp |= 0x80; 5648 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,CRTranslation[0x09],0x5F,temp); 5649 5650 temp = 0; 5651 temp |= (SiS_GetReg(SiS_Pr->SiS_P3c4,0x01) & 0x01); 5652 if(modeflag & HalfDCLK) temp |= 0x08; 5653 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* SR01: HalfDCLK[3], 8/9 div dotclock[0] */ 5654 5655 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00); /* CR14: (text mode: underline location) */ 5656 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00); /* CR17: n/a */ 5657 5658 temp = 0; 5659 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5660 temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) << 7; 5661 } 5662 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* SR0E, dither[7] */ 5663 5664 temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)); 5665 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */ 5666 } 5667 5668 /* Setup panel link 5669 * This is used for LVDS, LCDA and Chrontel TV output 5670 * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA 5671 */ 5672 static void 5673 SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 5674 unsigned short RefreshRateTableIndex) 5675 { 5676 unsigned short modeflag, resinfo = 0; 5677 unsigned short push2, tempax, tempbx, tempcx, temp; 5678 unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0; 5679 bool islvds = false, issis = false, chkdclkfirst = false; 5680 #ifdef CONFIG_FB_SIS_300 5681 unsigned short crt2crtc = 0; 5682 #endif 5683 #ifdef CONFIG_FB_SIS_315 5684 unsigned short pushcx; 5685 #endif 5686 5687 if(ModeNo <= 0x13) { 5688 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 5689 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 5690 #ifdef CONFIG_FB_SIS_300 5691 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 5692 #endif 5693 } else if(SiS_Pr->UseCustomMode) { 5694 modeflag = SiS_Pr->CModeFlag; 5695 } else { 5696 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 5697 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 5698 #ifdef CONFIG_FB_SIS_300 5699 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 5700 #endif 5701 } 5702 5703 /* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */ 5704 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) { 5705 islvds = true; 5706 } 5707 5708 /* is really sis if sis bridge, but not 301B-DH */ 5709 if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) { 5710 issis = true; 5711 } 5712 5713 if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) { 5714 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) { 5715 chkdclkfirst = true; 5716 } 5717 } 5718 5719 #ifdef CONFIG_FB_SIS_315 5720 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 5721 if(IS_SIS330) { 5722 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); 5723 } else if(IS_SIS740) { 5724 if(islvds) { 5725 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); 5726 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03); 5727 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5728 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); 5729 } 5730 } else { 5731 if(islvds) { 5732 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); 5733 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00); 5734 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 5735 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f); 5736 if(SiS_Pr->SiS_VBType & VB_SIS30xC) { 5737 if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) || 5738 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 5739 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20); 5740 } 5741 } 5742 } 5743 } 5744 } 5745 #endif 5746 5747 /* Horizontal */ 5748 5749 tempax = SiS_Pr->SiS_LCDHDES; 5750 if(islvds) { 5751 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5752 if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) { 5753 if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) && 5754 (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) { 5755 tempax -= 8; 5756 } 5757 } 5758 } 5759 } 5760 5761 temp = (tempax & 0x0007); 5762 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */ 5763 temp = (tempax >> 3) & 0x00FF; 5764 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */ 5765 5766 tempbx = SiS_Pr->SiS_HDE; 5767 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5768 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5769 tempbx = SiS_Pr->PanelXRes; 5770 } 5771 if((SiS_Pr->SiS_LCDResInfo == Panel_320x240_1) || 5772 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_2) || 5773 (SiS_Pr->SiS_LCDResInfo == Panel_320x240_3)) { 5774 tempbx >>= 1; 5775 } 5776 } 5777 5778 tempax += tempbx; 5779 if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT; 5780 5781 temp = tempax; 5782 if(temp & 0x07) temp += 8; 5783 temp >>= 3; 5784 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */ 5785 5786 tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2; 5787 5788 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5789 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5790 if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS; 5791 } 5792 } 5793 5794 tempcx += tempax; 5795 if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT; 5796 5797 temp = (tempcx >> 3) & 0x00FF; 5798 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5799 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5800 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5801 switch(ModeNo) { 5802 case 0x04: 5803 case 0x05: 5804 case 0x0d: temp = 0x56; break; 5805 case 0x10: temp = 0x60; break; 5806 case 0x13: temp = 0x5f; break; 5807 case 0x40: 5808 case 0x41: 5809 case 0x4f: 5810 case 0x43: 5811 case 0x44: 5812 case 0x62: 5813 case 0x56: 5814 case 0x53: 5815 case 0x5d: 5816 case 0x5e: temp = 0x54; break; 5817 } 5818 } 5819 } 5820 } 5821 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */ 5822 5823 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5824 temp += 2; 5825 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5826 temp += 8; 5827 if(SiS_Pr->PanelHRE != 999) { 5828 temp = tempcx + SiS_Pr->PanelHRE; 5829 if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT; 5830 temp >>= 3; 5831 } 5832 } 5833 } else { 5834 temp += 10; 5835 } 5836 5837 temp &= 0x1F; 5838 temp |= ((tempcx & 0x07) << 5); 5839 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */ 5840 5841 /* Vertical */ 5842 5843 tempax = SiS_Pr->SiS_VGAVDE; 5844 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5845 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5846 tempax = SiS_Pr->PanelYRes; 5847 } 5848 } 5849 5850 tempbx = SiS_Pr->SiS_LCDVDES + tempax; 5851 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; 5852 5853 push2 = tempbx; 5854 5855 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; 5856 if(SiS_Pr->ChipType < SIS_315H) { 5857 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5858 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5859 tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes; 5860 } 5861 } 5862 } 5863 if(islvds) tempcx >>= 1; 5864 else tempcx >>= 2; 5865 5866 if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && 5867 (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) && 5868 (SiS_Pr->PanelVRS != 999) ) { 5869 tempcx = SiS_Pr->PanelVRS; 5870 tempbx += tempcx; 5871 if(issis) tempbx++; 5872 } else { 5873 tempbx += tempcx; 5874 if(SiS_Pr->ChipType < SIS_315H) tempbx++; 5875 else if(issis) tempbx++; 5876 } 5877 5878 if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; 5879 5880 temp = tempbx & 0x00FF; 5881 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 5882 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 5883 if(ModeNo == 0x10) temp = 0xa9; 5884 } 5885 } 5886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* BPLVRS */ 5887 5888 tempcx >>= 3; 5889 tempcx++; 5890 5891 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5892 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 5893 if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE; 5894 } 5895 } 5896 5897 tempcx += tempbx; 5898 temp = tempcx & 0x000F; 5899 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */ 5900 5901 temp = ((tempbx >> 8) & 0x07) << 3; 5902 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { 5903 if(SiS_Pr->SiS_HDE != 640) { 5904 if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; 5905 } 5906 } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40; 5907 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40; 5908 tempbx = 0x87; 5909 if((SiS_Pr->ChipType >= SIS_315H) || 5910 (SiS_Pr->ChipRevision >= 0x30)) { 5911 tempbx = 0x07; 5912 if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 5913 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80; 5914 } 5915 /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit multiplexed) via VGA2 */ 5916 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 5917 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 5918 if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80; 5919 } else { 5920 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80; 5921 } 5922 } 5923 } 5924 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp); 5925 5926 tempbx = push2; /* BPLVDEE */ 5927 5928 tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */ 5929 5930 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 5931 switch(SiS_Pr->SiS_LCDResInfo) { 5932 case Panel_640x480: 5933 tempbx = SiS_Pr->SiS_VGAVDE - 1; 5934 tempcx = SiS_Pr->SiS_VGAVDE; 5935 break; 5936 case Panel_800x600: 5937 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5938 if(resinfo == SIS_RI_800x600) tempcx++; 5939 } 5940 break; 5941 case Panel_1024x600: 5942 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5943 if(resinfo == SIS_RI_1024x600) tempcx++; 5944 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 5945 if(resinfo == SIS_RI_800x600) tempcx++; 5946 } 5947 } 5948 break; 5949 case Panel_1024x768: 5950 if(SiS_Pr->ChipType < SIS_315H) { 5951 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 5952 if(resinfo == SIS_RI_1024x768) tempcx++; 5953 } 5954 } 5955 break; 5956 } 5957 } 5958 5959 temp = ((tempbx >> 8) & 0x07) << 3; 5960 temp |= ((tempcx >> 8) & 0x07); 5961 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp); 5962 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx); 5963 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx); 5964 5965 /* Vertical scaling */ 5966 5967 if(SiS_Pr->ChipType < SIS_315H) { 5968 5969 #ifdef CONFIG_FB_SIS_300 /* 300 series */ 5970 tempeax = SiS_Pr->SiS_VGAVDE << 6; 5971 temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE); 5972 tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE; 5973 if(temp) tempeax++; 5974 5975 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F; 5976 5977 temp = (unsigned short)(tempeax & 0x00FF); 5978 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */ 5979 tempvcfact = temp; 5980 #endif /* CONFIG_FB_SIS_300 */ 5981 5982 } else { 5983 5984 #ifdef CONFIG_FB_SIS_315 /* 315 series */ 5985 tempeax = SiS_Pr->SiS_VGAVDE << 18; 5986 tempebx = SiS_Pr->SiS_VDE; 5987 temp = (tempeax % tempebx); 5988 tempeax = tempeax / tempebx; 5989 if(temp) tempeax++; 5990 tempvcfact = tempeax; 5991 5992 temp = (unsigned short)(tempeax & 0x00FF); 5993 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp); 5994 temp = (unsigned short)((tempeax & 0x00FF00) >> 8); 5995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp); 5996 temp = (unsigned short)((tempeax & 0x00030000) >> 16); 5997 if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04; 5998 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp); 5999 6000 if(SiS_Pr->SiS_VBType & VB_SISPART4SCALER) { 6001 temp = (unsigned short)(tempeax & 0x00FF); 6002 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp); 6003 temp = (unsigned short)((tempeax & 0x00FF00) >> 8); 6004 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp); 6005 temp = (unsigned short)(((tempeax & 0x00030000) >> 16) << 6); 6006 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp); 6007 temp = 0; 6008 if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08; 6009 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp); 6010 } 6011 #endif 6012 6013 } 6014 6015 /* Horizontal scaling */ 6016 6017 tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/ 6018 if(chkdclkfirst) { 6019 if(modeflag & HalfDCLK) tempeax >>= 1; 6020 } 6021 tempebx = tempeax << 16; 6022 if(SiS_Pr->SiS_HDE == tempeax) { 6023 tempecx = 0xFFFF; 6024 } else { 6025 tempecx = tempebx / SiS_Pr->SiS_HDE; 6026 if(SiS_Pr->ChipType >= SIS_315H) { 6027 if(tempebx % SiS_Pr->SiS_HDE) tempecx++; 6028 } 6029 } 6030 6031 if(SiS_Pr->ChipType >= SIS_315H) { 6032 tempeax = (tempebx / tempecx) - 1; 6033 } else { 6034 tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1; 6035 } 6036 tempecx = (tempecx << 16) | (tempeax & 0xFFFF); 6037 temp = (unsigned short)(tempecx & 0x00FF); 6038 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp); 6039 6040 if(SiS_Pr->ChipType >= SIS_315H) { 6041 tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact; 6042 tempbx = (unsigned short)(tempeax & 0xFFFF); 6043 } else { 6044 tempeax = SiS_Pr->SiS_VGAVDE << 6; 6045 tempbx = tempvcfact & 0x3f; 6046 if(tempbx == 0) tempbx = 64; 6047 tempeax /= tempbx; 6048 tempbx = (unsigned short)(tempeax & 0xFFFF); 6049 } 6050 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--; 6051 if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) { 6052 if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1; 6053 else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1; 6054 } 6055 6056 temp = ((tempbx >> 8) & 0x07) << 3; 6057 temp = temp | ((tempecx >> 8) & 0x07); 6058 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp); 6059 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx); 6060 6061 tempecx >>= 16; /* BPLHCFACT */ 6062 if(!chkdclkfirst) { 6063 if(modeflag & HalfDCLK) tempecx >>= 1; 6064 } 6065 temp = (unsigned short)((tempecx & 0xFF00) >> 8); 6066 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp); 6067 temp = (unsigned short)(tempecx & 0x00FF); 6068 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp); 6069 6070 #ifdef CONFIG_FB_SIS_315 6071 if(SiS_Pr->ChipType >= SIS_315H) { 6072 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 6073 if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) { 6074 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20); 6075 } 6076 } else { 6077 if(islvds) { 6078 if(SiS_Pr->ChipType == SIS_740) { 6079 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); 6080 } else { 6081 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23); 6082 } 6083 } 6084 } 6085 } 6086 #endif 6087 6088 #ifdef CONFIG_FB_SIS_300 6089 if(SiS_Pr->SiS_IF_DEF_TRUMPION) { 6090 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 6091 unsigned char *trumpdata; 6092 int i, j = crt2crtc; 6093 unsigned char TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 }; 6094 unsigned char TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 }; 6095 unsigned char TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 }; 6096 6097 if(SiS_Pr->SiS_UseROM) { 6098 trumpdata = &ROMAddr[0x8001 + (j * 80)]; 6099 } else { 6100 if(SiS_Pr->SiS_LCDTypeInfo == 0x0e) j += 7; 6101 trumpdata = &SiS300_TrumpionData[j][0]; 6102 } 6103 6104 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf); 6105 for(i=0; i<5; i++) { 6106 SiS_SetTrumpionBlock(SiS_Pr, trumpdata); 6107 } 6108 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6109 if(ModeNo == 0x13) { 6110 for(i=0; i<4; i++) { 6111 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]); 6112 } 6113 } else if(ModeNo == 0x10) { 6114 for(i=0; i<4; i++) { 6115 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]); 6116 SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]); 6117 } 6118 } 6119 } 6120 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); 6121 } 6122 #endif 6123 6124 #ifdef CONFIG_FB_SIS_315 6125 if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) { 6126 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00); 6127 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00); 6128 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00); 6129 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87); 6130 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A); 6131 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B); 6132 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03); 6133 tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */ 6134 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6135 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6136 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6137 tempax += 64; 6138 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,tempax & 0xff); 6139 temp = (tempax >> 8) << 3; 6140 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp); 6141 tempax += 32; /* Blpe = lBlps+32 */ 6142 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,tempax & 0xff); 6143 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00); /* Bflml = 0 */ 6144 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x007); 6145 6146 tempax = SiS_Pr->SiS_VDE; 6147 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6148 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6149 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6150 tempax >>= 1; 6151 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,tempax & 0xff); 6152 temp = (tempax >> 8) << 3; 6153 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp); 6154 6155 tempeax = SiS_Pr->SiS_HDE; 6156 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6157 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6158 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempeax >>= 1; 6159 tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */ 6160 temp = tempeax & 0x7f; 6161 tempeax >>= 7; 6162 if(temp) tempeax++; 6163 temp = tempeax & 0x3f; 6164 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,temp); 6165 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00); /* BDxWadrst0 */ 6166 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00); 6167 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10); 6168 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x3C,~0x040); 6169 6170 tempax = SiS_Pr->SiS_HDE; 6171 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6172 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6173 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6174 tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */ 6175 pushcx = tempax; 6176 temp = tempax & 0x00FF; 6177 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp); 6178 temp = ((tempax & 0xFF00) >> 8) << 3; 6179 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x44, 0x07, temp); 6180 6181 tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */ 6182 if(SiS_Pr->SiS_LCDResInfo == Panel_320x240_1 || 6183 SiS_Pr->SiS_LCDResInfo == Panel_320x240_2 || 6184 SiS_Pr->SiS_LCDResInfo == Panel_320x240_3) tempax >>= 1; 6185 tempeax = tempax * pushcx; 6186 temp = tempeax & 0xFF; 6187 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp); 6188 temp = (tempeax & 0xFF00) >> 8; 6189 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp); 6190 temp = ((tempeax & 0xFF0000) >> 16) | 0x10; 6191 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp); 6192 temp = ((tempeax & 0x01000000) >> 24) << 7; 6193 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 0x3C, 0x7F, temp); 6194 6195 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03); 6196 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50); 6197 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00); 6198 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01); 6199 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38); 6200 6201 if(SiS_Pr->SiS_IF_DEF_FSTN) { 6202 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02); 6203 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00); 6204 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00); 6205 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c); 6206 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00); 6207 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00); 6208 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80); 6209 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0); 6210 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00); 6211 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0); 6212 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00); 6213 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10); 6214 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00); 6215 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00); 6216 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10); 6217 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25); 6218 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80); 6219 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14); 6220 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03); 6221 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a); 6222 } 6223 } 6224 #endif /* CONFIG_FB_SIS_315 */ 6225 } 6226 6227 /* Set Part 1 */ 6228 static void 6229 SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6230 unsigned short RefreshRateTableIndex) 6231 { 6232 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315) 6233 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 6234 #endif 6235 unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0; 6236 unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0; 6237 #ifdef CONFIG_FB_SIS_315 6238 unsigned short tempbl=0; 6239 #endif 6240 6241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 6242 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6243 return; 6244 } 6245 6246 if(ModeNo <= 0x13) { 6247 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 6248 } else if(SiS_Pr->UseCustomMode) { 6249 modeflag = SiS_Pr->CModeFlag; 6250 } else { 6251 CRT1Index = SiS_GetRefCRT1CRTC(SiS_Pr, RefreshRateTableIndex, SiS_Pr->SiS_UseWideCRT2); 6252 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 6253 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 6254 } 6255 6256 SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6257 6258 if( ! ((SiS_Pr->ChipType >= SIS_315H) && 6259 (SiS_Pr->SiS_IF_DEF_LVDS == 1) && 6260 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) { 6261 6262 if(SiS_Pr->ChipType < SIS_315H ) { 6263 #ifdef CONFIG_FB_SIS_300 6264 SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo); 6265 #endif 6266 } else { 6267 #ifdef CONFIG_FB_SIS_315 6268 SiS_SetCRT2FIFO_310(SiS_Pr); 6269 #endif 6270 } 6271 6272 /* 1. Horizontal setup */ 6273 6274 if(SiS_Pr->ChipType < SIS_315H ) { 6275 6276 #ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/ 6277 6278 temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ 6279 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */ 6280 6281 temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4; 6282 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */ 6283 6284 temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ 6285 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */ 6286 6287 pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */ 6288 tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2; 6289 tempbx = pushbx + tempcx; 6290 tempcx <<= 1; 6291 tempcx += tempbx; 6292 6293 bridgeadd = 12; 6294 6295 #endif /* CONFIG_FB_SIS_300 */ 6296 6297 } else { 6298 6299 #ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */ 6300 6301 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */ 6302 if(modeflag & HalfDCLK) { 6303 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6304 tempcx >>= 1; 6305 } else { 6306 tempax = SiS_Pr->SiS_VGAHDE >> 1; 6307 tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax; 6308 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 6309 tempcx = SiS_Pr->SiS_HT - tempax; 6310 } 6311 } 6312 } 6313 tempcx--; 6314 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */ 6315 temp = (tempcx >> 4) & 0xF0; 6316 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */ 6317 6318 tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */ 6319 tempbx = SiS_Pr->SiS_VGAHDE; 6320 tempcx -= tempbx; 6321 tempcx >>= 2; 6322 if(modeflag & HalfDCLK) { 6323 tempbx >>= 1; 6324 tempcx >>= 1; 6325 } 6326 tempbx += 16; 6327 6328 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */ 6329 6330 pushbx = tempbx; 6331 tempcx >>= 1; 6332 tempbx += tempcx; 6333 tempcx += tempbx; 6334 6335 bridgeadd = 16; 6336 6337 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6338 if(SiS_Pr->ChipType >= SIS_661) { 6339 if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) || 6340 (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) { 6341 if(resinfo == SIS_RI_1280x1024) { 6342 tempcx = (tempcx & 0xff00) | 0x30; 6343 } else if(resinfo == SIS_RI_1600x1200) { 6344 tempcx = (tempcx & 0xff00) | 0xff; 6345 } 6346 } 6347 } 6348 } 6349 6350 #endif /* CONFIG_FB_SIS_315 */ 6351 6352 } /* 315/330 series */ 6353 6354 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6355 6356 if(SiS_Pr->UseCustomMode) { 6357 tempbx = SiS_Pr->CHSyncStart + bridgeadd; 6358 tempcx = SiS_Pr->CHSyncEnd + bridgeadd; 6359 tempax = SiS_Pr->SiS_VGAHT; 6360 if(modeflag & HalfDCLK) tempax >>= 1; 6361 tempax--; 6362 if(tempcx > tempax) tempcx = tempax; 6363 } 6364 6365 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 6366 unsigned char cr4, cr14, cr5, cr15; 6367 if(SiS_Pr->UseCustomMode) { 6368 cr4 = SiS_Pr->CCRT1CRTC[4]; 6369 cr14 = SiS_Pr->CCRT1CRTC[14]; 6370 cr5 = SiS_Pr->CCRT1CRTC[5]; 6371 cr15 = SiS_Pr->CCRT1CRTC[15]; 6372 } else { 6373 cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4]; 6374 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14]; 6375 cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5]; 6376 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15]; 6377 } 6378 tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */ 6379 tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */ 6380 tempcx &= 0x00FF; 6381 tempcx |= (tempbx & 0xFF00); 6382 tempbx += bridgeadd; 6383 tempcx += bridgeadd; 6384 tempax = SiS_Pr->SiS_VGAHT; 6385 if(modeflag & HalfDCLK) tempax >>= 1; 6386 tempax--; 6387 if(tempcx > tempax) tempcx = tempax; 6388 } 6389 6390 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) { 6391 tempbx = 1040; 6392 tempcx = 1044; /* HWCursor bug! */ 6393 } 6394 6395 } 6396 6397 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */ 6398 6399 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */ 6400 6401 temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0); 6402 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */ 6403 6404 /* 2. Vertical setup */ 6405 6406 tempcx = SiS_Pr->SiS_VGAVT - 1; 6407 temp = tempcx & 0x00FF; 6408 6409 if(SiS_Pr->ChipType < SIS_661) { 6410 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6411 if(SiS_Pr->ChipType < SIS_315H) { 6412 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6413 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { 6414 temp--; 6415 } 6416 } 6417 } else { 6418 temp--; 6419 } 6420 } else if(SiS_Pr->ChipType >= SIS_315H) { 6421 temp--; 6422 } 6423 } 6424 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */ 6425 6426 tempbx = SiS_Pr->SiS_VGAVDE - 1; 6427 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */ 6428 6429 temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07); 6430 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */ 6431 6432 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) { 6433 tempbx++; 6434 tempax = tempbx; 6435 tempcx++; 6436 tempcx -= tempax; 6437 tempcx >>= 2; 6438 tempbx += tempcx; 6439 if(tempcx < 4) tempcx = 4; 6440 tempcx >>= 2; 6441 tempcx += tempbx; 6442 tempcx++; 6443 } else { 6444 tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */ 6445 tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */ 6446 } 6447 6448 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6449 if(SiS_Pr->UseCustomMode) { 6450 tempbx = SiS_Pr->CVSyncStart; 6451 tempcx = SiS_Pr->CVSyncEnd; 6452 } 6453 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { 6454 unsigned char cr8, cr7, cr13; 6455 if(SiS_Pr->UseCustomMode) { 6456 cr8 = SiS_Pr->CCRT1CRTC[8]; 6457 cr7 = SiS_Pr->CCRT1CRTC[7]; 6458 cr13 = SiS_Pr->CCRT1CRTC[13]; 6459 tempcx = SiS_Pr->CCRT1CRTC[9]; 6460 } else { 6461 cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8]; 6462 cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7]; 6463 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13]; 6464 tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9]; 6465 } 6466 tempbx = cr8; 6467 if(cr7 & 0x04) tempbx |= 0x0100; 6468 if(cr7 & 0x80) tempbx |= 0x0200; 6469 if(cr13 & 0x08) tempbx |= 0x0400; 6470 } 6471 } 6472 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */ 6473 6474 temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F); 6475 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */ 6476 6477 /* 3. Panel delay compensation */ 6478 6479 if(SiS_Pr->ChipType < SIS_315H) { 6480 6481 #ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */ 6482 6483 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6484 temp = 0x20; 6485 if(SiS_Pr->ChipType == SIS_300) { 6486 temp = 0x10; 6487 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c; 6488 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20; 6489 } 6490 if(SiS_Pr->SiS_VBType & VB_SIS301) { 6491 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20; 6492 } 6493 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24; 6494 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c; 6495 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08; 6496 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6497 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c; 6498 else temp = 0x20; 6499 } 6500 if(SiS_Pr->SiS_UseROM) { 6501 if(ROMAddr[0x220] & 0x80) { 6502 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) 6503 temp = ROMAddr[0x221]; 6504 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) 6505 temp = ROMAddr[0x222]; 6506 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) 6507 temp = ROMAddr[0x223]; 6508 else 6509 temp = ROMAddr[0x224]; 6510 } 6511 } 6512 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6513 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC; 6514 } 6515 6516 } else { 6517 temp = 0x20; 6518 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 6519 if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04; 6520 } 6521 if(SiS_Pr->SiS_UseROM) { 6522 if(ROMAddr[0x220] & 0x80) { 6523 temp = ROMAddr[0x220]; 6524 } 6525 } 6526 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6527 if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC; 6528 } 6529 } 6530 6531 temp &= 0x3c; 6532 6533 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */ 6534 6535 #endif /* CONFIG_FB_SIS_300 */ 6536 6537 } else { 6538 6539 #ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/ 6540 6541 if(SiS_Pr->ChipType < SIS_661) { 6542 6543 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 6544 6545 if(SiS_Pr->ChipType == SIS_740) temp = 0x03; 6546 else temp = 0x00; 6547 6548 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a; 6549 tempbl = 0xF0; 6550 if(SiS_Pr->ChipType == SIS_650) { 6551 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6552 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F; 6553 } 6554 } 6555 6556 if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) { 6557 temp = 0x08; 6558 tempbl = 0; 6559 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 6560 if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0; 6561 } 6562 } 6563 6564 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */ 6565 } 6566 6567 } /* < 661 */ 6568 6569 tempax = 0; 6570 if(modeflag & DoubleScanMode) tempax |= 0x80; 6571 if(modeflag & HalfDCLK) tempax |= 0x40; 6572 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax); 6573 6574 #endif /* CONFIG_FB_SIS_315 */ 6575 6576 } 6577 6578 } /* Slavemode */ 6579 6580 if(SiS_Pr->SiS_VBType & VB_SISVB) { 6581 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 6582 /* For 301BDH with LCD, we set up the Panel Link */ 6583 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6584 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6585 SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6586 } 6587 } else { 6588 if(SiS_Pr->ChipType < SIS_315H) { 6589 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 6590 } else { 6591 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 6592 if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 6593 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex); 6594 } 6595 } else { 6596 SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,RefreshRateTableIndex); 6597 } 6598 } 6599 } 6600 } 6601 6602 /*********************************************/ 6603 /* SET PART 2 REGISTER GROUP */ 6604 /*********************************************/ 6605 6606 #ifdef CONFIG_FB_SIS_315 6607 static unsigned char * 6608 SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype) 6609 { 6610 const unsigned char *tableptr = NULL; 6611 unsigned short a, b, p = 0; 6612 6613 a = SiS_Pr->SiS_VGAHDE; 6614 b = SiS_Pr->SiS_HDE; 6615 if(tabletype) { 6616 a = SiS_Pr->SiS_VGAVDE; 6617 b = SiS_Pr->SiS_VDE; 6618 } 6619 6620 if(a < b) { 6621 tableptr = SiS_Part2CLVX_1; 6622 } else if(a == b) { 6623 tableptr = SiS_Part2CLVX_2; 6624 } else { 6625 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6626 tableptr = SiS_Part2CLVX_4; 6627 } else { 6628 tableptr = SiS_Part2CLVX_3; 6629 } 6630 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 6631 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3; 6632 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3; 6633 else tableptr = SiS_Part2CLVX_5; 6634 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6635 tableptr = SiS_Part2CLVX_6; 6636 } 6637 do { 6638 if((tableptr[p] | tableptr[p+1] << 8) == a) break; 6639 p += 0x42; 6640 } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff); 6641 if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42; 6642 } 6643 p += 2; 6644 return ((unsigned char *)&tableptr[p]); 6645 } 6646 6647 static void 6648 SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6649 unsigned short RefreshRateTableIndex) 6650 { 6651 unsigned char *tableptr; 6652 unsigned char temp; 6653 int i, j; 6654 6655 if(!(SiS_Pr->SiS_VBType & VB_SISTAP4SCALER)) return; 6656 6657 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 0); 6658 for(i = 0x80, j = 0; i <= 0xbf; i++, j++) { 6659 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]); 6660 } 6661 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 6662 tableptr = SiS_GetGroup2CLVXPtr(SiS_Pr, 1); 6663 for(i = 0xc0, j = 0; i <= 0xff; i++, j++) { 6664 SiS_SetReg(SiS_Pr->SiS_Part2Port, i, tableptr[j]); 6665 } 6666 } 6667 temp = 0x10; 6668 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp |= 0x04; 6669 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp); 6670 } 6671 6672 static bool 6673 SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex, 6674 unsigned short RefreshRateTableIndex,unsigned short *CRT2Index, 6675 unsigned short *ResIndex) 6676 { 6677 6678 if(SiS_Pr->ChipType < SIS_315H) return false; 6679 6680 if(ModeNo <= 0x13) 6681 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6682 else 6683 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6684 6685 (*ResIndex) &= 0x3f; 6686 (*CRT2Index) = 0; 6687 6688 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6689 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 6690 (*CRT2Index) = 200; 6691 } 6692 } 6693 6694 if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) { 6695 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 6696 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206; 6697 } 6698 } 6699 return (((*CRT2Index) != 0)); 6700 } 6701 #endif 6702 6703 #ifdef CONFIG_FB_SIS_300 6704 static void 6705 SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc) 6706 { 6707 unsigned short tempcx; 6708 static const unsigned char atable[] = { 6709 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02, 6710 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02 6711 }; 6712 6713 if(!SiS_Pr->UseCustomMode) { 6714 if( ( ( (SiS_Pr->ChipType == SIS_630) || 6715 (SiS_Pr->ChipType == SIS_730) ) && 6716 (SiS_Pr->ChipRevision > 2) ) && 6717 (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) && 6718 (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) && 6719 (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) { 6720 if(ModeNo == 0x13) { 6721 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9); 6722 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC); 6723 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6); 6724 } else if((crt2crtc & 0x3F) == 4) { 6725 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B); 6726 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13); 6727 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5); 6728 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08); 6729 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2); 6730 } 6731 } 6732 6733 if(SiS_Pr->ChipType < SIS_315H) { 6734 if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) { 6735 crt2crtc &= 0x1f; 6736 tempcx = 0; 6737 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6738 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6739 tempcx += 7; 6740 } 6741 } 6742 tempcx += crt2crtc; 6743 if(crt2crtc >= 4) { 6744 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff); 6745 } 6746 6747 if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) { 6748 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6749 if(crt2crtc == 4) { 6750 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28); 6751 } 6752 } 6753 } 6754 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18); 6755 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]); 6756 } 6757 } 6758 } 6759 } 6760 6761 /* For ECS A907. Highly preliminary. */ 6762 static void 6763 SiS_Set300Part2Regs(struct SiS_Private *SiS_Pr, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, 6764 unsigned short ModeNo) 6765 { 6766 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; 6767 unsigned short crt2crtc, resindex; 6768 int i, j; 6769 6770 if(SiS_Pr->ChipType != SIS_300) return; 6771 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return; 6772 if(SiS_Pr->UseCustomMode) return; 6773 6774 if(ModeNo <= 0x13) { 6775 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6776 } else { 6777 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6778 } 6779 6780 resindex = crt2crtc & 0x3F; 6781 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; 6782 else CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2; 6783 6784 /* The BIOS code (1.16.51,56) is obviously a fragment! */ 6785 if(ModeNo > 0x13) { 6786 CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; 6787 resindex = 4; 6788 } 6789 6790 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 6791 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); 6792 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { 6793 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6794 } 6795 for(j = 0x1c; j <= 0x1d; i++, j++ ) { 6796 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6797 } 6798 for(j = 0x1f; j <= 0x21; i++, j++ ) { 6799 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 6800 } 6801 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); 6802 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); 6803 } 6804 #endif 6805 6806 static void 6807 SiS_SetTVSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 6808 { 6809 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) return; 6810 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) return; 6811 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) return; 6812 6813 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 6814 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6815 static const unsigned char specialtv[] = { 6816 0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53, 6817 0x13,0x40,0x34,0xf4,0x63,0xbb,0xcc,0x7a, 6818 0x58,0xe4,0x73,0xda,0x13 6819 }; 6820 int i, j; 6821 for(i = 0x1c, j = 0; i <= 0x30; i++, j++) { 6822 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,specialtv[j]); 6823 } 6824 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72); 6825 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) { 6826 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 6827 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); 6828 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b); 6829 } else { 6830 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */ 6831 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */ 6832 } 6833 } 6834 } 6835 } else { 6836 if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) || 6837 (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) { 6838 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */ 6839 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */ 6840 } else { 6841 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */ 6842 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */ 6843 } 6844 } 6845 } 6846 6847 static void 6848 SiS_SetGroup2_Tail(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 6849 { 6850 unsigned short temp; 6851 6852 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { 6853 if(SiS_Pr->SiS_VGAVDE == 525) { 6854 temp = 0xc3; 6855 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6856 temp++; 6857 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp += 2; 6858 } 6859 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6860 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3); 6861 } else if(SiS_Pr->SiS_VGAVDE == 420) { 6862 temp = 0x4d; 6863 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 6864 temp++; 6865 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) temp++; 6866 } 6867 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp); 6868 } 6869 } 6870 6871 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 6872 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) { 6873 if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 6874 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03); 6875 /* Not always for LV, see SetGrp2 */ 6876 } 6877 temp = 1; 6878 if(ModeNo <= 0x13) temp = 3; 6879 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp); 6880 } 6881 #if 0 6882 /* 651+301C, for 1280x768 - do I really need that? */ 6883 if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) { 6884 if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) { 6885 if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) || 6886 ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) { 6887 SiS_SetReg(SiS_Part2Port,0x01,0x2b); 6888 SiS_SetReg(SiS_Part2Port,0x02,0x13); 6889 SiS_SetReg(SiS_Part2Port,0x04,0xe5); 6890 SiS_SetReg(SiS_Part2Port,0x05,0x08); 6891 SiS_SetReg(SiS_Part2Port,0x06,0xe2); 6892 SiS_SetReg(SiS_Part2Port,0x1c,0x21); 6893 SiS_SetReg(SiS_Part2Port,0x1d,0x45); 6894 SiS_SetReg(SiS_Part2Port,0x1f,0x0b); 6895 SiS_SetReg(SiS_Part2Port,0x20,0x00); 6896 SiS_SetReg(SiS_Part2Port,0x21,0xa9); 6897 SiS_SetReg(SiS_Part2Port,0x23,0x0b); 6898 SiS_SetReg(SiS_Part2Port,0x25,0x04); 6899 } 6900 } 6901 } 6902 #endif 6903 } 6904 } 6905 6906 static void 6907 SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 6908 unsigned short RefreshRateTableIndex) 6909 { 6910 unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp; 6911 unsigned short push2, modeflag, crt2crtc, bridgeoffset; 6912 unsigned int longtemp, PhaseIndex; 6913 bool newtvphase; 6914 const unsigned char *TimingPoint; 6915 #ifdef CONFIG_FB_SIS_315 6916 unsigned short resindex, CRT2Index; 6917 const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL; 6918 6919 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 6920 #endif 6921 6922 if(ModeNo <= 0x13) { 6923 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 6924 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 6925 } else if(SiS_Pr->UseCustomMode) { 6926 modeflag = SiS_Pr->CModeFlag; 6927 crt2crtc = 0; 6928 } else { 6929 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 6930 crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 6931 } 6932 6933 temp = 0; 6934 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO)) temp |= 0x08; 6935 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x04; 6936 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) temp |= 0x02; 6937 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp |= 0x01; 6938 6939 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) temp |= 0x10; 6940 6941 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp); 6942 6943 PhaseIndex = 0x01; /* SiS_PALPhase */ 6944 TimingPoint = SiS_Pr->SiS_PALTiming; 6945 6946 newtvphase = false; 6947 if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) && 6948 ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || 6949 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) { 6950 newtvphase = true; 6951 } 6952 6953 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 6954 6955 TimingPoint = SiS_Pr->SiS_HiTVExtTiming; 6956 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 6957 TimingPoint = SiS_Pr->SiS_HiTVSt2Timing; 6958 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 6959 TimingPoint = SiS_Pr->SiS_HiTVSt1Timing; 6960 } 6961 } 6962 6963 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 6964 6965 i = 0; 6966 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) i = 2; 6967 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) i = 1; 6968 6969 TimingPoint = &SiS_YPbPrTable[i][0]; 6970 6971 PhaseIndex = 0x00; /* SiS_NTSCPhase */ 6972 6973 } else if(SiS_Pr->SiS_TVMode & TVSetPAL) { 6974 6975 if(newtvphase) PhaseIndex = 0x09; /* SiS_PALPhase2 */ 6976 6977 } else { 6978 6979 TimingPoint = SiS_Pr->SiS_NTSCTiming; 6980 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetNTSCJ) ? 0x01 : 0x00; /* SiS_PALPhase : SiS_NTSCPhase */ 6981 if(newtvphase) PhaseIndex += 8; /* SiS_PALPhase2 : SiS_NTSCPhase2 */ 6982 6983 } 6984 6985 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) { 6986 PhaseIndex = (SiS_Pr->SiS_TVMode & TVSetPALM) ? 0x02 : 0x03; /* SiS_PALMPhase : SiS_PALNPhase */ 6987 if(newtvphase) PhaseIndex += 8; /* SiS_PALMPhase2 : SiS_PALNPhase2 */ 6988 } 6989 6990 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 6991 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 6992 PhaseIndex = 0x05; /* SiS_SpecialPhaseM */ 6993 } else if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) { 6994 PhaseIndex = 0x11; /* SiS_SpecialPhaseJ */ 6995 } else { 6996 PhaseIndex = 0x10; /* SiS_SpecialPhase */ 6997 } 6998 } 6999 7000 for(i = 0x31, j = 0; i <= 0x34; i++, j++) { 7001 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[(PhaseIndex * 4) + j]); 7002 } 7003 7004 for(i = 0x01, j = 0; i <= 0x2D; i++, j++) { 7005 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 7006 } 7007 for(i = 0x39; i <= 0x45; i++, j++) { 7008 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]); 7009 } 7010 7011 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7012 if(SiS_Pr->SiS_ModeType != ModeText) { 7013 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F); 7014 } 7015 } 7016 7017 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode); 7018 7019 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE); 7020 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE); 7021 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE); 7022 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE); 7023 7024 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950; 7025 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempax = 680; 7026 else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520; 7027 else tempax = 440; /* NTSC, YPbPr 525 */ 7028 7029 if( ((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) && (SiS_Pr->SiS_VDE <= tempax)) || 7030 ( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) && 7031 ((SiS_Pr->SiS_VGAHDE == 1024) || (SiS_Pr->SiS_VDE <= tempax)) ) ) { 7032 7033 tempax -= SiS_Pr->SiS_VDE; 7034 tempax >>= 1; 7035 if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) { 7036 tempax >>= 1; 7037 } 7038 tempax &= 0x00ff; 7039 7040 temp = tempax + (unsigned short)TimingPoint[0]; 7041 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 7042 7043 temp = tempax + (unsigned short)TimingPoint[1]; 7044 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp); 7045 7046 if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) { 7047 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 7048 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); 7049 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); 7050 } else { 7051 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17); 7052 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d); 7053 } 7054 } 7055 7056 } 7057 7058 tempcx = SiS_Pr->SiS_HT; 7059 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 7060 tempcx--; 7061 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) tempcx--; 7062 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx); 7063 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f)); 7064 7065 tempcx = SiS_Pr->SiS_HT >> 1; 7066 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 7067 tempcx += 7; 7068 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4; 7069 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0)); 7070 7071 tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8); 7072 tempbx += tempcx; 7073 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx); 7074 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0)); 7075 7076 tempbx += 8; 7077 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7078 tempbx -= 4; 7079 tempcx = tempbx; 7080 } 7081 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0)); 7082 7083 j += 2; 7084 tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8)); 7085 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx); 7086 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0)); 7087 7088 tempcx += 8; 7089 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4; 7090 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0)); 7091 7092 tempcx = SiS_Pr->SiS_HT >> 1; 7093 if(SiS_IsDualLink(SiS_Pr)) tempcx >>= 1; 7094 j += 2; 7095 tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8)); 7096 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0)); 7097 7098 tempcx -= 11; 7099 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 7100 tempcx = SiS_GetVGAHT2(SiS_Pr) - 1; 7101 } 7102 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx); 7103 7104 tempbx = SiS_Pr->SiS_VDE; 7105 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7106 if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746; 7107 if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746; 7108 if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853; 7109 } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 7110 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) { 7111 tempbx >>= 1; 7112 if(SiS_Pr->ChipType >= SIS_315H) { 7113 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 7114 if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++; 7115 } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 7116 if(SiS_Pr->SiS_ModeType <= ModeVGA) { 7117 if(crt2crtc == 4) tempbx++; 7118 } 7119 } 7120 } 7121 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 7122 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7123 if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++; 7124 } 7125 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { 7126 if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */ 7127 } 7128 } 7129 } 7130 tempbx -= 2; 7131 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx); 7132 7133 temp = (tempcx >> 8) & 0x0F; 7134 temp |= ((tempbx >> 2) & 0xC0); 7135 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) { 7136 temp |= 0x10; 7137 if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20; 7138 } 7139 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp); 7140 7141 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) { 7142 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5)); 7143 } 7144 7145 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7146 tempbx = SiS_Pr->SiS_VDE; 7147 if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && 7148 (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) { 7149 tempbx >>= 1; 7150 } 7151 tempbx -= 3; 7152 temp = ((tempbx >> 3) & 0x60) | 0x18; 7153 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp); 7154 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx); 7155 7156 if(SiS_Pr->SiS_VBType & VB_SISPART4OVERFLOW) { 7157 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4)); 7158 } 7159 } 7160 7161 tempbx = 0; 7162 if(!(modeflag & HalfDCLK)) { 7163 if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) { 7164 tempax = 0; 7165 tempbx |= 0x20; 7166 } 7167 } 7168 7169 tempch = tempcl = 0x01; 7170 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7171 if(SiS_Pr->SiS_VGAHDE >= 960) { 7172 if((!(modeflag & HalfDCLK)) || (SiS_Pr->ChipType < SIS_315H)) { 7173 tempcl = 0x20; 7174 if(SiS_Pr->SiS_VGAHDE >= 1280) { 7175 tempch = 20; 7176 tempbx &= ~0x20; 7177 } else { 7178 tempch = 25; /* OK */ 7179 } 7180 } 7181 } 7182 } 7183 7184 if(!(tempbx & 0x20)) { 7185 if(modeflag & HalfDCLK) tempcl <<= 1; 7186 longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13; 7187 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) longtemp <<= 3; 7188 tempax = longtemp / SiS_Pr->SiS_HDE; 7189 if(longtemp % SiS_Pr->SiS_HDE) tempax++; 7190 tempbx |= ((tempax >> 8) & 0x1F); 7191 tempcx = tempax >> 13; 7192 } 7193 7194 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax); 7195 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx); 7196 7197 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7198 7199 tempcx &= 0x07; 7200 if(tempbx & 0x20) tempcx = 0; 7201 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx); 7202 7203 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 7204 tempbx = 0x0382; 7205 tempcx = 0x007e; 7206 } else { 7207 tempbx = 0x0369; 7208 tempcx = 0x0061; 7209 } 7210 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx); 7211 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx); 7212 temp = (tempcx & 0x0300) >> 6; 7213 temp |= ((tempbx >> 8) & 0x03); 7214 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 7215 temp |= 0x10; 7216 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp |= 0x20; 7217 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp |= 0x40; 7218 } 7219 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp); 7220 7221 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43); 7222 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3)); 7223 7224 SiS_SetTVSpecial(SiS_Pr, ModeNo); 7225 7226 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 7227 temp = 0; 7228 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8; 7229 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xf7,temp); 7230 } 7231 7232 } 7233 7234 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 7235 if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) { 7236 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01); 7237 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1)); 7238 } 7239 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF); 7240 } 7241 7242 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7243 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 7244 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00); 7245 } 7246 } 7247 7248 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) return; 7249 7250 /* From here: Part2 LCD setup */ 7251 7252 tempbx = SiS_Pr->SiS_HDE; 7253 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7254 tempbx--; /* RHACTE = HDE - 1 */ 7255 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx); 7256 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0)); 7257 7258 temp = 0x01; 7259 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 7260 if(SiS_Pr->SiS_ModeType == ModeEGA) { 7261 if(SiS_Pr->SiS_VGAHDE >= 1024) { 7262 temp = 0x02; 7263 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 7264 temp = 0x01; 7265 } 7266 } 7267 } 7268 } 7269 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp); 7270 7271 tempbx = SiS_Pr->SiS_VDE - 1; 7272 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx); 7273 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07)); 7274 7275 tempcx = SiS_Pr->SiS_VT - 1; 7276 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx); 7277 temp = (tempcx >> 3) & 0xE0; 7278 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 7279 /* Enable dithering; only do this for 32bpp mode */ 7280 if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) { 7281 temp |= 0x10; 7282 } 7283 } 7284 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp); 7285 7286 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0); 7287 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0); 7288 7289 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB); 7290 SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF); 7291 7292 #ifdef CONFIG_FB_SIS_315 7293 if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 7294 &CRT2Index, &resindex)) { 7295 switch(CRT2Index) { 7296 case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break; 7297 default: 7298 case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; 7299 } 7300 7301 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]); 7302 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]); 7303 for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) { 7304 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7305 } 7306 for(j = 0x1c; j <= 0x1d; i++, j++ ) { 7307 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7308 } 7309 for(j = 0x1f; j <= 0x21; i++, j++ ) { 7310 SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]); 7311 } 7312 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]); 7313 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]); 7314 7315 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7316 7317 } else { 7318 #endif 7319 7320 /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */ 7321 /* Clevo dual-link 1024x768 */ 7322 /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */ 7323 /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */ 7324 7325 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7326 if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) { 7327 tempbx = SiS_Pr->SiS_VDE - 1; 7328 tempcx = SiS_Pr->SiS_VT - 1; 7329 } else { 7330 tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2); 7331 tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2); 7332 } 7333 } else { 7334 tempbx = SiS_Pr->PanelYRes; 7335 tempcx = SiS_Pr->SiS_VT; 7336 tempax = 1; 7337 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7338 tempax = SiS_Pr->PanelYRes; 7339 /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */ 7340 if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) { 7341 tempax = tempcx = 0; 7342 } else { 7343 tempax -= SiS_Pr->SiS_VDE; 7344 } 7345 tempax >>= 1; 7346 } 7347 tempcx -= tempax; /* lcdvdes */ 7348 tempbx -= tempax; /* lcdvdee */ 7349 } 7350 7351 /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */ 7352 7353 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */ 7354 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */ 7355 7356 temp = (tempbx >> 5) & 0x38; 7357 temp |= ((tempcx >> 8) & 0x07); 7358 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp); 7359 7360 tempax = SiS_Pr->SiS_VDE; 7361 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7362 tempax = SiS_Pr->PanelYRes; 7363 } 7364 tempcx = (SiS_Pr->SiS_VT - tempax) >> 4; 7365 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7366 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7367 tempcx = (SiS_Pr->SiS_VT - tempax) / 10; 7368 } 7369 } 7370 7371 tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1; 7372 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7373 if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) { 7374 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */ 7375 tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes; 7376 if(tempax % 4) { tempax >>= 2; tempax++; } 7377 else { tempax >>= 2; } 7378 tempbx -= (tempax - 1); 7379 } else { 7380 tempbx -= 10; 7381 if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1; 7382 } 7383 } 7384 } 7385 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 7386 tempbx++; 7387 if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) { 7388 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 7389 tempbx = 770; 7390 tempcx = 3; 7391 } 7392 } 7393 } 7394 7395 /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */ 7396 7397 if(SiS_Pr->UseCustomMode) { 7398 tempbx = SiS_Pr->CVSyncStart; 7399 } 7400 7401 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */ 7402 7403 temp = (tempbx >> 4) & 0xF0; 7404 tempbx += (tempcx + 1); 7405 temp |= (tempbx & 0x0F); 7406 7407 if(SiS_Pr->UseCustomMode) { 7408 temp &= 0xf0; 7409 temp |= (SiS_Pr->CVSyncEnd & 0x0f); 7410 } 7411 7412 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp); 7413 7414 #ifdef CONFIG_FB_SIS_300 7415 SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc); 7416 #endif 7417 7418 bridgeoffset = 7; 7419 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) bridgeoffset += 2; 7420 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) bridgeoffset += 2; /* OK for Averatec 1280x800 (301C) */ 7421 if(SiS_IsDualLink(SiS_Pr)) bridgeoffset++; 7422 else if(SiS_Pr->SiS_VBType & VB_SIS302LV) bridgeoffset++; /* OK for Asus A4L 1280x800 */ 7423 /* Higher bridgeoffset shifts to the LEFT */ 7424 7425 temp = 0; 7426 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7427 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) { 7428 temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7429 if(SiS_IsDualLink(SiS_Pr)) temp >>= 1; 7430 } 7431 } 7432 temp += bridgeoffset; 7433 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */ 7434 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0)); 7435 7436 tempcx = SiS_Pr->SiS_HT; 7437 tempax = tempbx = SiS_Pr->SiS_HDE; 7438 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7439 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) { 7440 tempax = SiS_Pr->PanelXRes; 7441 tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2); 7442 } 7443 } 7444 if(SiS_IsDualLink(SiS_Pr)) { 7445 tempcx >>= 1; 7446 tempbx >>= 1; 7447 tempax >>= 1; 7448 } 7449 7450 tempbx += bridgeoffset; 7451 7452 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */ 7453 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f)); 7454 7455 tempcx = (tempcx - tempax) >> 2; 7456 7457 tempbx += tempcx; 7458 push2 = tempbx; 7459 7460 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 7461 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 7462 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 7463 if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47; 7464 } 7465 } 7466 } 7467 7468 if(SiS_Pr->UseCustomMode) { 7469 tempbx = SiS_Pr->CHSyncStart; 7470 if(modeflag & HalfDCLK) tempbx <<= 1; 7471 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7472 tempbx += bridgeoffset; 7473 } 7474 7475 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */ 7476 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0)); 7477 7478 tempbx = push2; 7479 7480 tempcx <<= 1; 7481 if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) { 7482 if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2; 7483 } 7484 tempbx += tempcx; 7485 7486 if(SiS_Pr->UseCustomMode) { 7487 tempbx = SiS_Pr->CHSyncEnd; 7488 if(modeflag & HalfDCLK) tempbx <<= 1; 7489 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7490 tempbx += bridgeoffset; 7491 } 7492 7493 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */ 7494 7495 SiS_SetGroup2_Tail(SiS_Pr, ModeNo); 7496 7497 #ifdef CONFIG_FB_SIS_300 7498 SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo); 7499 #endif 7500 #ifdef CONFIG_FB_SIS_315 7501 } /* CRT2-LCD from table */ 7502 #endif 7503 } 7504 7505 /*********************************************/ 7506 /* SET PART 3 REGISTER GROUP */ 7507 /*********************************************/ 7508 7509 static void 7510 SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7511 { 7512 unsigned short i; 7513 const unsigned char *tempdi; 7514 7515 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7516 7517 #ifndef SIS_CP 7518 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00); 7519 #else 7520 SIS_CP_INIT301_CP 7521 #endif 7522 7523 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 7524 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA); 7525 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8); 7526 } else { 7527 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5); 7528 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7); 7529 } 7530 7531 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 7532 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA); 7533 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8); 7534 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8); 7535 } 7536 7537 tempdi = NULL; 7538 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7539 tempdi = SiS_Pr->SiS_HiTVGroup3Data; 7540 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) { 7541 tempdi = SiS_Pr->SiS_HiTVGroup3Simu; 7542 } 7543 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) { 7544 if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) { 7545 tempdi = SiS_HiTVGroup3_1; 7546 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) tempdi = SiS_HiTVGroup3_2; 7547 } 7548 } 7549 if(tempdi) { 7550 for(i=0; i<=0x3E; i++) { 7551 SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]); 7552 } 7553 if(SiS_Pr->SiS_VBType & VB_SIS30xCLV) { 7554 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) { 7555 SiS_SetReg(SiS_Pr->SiS_Part3Port,0x28,0x3f); 7556 } 7557 } 7558 } 7559 7560 #ifdef SIS_CP 7561 SIS_CP_INIT301_CP2 7562 #endif 7563 } 7564 7565 /*********************************************/ 7566 /* SET PART 4 REGISTER GROUP */ 7567 /*********************************************/ 7568 7569 #ifdef CONFIG_FB_SIS_315 7570 #if 0 7571 static void 7572 SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift) 7573 { 7574 unsigned short temp, temp1, temp2; 7575 7576 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f); 7577 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20); 7578 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7579 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp); 7580 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0)); 7581 temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f; 7582 temp = (unsigned short)((int)(temp) + shift); 7583 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f)); 7584 temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43); 7585 temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42); 7586 temp = (unsigned short)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift); 7587 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp); 7588 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0)); 7589 } 7590 #endif 7591 7592 static void 7593 SiS_SetGroup4_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7594 { 7595 unsigned short temp, temp1; 7596 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 7597 7598 if(!(SiS_Pr->SiS_VBType & VB_SIS30xCLV)) return; 7599 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return; 7600 7601 if(SiS_Pr->ChipType >= XGI_20) return; 7602 7603 if((SiS_Pr->ChipType >= SIS_661) && (SiS_Pr->SiS_ROMNew)) { 7604 if(!(ROMAddr[0x61] & 0x04)) return; 7605 } 7606 7607 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08); 7608 temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a); 7609 if(!(temp & 0x01)) { 7610 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3a,0xdf); 7611 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xfc); 7612 if((SiS_Pr->ChipType < SIS_661) && (!(SiS_Pr->SiS_ROMNew))) { 7613 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8); 7614 } 7615 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb); 7616 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000; 7617 else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002; 7618 else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400; 7619 else temp = 0x0402; 7620 if((SiS_Pr->ChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) { 7621 temp1 = 0; 7622 if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4; 7623 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1); 7624 if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01; 7625 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff)); 7626 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8)); 7627 if(ModeNo > 0x13) { 7628 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,0xfd); 7629 } 7630 } else { 7631 temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03; 7632 if(temp1 == 0x01) temp |= 0x01; 7633 if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */ 7634 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff)); 7635 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8)); 7636 if(ModeNo > 0x13) { 7637 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x3b,0xfd); 7638 } 7639 } 7640 7641 #if 0 7642 if(SiS_Pr->ChipType >= SIS_661) { /* ? */ 7643 if(SiS_Pr->SiS_TVMode & TVAspect43) { 7644 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) { 7645 if(resinfo == SIS_RI_1024x768) { 7646 SiS_ShiftXPos(SiS_Pr, 97); 7647 } else { 7648 SiS_ShiftXPos(SiS_Pr, 111); 7649 } 7650 } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) { 7651 SiS_ShiftXPos(SiS_Pr, 136); 7652 } 7653 } 7654 } 7655 #endif 7656 7657 } 7658 7659 } 7660 #endif 7661 7662 static void 7663 SiS_SetCRT2VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7664 unsigned short RefreshRateTableIndex) 7665 { 7666 unsigned short vclkindex, temp, reg1, reg2; 7667 7668 if(SiS_Pr->UseCustomMode) { 7669 reg1 = SiS_Pr->CSR2B; 7670 reg2 = SiS_Pr->CSR2C; 7671 } else { 7672 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 7673 reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A; 7674 reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B; 7675 } 7676 7677 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7678 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSet525p1024)) { 7679 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57); 7680 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46); 7681 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6); 7682 } else { 7683 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1); 7684 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2); 7685 } 7686 } else { 7687 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x01); 7688 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,reg2); 7689 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,reg1); 7690 } 7691 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00); 7692 temp = 0x08; 7693 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20; 7694 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp); 7695 } 7696 7697 static void 7698 SiS_SetDualLinkEtc(struct SiS_Private *SiS_Pr) 7699 { 7700 if(SiS_Pr->ChipType >= SIS_315H) { 7701 if(SiS_Pr->SiS_VBType & VB_SISDUALLINK) { 7702 if((SiS_CRT2IsLCD(SiS_Pr)) || 7703 (SiS_IsVAMode(SiS_Pr))) { 7704 if(SiS_Pr->SiS_LCDInfo & LCDDualLink) { 7705 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c); 7706 } else { 7707 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,~0x20); 7708 } 7709 } 7710 } 7711 } 7712 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 7713 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00); 7714 #ifdef SET_EMI 7715 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 7716 #endif 7717 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 7718 } 7719 } 7720 7721 static void 7722 SiS_SetGroup4(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7723 unsigned short RefreshRateTableIndex) 7724 { 7725 unsigned short tempax, tempcx, tempbx, modeflag, temp, resinfo; 7726 unsigned int tempebx, tempeax, templong; 7727 7728 if(ModeNo <= 0x13) { 7729 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7730 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 7731 } else if(SiS_Pr->UseCustomMode) { 7732 modeflag = SiS_Pr->CModeFlag; 7733 resinfo = 0; 7734 } else { 7735 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7736 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 7737 } 7738 7739 if(SiS_Pr->ChipType >= SIS_315H) { 7740 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 7741 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7742 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7743 } 7744 } 7745 } 7746 7747 if(SiS_Pr->SiS_VBType & (VB_SIS30xCLV | VB_SIS302LV)) { 7748 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7749 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x10,0x9f); 7750 } 7751 } 7752 7753 if(SiS_Pr->ChipType >= SIS_315H) { 7754 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 7755 SiS_SetDualLinkEtc(SiS_Pr); 7756 return; 7757 } 7758 } 7759 7760 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT); 7761 7762 tempbx = SiS_Pr->SiS_RVBHCMAX; 7763 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx); 7764 7765 temp = (tempbx >> 1) & 0x80; 7766 7767 tempcx = SiS_Pr->SiS_VGAHT - 1; 7768 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx); 7769 7770 temp |= ((tempcx >> 5) & 0x78); 7771 7772 tempcx = SiS_Pr->SiS_VGAVT - 1; 7773 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5; 7774 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx); 7775 7776 temp |= ((tempcx >> 8) & 0x07); 7777 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp); 7778 7779 tempbx = SiS_Pr->SiS_VGAHDE; 7780 if(modeflag & HalfDCLK) tempbx >>= 1; 7781 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7782 7783 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7784 temp = 0; 7785 if(tempbx > 800) temp = 0x60; 7786 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7787 temp = 0; 7788 if(tempbx > 1024) temp = 0xC0; 7789 else if(tempbx >= 960) temp = 0xA0; 7790 } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) { 7791 temp = 0; 7792 if(tempbx >= 1280) temp = 0x40; 7793 else if(tempbx >= 1024) temp = 0x20; 7794 } else { 7795 temp = 0x80; 7796 if(tempbx >= 1024) temp = 0xA0; 7797 } 7798 7799 temp |= SiS_Pr->Init_P4_0E; 7800 7801 if(SiS_Pr->SiS_VBType & VB_SIS301) { 7802 if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) { 7803 temp &= 0xf0; 7804 temp |= 0x0A; 7805 } 7806 } 7807 7808 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp); 7809 7810 tempeax = SiS_Pr->SiS_VGAVDE; 7811 tempebx = SiS_Pr->SiS_VDE; 7812 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 7813 if(!(temp & 0xE0)) tempebx >>=1; 7814 } 7815 7816 tempcx = SiS_Pr->SiS_RVBHRS; 7817 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx); 7818 tempcx >>= 8; 7819 tempcx |= 0x40; 7820 7821 if(tempeax <= tempebx) { 7822 tempcx ^= 0x40; 7823 } else { 7824 tempeax -= tempebx; 7825 } 7826 7827 tempeax *= (256 * 1024); 7828 templong = tempeax % tempebx; 7829 tempeax /= tempebx; 7830 if(templong) tempeax++; 7831 7832 temp = (unsigned short)(tempeax & 0x000000FF); 7833 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp); 7834 temp = (unsigned short)((tempeax & 0x0000FF00) >> 8); 7835 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp); 7836 temp = (unsigned short)((tempeax >> 12) & 0x70); /* sic! */ 7837 temp |= (tempcx & 0x4F); 7838 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp); 7839 7840 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 7841 7842 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28); 7843 7844 /* Calc Linebuffer max address and set/clear decimode */ 7845 tempbx = 0; 7846 if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08; 7847 tempax = SiS_Pr->SiS_VGAHDE; 7848 if(modeflag & HalfDCLK) tempax >>= 1; 7849 if(SiS_IsDualLink(SiS_Pr)) tempax >>= 1; 7850 if(tempax > 800) { 7851 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7852 tempax -= 800; 7853 } else { 7854 tempbx = 0x08; 7855 if(tempax == 960) tempax *= 25; /* Correct */ 7856 else if(tempax == 1024) tempax *= 25; 7857 else tempax *= 20; 7858 temp = tempax % 32; 7859 tempax /= 32; 7860 if(temp) tempax++; 7861 tempax++; 7862 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7863 if(resinfo == SIS_RI_1024x768 || 7864 resinfo == SIS_RI_1024x576 || 7865 resinfo == SIS_RI_1280x1024 || 7866 resinfo == SIS_RI_1280x720) { 7867 /* Otherwise white line or garbage at right edge */ 7868 tempax = (tempax & 0xff00) | 0x20; 7869 } 7870 } 7871 } 7872 } 7873 tempax--; 7874 temp = ((tempax >> 4) & 0x30) | tempbx; 7875 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax); 7876 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp); 7877 7878 temp = 0x0036; tempbx = 0xD0; 7879 if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 7880 temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */ 7881 } 7882 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 7883 if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) { 7884 temp |= 0x01; 7885 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 7886 if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 7887 temp &= ~0x01; 7888 } 7889 } 7890 } 7891 } 7892 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp); 7893 7894 tempbx = SiS_Pr->SiS_HT >> 1; 7895 if(SiS_IsDualLink(SiS_Pr)) tempbx >>= 1; 7896 tempbx -= 2; 7897 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx); 7898 temp = (tempbx >> 5) & 0x38; 7899 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp); 7900 7901 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 7902 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 7903 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e); 7904 /* LCD-too-dark-error-source, see FinalizeLCD() */ 7905 } 7906 } 7907 7908 SiS_SetDualLinkEtc(SiS_Pr); 7909 7910 } /* 301B */ 7911 7912 SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 7913 } 7914 7915 /*********************************************/ 7916 /* SET PART 5 REGISTER GROUP */ 7917 /*********************************************/ 7918 7919 static void 7920 SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 7921 { 7922 7923 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return; 7924 7925 if(SiS_Pr->SiS_ModeType == ModeVGA) { 7926 if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) { 7927 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); 7928 SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex); 7929 } 7930 } 7931 } 7932 7933 /*********************************************/ 7934 /* MODIFY CRT1 GROUP FOR SLAVE MODE */ 7935 /*********************************************/ 7936 7937 static bool 7938 SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 7939 unsigned short RefreshRateTableIndex, unsigned short *ResIndex, 7940 unsigned short *DisplayType) 7941 { 7942 unsigned short modeflag = 0; 7943 bool checkhd = true; 7944 7945 /* Pass 1:1 not supported here */ 7946 7947 if(ModeNo <= 0x13) { 7948 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 7949 (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 7950 } else { 7951 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 7952 (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 7953 } 7954 7955 (*ResIndex) &= 0x3F; 7956 7957 if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 7958 7959 (*DisplayType) = 80; 7960 if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) { 7961 (*DisplayType) = 82; 7962 if(SiS_Pr->SiS_ModeType > ModeVGA) { 7963 if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 84; 7964 } 7965 } 7966 if((*DisplayType) != 84) { 7967 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++; 7968 } 7969 7970 } else { 7971 7972 (*DisplayType = 0); 7973 switch(SiS_Pr->SiS_LCDResInfo) { 7974 case Panel_320x240_1: (*DisplayType) = 50; 7975 checkhd = false; 7976 break; 7977 case Panel_320x240_2: (*DisplayType) = 14; 7978 break; 7979 case Panel_320x240_3: (*DisplayType) = 18; 7980 break; 7981 case Panel_640x480: (*DisplayType) = 10; 7982 break; 7983 case Panel_1024x600: (*DisplayType) = 26; 7984 break; 7985 default: return true; 7986 } 7987 7988 if(checkhd) { 7989 if(modeflag & HalfDCLK) (*DisplayType)++; 7990 } 7991 7992 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) { 7993 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2; 7994 } 7995 7996 } 7997 7998 return true; 7999 } 8000 8001 static void 8002 SiS_ModCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 8003 unsigned short RefreshRateTableIndex) 8004 { 8005 unsigned short tempah, i, modeflag, j, ResIndex, DisplayType; 8006 const struct SiS_LVDSCRT1Data *LVDSCRT1Ptr=NULL; 8007 static const unsigned short CRIdx[] = { 8008 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 8009 0x07, 0x10, 0x11, 0x15, 0x16 8010 }; 8011 8012 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 8013 (SiS_Pr->SiS_CustomT == CUT_BARCO1024) || 8014 (SiS_Pr->SiS_CustomT == CUT_PANEL848) || 8015 (SiS_Pr->SiS_CustomT == CUT_PANEL856) ) 8016 return; 8017 8018 if(SiS_Pr->SiS_IF_DEF_LVDS) { 8019 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 8020 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return; 8021 } 8022 } else if(SiS_Pr->SiS_VBType & VB_SISVB) { 8023 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return; 8024 } else return; 8025 8026 if(SiS_Pr->SiS_LCDInfo & LCDPass11) return; 8027 8028 if(SiS_Pr->ChipType < SIS_315H) { 8029 if(SiS_Pr->SiS_SetFlag & SetDOSMode) return; 8030 } 8031 8032 if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, 8033 &ResIndex, &DisplayType))) { 8034 return; 8035 } 8036 8037 switch(DisplayType) { 8038 case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_1; break; /* xSTN */ 8039 case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2; break; /* xSTN */ 8040 case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_2_H; break; /* xSTN */ 8041 case 18: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3; break; /* xSTN */ 8042 case 19: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x240_3_H; break; /* xSTN */ 8043 case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1; break; 8044 case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H; break; 8045 #if 0 /* Works better with calculated numbers */ 8046 case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1; break; 8047 case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H; break; 8048 case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2; break; 8049 case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H; break; 8050 #endif 8051 case 80: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC; break; 8052 case 81: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC; break; 8053 case 82: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL; break; 8054 case 83: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL; break; 8055 case 84: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL; break; 8056 } 8057 8058 if(LVDSCRT1Ptr) { 8059 8060 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); 8061 8062 for(i = 0; i <= 10; i++) { 8063 tempah = (LVDSCRT1Ptr + ResIndex)->CR[i]; 8064 SiS_SetReg(SiS_Pr->SiS_P3d4,CRIdx[i],tempah); 8065 } 8066 8067 for(i = 0x0A, j = 11; i <= 0x0C; i++, j++) { 8068 tempah = (LVDSCRT1Ptr + ResIndex)->CR[j]; 8069 SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah); 8070 } 8071 8072 tempah = (LVDSCRT1Ptr + ResIndex)->CR[14] & 0xE0; 8073 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah); 8074 8075 if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 8076 else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 8077 8078 tempah = ((LVDSCRT1Ptr + ResIndex)->CR[14] & 0x01) << 5; 8079 if(modeflag & DoubleScanMode) tempah |= 0x80; 8080 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah); 8081 8082 } else { 8083 8084 SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex); 8085 8086 } 8087 } 8088 8089 /*********************************************/ 8090 /* SET CRT2 ECLK */ 8091 /*********************************************/ 8092 8093 static void 8094 SiS_SetCRT2ECLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 8095 unsigned short RefreshRateTableIndex) 8096 { 8097 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 8098 unsigned short clkbase, vclkindex = 0; 8099 unsigned char sr2b, sr2c; 8100 8101 if(SiS_Pr->SiS_LCDInfo & LCDPass11) { 8102 SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2); 8103 if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK == 2) { 8104 RefreshRateTableIndex--; 8105 } 8106 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 8107 RefreshRateTableIndex); 8108 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 8109 } else { 8110 vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, 8111 RefreshRateTableIndex); 8112 } 8113 8114 sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B; 8115 sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C; 8116 8117 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 8118 if(SiS_Pr->SiS_UseROM) { 8119 if(ROMAddr[0x220] & 0x01) { 8120 sr2b = ROMAddr[0x227]; 8121 sr2c = ROMAddr[0x228]; 8122 } 8123 } 8124 } 8125 8126 clkbase = 0x02B; 8127 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) { 8128 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) { 8129 clkbase += 3; 8130 } 8131 } 8132 8133 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20); 8134 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 8135 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 8136 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10); 8137 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 8138 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 8139 SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00); 8140 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b); 8141 SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c); 8142 } 8143 8144 /*********************************************/ 8145 /* SET UP CHRONTEL CHIPS */ 8146 /*********************************************/ 8147 8148 static void 8149 SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 8150 unsigned short RefreshRateTableIndex) 8151 { 8152 unsigned short TVType, resindex; 8153 const struct SiS_CHTVRegData *CHTVRegData = NULL; 8154 8155 if(ModeNo <= 0x13) 8156 resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 8157 else 8158 resindex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; 8159 8160 resindex &= 0x3F; 8161 8162 TVType = 0; 8163 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8164 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 8165 TVType += 2; 8166 if(SiS_Pr->SiS_ModeType > ModeVGA) { 8167 if(SiS_Pr->SiS_CHSOverScan) TVType = 8; 8168 } 8169 if(SiS_Pr->SiS_TVMode & TVSetPALM) { 8170 TVType = 4; 8171 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8172 } else if(SiS_Pr->SiS_TVMode & TVSetPALN) { 8173 TVType = 6; 8174 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1; 8175 } 8176 } 8177 8178 switch(TVType) { 8179 case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break; 8180 case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break; 8181 case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break; 8182 case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8183 case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break; 8184 case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break; 8185 case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break; 8186 case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break; 8187 case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break; 8188 default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break; 8189 } 8190 8191 8192 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8193 8194 #ifdef CONFIG_FB_SIS_300 8195 8196 /* Chrontel 7005 - I assume that it does not come with a 315 series chip */ 8197 8198 /* We don't support modes >800x600 */ 8199 if (resindex > 5) return; 8200 8201 if(SiS_Pr->SiS_TVMode & TVSetPAL) { 8202 SiS_SetCH700x(SiS_Pr,0x04,0x43); /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/ 8203 SiS_SetCH700x(SiS_Pr,0x09,0x69); /* Black level for PAL (105)*/ 8204 } else { 8205 SiS_SetCH700x(SiS_Pr,0x04,0x03); /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/ 8206 SiS_SetCH700x(SiS_Pr,0x09,0x71); /* Black level for NTSC (113)*/ 8207 } 8208 8209 SiS_SetCH700x(SiS_Pr,0x00,CHTVRegData[resindex].Reg[0]); /* Mode register */ 8210 SiS_SetCH700x(SiS_Pr,0x07,CHTVRegData[resindex].Reg[1]); /* Start active video register */ 8211 SiS_SetCH700x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[2]); /* Position overflow register */ 8212 SiS_SetCH700x(SiS_Pr,0x0a,CHTVRegData[resindex].Reg[3]); /* Horiz Position register */ 8213 SiS_SetCH700x(SiS_Pr,0x0b,CHTVRegData[resindex].Reg[4]); /* Vertical Position register */ 8214 8215 /* Set minimum flicker filter for Luma channel (SR1-0=00), 8216 minimum text enhancement (S3-2=10), 8217 maximum flicker filter for Chroma channel (S5-4=10) 8218 =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!) 8219 */ 8220 SiS_SetCH700x(SiS_Pr,0x01,0x28); 8221 8222 /* Set video bandwidth 8223 High bandwidth Luma composite video filter(S0=1) 8224 low bandwidth Luma S-video filter (S2-1=00) 8225 disable peak filter in S-video channel (S3=0) 8226 high bandwidth Chroma Filter (S5-4=11) 8227 =00110001=0x31 8228 */ 8229 SiS_SetCH700x(SiS_Pr,0x03,0xb1); /* old: 3103 */ 8230 8231 /* Register 0x3D does not exist in non-macrovision register map 8232 (Maybe this is a macrovision register?) 8233 */ 8234 #ifndef SIS_CP 8235 SiS_SetCH70xx(SiS_Pr,0x3d,0x00); 8236 #endif 8237 8238 /* Register 0x10 only contains 1 writable bit (S0) for sensing, 8239 all other bits a read-only. Macrovision? 8240 */ 8241 SiS_SetCH70xxANDOR(SiS_Pr,0x10,0x00,0x1F); 8242 8243 /* Register 0x11 only contains 3 writable bits (S0-S2) for 8244 contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) ) 8245 */ 8246 SiS_SetCH70xxANDOR(SiS_Pr,0x11,0x02,0xF8); 8247 8248 /* Clear DSEN 8249 */ 8250 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xEF); 8251 8252 if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) { /* ---- NTSC ---- */ 8253 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) { 8254 if(resindex == 0x04) { /* 640x480 overscan: Mode 16 */ 8255 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8256 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); /* ACIV on, no need to set FSCI */ 8257 } else if(resindex == 0x05) { /* 800x600 overscan: Mode 23 */ 8258 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* 0x18-0x1f: FSCI 469,762,048 */ 8259 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x0C,0xF0); 8260 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x00,0xF0); 8261 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x00,0xF0); 8262 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x00,0xF0); 8263 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x00,0xF0); 8264 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x00,0xF0); 8265 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x00,0xF0); 8266 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x01,0xEF); /* Loop filter on for mode 23 */ 8267 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); /* ACIV off, need to set FSCI */ 8268 } 8269 } else { 8270 if(resindex == 0x04) { /* ----- 640x480 underscan; Mode 17 */ 8271 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8272 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); 8273 } else if(resindex == 0x05) { /* ----- 800x600 underscan: Mode 24 */ 8274 #if 0 8275 SiS_SetCH70xxANDOR(SiS_Pr,0x18,0x01,0xF0); /* (FSCI was 0x1f1c71c7 - this is for mode 22) */ 8276 SiS_SetCH70xxANDOR(SiS_Pr,0x19,0x09,0xF0); /* FSCI for mode 24 is 428,554,851 */ 8277 SiS_SetCH70xxANDOR(SiS_Pr,0x1a,0x08,0xF0); /* 198b3a63 */ 8278 SiS_SetCH70xxANDOR(SiS_Pr,0x1b,0x0b,0xF0); 8279 SiS_SetCH70xxANDOR(SiS_Pr,0x1c,0x04,0xF0); 8280 SiS_SetCH70xxANDOR(SiS_Pr,0x1d,0x01,0xF0); 8281 SiS_SetCH70xxANDOR(SiS_Pr,0x1e,0x06,0xF0); 8282 SiS_SetCH70xxANDOR(SiS_Pr,0x1f,0x05,0xF0); 8283 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off for mode 24 */ 8284 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x00,0xFE); * ACIV off, need to set FSCI */ 8285 #endif /* All alternatives wrong (datasheet wrong?), don't use FSCI */ 8286 SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF); /* loop filter off */ 8287 SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE); 8288 } 8289 } 8290 } else { /* ---- PAL ---- */ 8291 /* We don't play around with FSCI in PAL mode */ 8292 SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF); /* loop filter off */ 8293 SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE); /* ACIV on */ 8294 } 8295 8296 #endif /* 300 */ 8297 8298 } else { 8299 8300 /* Chrontel 7019 - assumed that it does not come with a 300 series chip */ 8301 8302 #ifdef CONFIG_FB_SIS_315 8303 8304 unsigned short temp; 8305 8306 /* We don't support modes >1024x768 */ 8307 if (resindex > 6) return; 8308 8309 temp = CHTVRegData[resindex].Reg[0]; 8310 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp |= 0x10; 8311 SiS_SetCH701x(SiS_Pr,0x00,temp); 8312 8313 SiS_SetCH701x(SiS_Pr,0x01,CHTVRegData[resindex].Reg[1]); 8314 SiS_SetCH701x(SiS_Pr,0x02,CHTVRegData[resindex].Reg[2]); 8315 SiS_SetCH701x(SiS_Pr,0x04,CHTVRegData[resindex].Reg[3]); 8316 SiS_SetCH701x(SiS_Pr,0x03,CHTVRegData[resindex].Reg[4]); 8317 SiS_SetCH701x(SiS_Pr,0x05,CHTVRegData[resindex].Reg[5]); 8318 SiS_SetCH701x(SiS_Pr,0x06,CHTVRegData[resindex].Reg[6]); 8319 8320 temp = CHTVRegData[resindex].Reg[7]; 8321 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 0x66; 8322 SiS_SetCH701x(SiS_Pr,0x07,temp); 8323 8324 SiS_SetCH701x(SiS_Pr,0x08,CHTVRegData[resindex].Reg[8]); 8325 SiS_SetCH701x(SiS_Pr,0x15,CHTVRegData[resindex].Reg[9]); 8326 SiS_SetCH701x(SiS_Pr,0x1f,CHTVRegData[resindex].Reg[10]); 8327 SiS_SetCH701x(SiS_Pr,0x0c,CHTVRegData[resindex].Reg[11]); 8328 SiS_SetCH701x(SiS_Pr,0x0d,CHTVRegData[resindex].Reg[12]); 8329 SiS_SetCH701x(SiS_Pr,0x0e,CHTVRegData[resindex].Reg[13]); 8330 SiS_SetCH701x(SiS_Pr,0x0f,CHTVRegData[resindex].Reg[14]); 8331 SiS_SetCH701x(SiS_Pr,0x10,CHTVRegData[resindex].Reg[15]); 8332 8333 temp = SiS_GetCH701x(SiS_Pr,0x21) & ~0x02; 8334 /* D1 should be set for PAL, PAL-N and NTSC-J, 8335 but I won't do that for PAL unless somebody 8336 tells me to do so. Since the BIOS uses 8337 non-default CIV values and blacklevels, 8338 this might be compensated anyway. 8339 */ 8340 if(SiS_Pr->SiS_TVMode & (TVSetPALN | TVSetNTSCJ)) temp |= 0x02; 8341 SiS_SetCH701x(SiS_Pr,0x21,temp); 8342 8343 #endif /* 315 */ 8344 8345 } 8346 8347 #ifdef SIS_CP 8348 SIS_CP_INIT301_CP3 8349 #endif 8350 8351 } 8352 8353 #ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */ 8354 8355 void 8356 SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr) 8357 { 8358 unsigned short temp; 8359 8360 /* Enable Chrontel 7019 LCD panel backlight */ 8361 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8362 if(SiS_Pr->ChipType == SIS_740) { 8363 SiS_SetCH701x(SiS_Pr,0x66,0x65); 8364 } else { 8365 temp = SiS_GetCH701x(SiS_Pr,0x66); 8366 temp |= 0x20; 8367 SiS_SetCH701x(SiS_Pr,0x66,temp); 8368 } 8369 } 8370 } 8371 8372 void 8373 SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr) 8374 { 8375 unsigned short temp; 8376 8377 /* Disable Chrontel 7019 LCD panel backlight */ 8378 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8379 temp = SiS_GetCH701x(SiS_Pr,0x66); 8380 temp &= 0xDF; 8381 SiS_SetCH701x(SiS_Pr,0x66,temp); 8382 } 8383 } 8384 8385 static void 8386 SiS_ChrontelPowerSequencing(struct SiS_Private *SiS_Pr) 8387 { 8388 static const unsigned char regtable[] = { 0x67, 0x68, 0x69, 0x6a, 0x6b }; 8389 static const unsigned char table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 }; 8390 static const unsigned char table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 }; 8391 static const unsigned char asus1024_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8392 static const unsigned char asus1400_740[] = { 0x19, 0x6e, 0x01, 0x19, 0x09 }; 8393 static const unsigned char table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8394 static const unsigned char table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 }; 8395 const unsigned char *tableptr = NULL; 8396 int i; 8397 8398 /* Set up Power up/down timing */ 8399 8400 if(SiS_Pr->ChipType == SIS_740) { 8401 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8402 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740; 8403 else tableptr = table1024_740; 8404 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8405 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8406 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8407 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740; 8408 else tableptr = table1400_740; 8409 } else return; 8410 } else { 8411 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 8412 tableptr = table1024_650; 8413 } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) || 8414 (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) || 8415 (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) { 8416 tableptr = table1400_650; 8417 } else return; 8418 } 8419 8420 for(i=0; i<5; i++) { 8421 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]); 8422 } 8423 } 8424 8425 static void 8426 SiS_SetCH701xForLCD(struct SiS_Private *SiS_Pr) 8427 { 8428 const unsigned char *tableptr = NULL; 8429 unsigned short tempbh; 8430 int i; 8431 static const unsigned char regtable[] = { 8432 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71, 8433 0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 8434 }; 8435 static const unsigned char table1024_740[] = { 8436 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, 8437 0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 8438 }; 8439 static const unsigned char table1280_740[] = { 8440 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8441 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 8442 }; 8443 static const unsigned char table1400_740[] = { 8444 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8445 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 8446 }; 8447 static const unsigned char table1600_740[] = { 8448 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, 8449 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 8450 }; 8451 static const unsigned char table1024_650[] = { 8452 0x60, 0x02, 0x00, 0x07, 0x40, 0xed, 8453 0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 8454 }; 8455 static const unsigned char table1280_650[] = { 8456 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3, 8457 0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 8458 }; 8459 static const unsigned char table1400_650[] = { 8460 0x60, 0x03, 0x11, 0x00, 0x40, 0xef, 8461 0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 8462 }; 8463 static const unsigned char table1600_650[] = { 8464 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3, 8465 0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a 8466 }; 8467 8468 if(SiS_Pr->ChipType == SIS_740) { 8469 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740; 8470 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740; 8471 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740; 8472 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740; 8473 else return; 8474 } else { 8475 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650; 8476 else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650; 8477 else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650; 8478 else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650; 8479 else return; 8480 } 8481 8482 tempbh = SiS_GetCH701x(SiS_Pr,0x74); 8483 if((tempbh == 0xf6) || (tempbh == 0xc7)) { 8484 tempbh = SiS_GetCH701x(SiS_Pr,0x73); 8485 if(tempbh == 0xc8) { 8486 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return; 8487 } else if(tempbh == 0xdb) { 8488 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return; 8489 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return; 8490 } else if(tempbh == 0xde) { 8491 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return; 8492 } 8493 } 8494 8495 if(SiS_Pr->ChipType == SIS_740) tempbh = 0x0d; 8496 else tempbh = 0x0c; 8497 8498 for(i = 0; i < tempbh; i++) { 8499 SiS_SetCH701x(SiS_Pr, regtable[i], tableptr[i]); 8500 } 8501 SiS_ChrontelPowerSequencing(SiS_Pr); 8502 tempbh = SiS_GetCH701x(SiS_Pr,0x1e); 8503 tempbh |= 0xc0; 8504 SiS_SetCH701x(SiS_Pr,0x1e,tempbh); 8505 8506 if(SiS_Pr->ChipType == SIS_740) { 8507 tempbh = SiS_GetCH701x(SiS_Pr,0x1c); 8508 tempbh &= 0xfb; 8509 SiS_SetCH701x(SiS_Pr,0x1c,tempbh); 8510 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8511 tempbh = SiS_GetCH701x(SiS_Pr,0x64); 8512 tempbh |= 0x40; 8513 SiS_SetCH701x(SiS_Pr,0x64,tempbh); 8514 tempbh = SiS_GetCH701x(SiS_Pr,0x03); 8515 tempbh &= 0x3f; 8516 SiS_SetCH701x(SiS_Pr,0x03,tempbh); 8517 } 8518 } 8519 8520 static void 8521 SiS_ChrontelResetVSync(struct SiS_Private *SiS_Pr) 8522 { 8523 unsigned char temp, temp1; 8524 8525 temp1 = SiS_GetCH701x(SiS_Pr,0x49); 8526 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 8527 temp = SiS_GetCH701x(SiS_Pr,0x47); 8528 temp &= 0x7f; /* Use external VSYNC */ 8529 SiS_SetCH701x(SiS_Pr,0x47,temp); 8530 SiS_LongDelay(SiS_Pr, 3); 8531 temp = SiS_GetCH701x(SiS_Pr,0x47); 8532 temp |= 0x80; /* Use internal VSYNC */ 8533 SiS_SetCH701x(SiS_Pr,0x47,temp); 8534 SiS_SetCH701x(SiS_Pr,0x49,temp1); 8535 } 8536 8537 static void 8538 SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr) 8539 { 8540 unsigned short temp; 8541 8542 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8543 if(SiS_Pr->ChipType == SIS_740) { 8544 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8545 temp |= 0x04; /* Invert XCLK phase */ 8546 SiS_SetCH701x(SiS_Pr,0x1c,temp); 8547 } 8548 if(SiS_IsYPbPr(SiS_Pr)) { 8549 temp = SiS_GetCH701x(SiS_Pr,0x01); 8550 temp &= 0x3f; 8551 temp |= 0x80; /* Enable YPrPb (HDTV) */ 8552 SiS_SetCH701x(SiS_Pr,0x01,temp); 8553 } 8554 if(SiS_IsChScart(SiS_Pr)) { 8555 temp = SiS_GetCH701x(SiS_Pr,0x01); 8556 temp &= 0x3f; 8557 temp |= 0xc0; /* Enable SCART + CVBS */ 8558 SiS_SetCH701x(SiS_Pr,0x01,temp); 8559 } 8560 if(SiS_Pr->ChipType == SIS_740) { 8561 SiS_ChrontelResetVSync(SiS_Pr); 8562 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */ 8563 } else { 8564 SiS_SetCH701x(SiS_Pr,0x49,0x20); /* Enable TV path */ 8565 temp = SiS_GetCH701x(SiS_Pr,0x49); 8566 if(SiS_IsYPbPr(SiS_Pr)) { 8567 temp = SiS_GetCH701x(SiS_Pr,0x73); 8568 temp |= 0x60; 8569 SiS_SetCH701x(SiS_Pr,0x73,temp); 8570 } 8571 temp = SiS_GetCH701x(SiS_Pr,0x47); 8572 temp &= 0x7f; 8573 SiS_SetCH701x(SiS_Pr,0x47,temp); 8574 SiS_LongDelay(SiS_Pr, 2); 8575 temp = SiS_GetCH701x(SiS_Pr,0x47); 8576 temp |= 0x80; 8577 SiS_SetCH701x(SiS_Pr,0x47,temp); 8578 } 8579 } 8580 } 8581 8582 static void 8583 SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr) 8584 { 8585 unsigned short temp; 8586 8587 /* Complete power down of LVDS */ 8588 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8589 if(SiS_Pr->ChipType == SIS_740) { 8590 SiS_LongDelay(SiS_Pr, 1); 8591 SiS_GenericDelay(SiS_Pr, 5887); 8592 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8593 SiS_SetCH701x(SiS_Pr,0x66,0x00); 8594 } else { 8595 SiS_LongDelay(SiS_Pr, 2); 8596 temp = SiS_GetCH701x(SiS_Pr,0x76); 8597 temp &= 0xfc; 8598 SiS_SetCH701x(SiS_Pr,0x76,temp); 8599 SiS_SetCH701x(SiS_Pr,0x66,0x00); 8600 } 8601 } 8602 } 8603 8604 static void 8605 SiS_ChrontelResetDB(struct SiS_Private *SiS_Pr) 8606 { 8607 unsigned short temp; 8608 8609 if(SiS_Pr->ChipType == SIS_740) { 8610 8611 temp = SiS_GetCH701x(SiS_Pr,0x4a); /* Version ID */ 8612 temp &= 0x01; 8613 if(!temp) { 8614 8615 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8616 temp = SiS_GetCH701x(SiS_Pr,0x49); 8617 SiS_SetCH701x(SiS_Pr,0x49,0x3e); 8618 } 8619 8620 /* Reset Chrontel 7019 datapath */ 8621 SiS_SetCH701x(SiS_Pr,0x48,0x10); 8622 SiS_LongDelay(SiS_Pr, 1); 8623 SiS_SetCH701x(SiS_Pr,0x48,0x18); 8624 8625 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8626 SiS_ChrontelResetVSync(SiS_Pr); 8627 SiS_SetCH701x(SiS_Pr,0x49,temp); 8628 } 8629 8630 } else { 8631 8632 /* Clear/set/clear GPIO */ 8633 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8634 temp &= 0xef; 8635 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8636 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8637 temp |= 0x10; 8638 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8639 temp = SiS_GetCH701x(SiS_Pr,0x5c); 8640 temp &= 0xef; 8641 SiS_SetCH701x(SiS_Pr,0x5c,temp); 8642 temp = SiS_GetCH701x(SiS_Pr,0x61); 8643 if(!temp) { 8644 SiS_SetCH701xForLCD(SiS_Pr); 8645 } 8646 } 8647 8648 } else { /* 650 */ 8649 /* Reset Chrontel 7019 datapath */ 8650 SiS_SetCH701x(SiS_Pr,0x48,0x10); 8651 SiS_LongDelay(SiS_Pr, 1); 8652 SiS_SetCH701x(SiS_Pr,0x48,0x18); 8653 } 8654 } 8655 8656 static void 8657 SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr) 8658 { 8659 unsigned short temp; 8660 8661 if(SiS_Pr->ChipType == SIS_740) { 8662 8663 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8664 SiS_ChrontelResetVSync(SiS_Pr); 8665 } 8666 8667 } else { 8668 8669 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* Power up LVDS block */ 8670 temp = SiS_GetCH701x(SiS_Pr,0x49); 8671 temp &= 1; 8672 if(temp != 1) { /* TV block powered? (0 = yes, 1 = no) */ 8673 temp = SiS_GetCH701x(SiS_Pr,0x47); 8674 temp &= 0x70; 8675 SiS_SetCH701x(SiS_Pr,0x47,temp); /* enable VSYNC */ 8676 SiS_LongDelay(SiS_Pr, 3); 8677 temp = SiS_GetCH701x(SiS_Pr,0x47); 8678 temp |= 0x80; 8679 SiS_SetCH701x(SiS_Pr,0x47,temp); /* disable VSYNC */ 8680 } 8681 8682 } 8683 } 8684 8685 static void 8686 SiS_ChrontelDoSomething3(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 8687 { 8688 unsigned short temp,temp1; 8689 8690 if(SiS_Pr->ChipType == SIS_740) { 8691 8692 temp = SiS_GetCH701x(SiS_Pr,0x61); 8693 if(temp < 1) { 8694 temp++; 8695 SiS_SetCH701x(SiS_Pr,0x61,temp); 8696 } 8697 SiS_SetCH701x(SiS_Pr,0x66,0x45); /* Panel power on */ 8698 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on */ 8699 SiS_LongDelay(SiS_Pr, 1); 8700 SiS_GenericDelay(SiS_Pr, 5887); 8701 8702 } else { /* 650 */ 8703 8704 temp1 = 0; 8705 temp = SiS_GetCH701x(SiS_Pr,0x61); 8706 if(temp < 2) { 8707 temp++; 8708 SiS_SetCH701x(SiS_Pr,0x61,temp); 8709 temp1 = 1; 8710 } 8711 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8712 temp = SiS_GetCH701x(SiS_Pr,0x66); 8713 temp |= 0x5f; 8714 SiS_SetCH701x(SiS_Pr,0x66,temp); 8715 if(ModeNo > 0x13) { 8716 if(SiS_WeHaveBacklightCtrl(SiS_Pr)) { 8717 SiS_GenericDelay(SiS_Pr, 1023); 8718 } else { 8719 SiS_GenericDelay(SiS_Pr, 767); 8720 } 8721 } else { 8722 if(!temp1) 8723 SiS_GenericDelay(SiS_Pr, 767); 8724 } 8725 temp = SiS_GetCH701x(SiS_Pr,0x76); 8726 temp |= 0x03; 8727 SiS_SetCH701x(SiS_Pr,0x76,temp); 8728 temp = SiS_GetCH701x(SiS_Pr,0x66); 8729 temp &= 0x7f; 8730 SiS_SetCH701x(SiS_Pr,0x66,temp); 8731 SiS_LongDelay(SiS_Pr, 1); 8732 8733 } 8734 } 8735 8736 static void 8737 SiS_ChrontelDoSomething2(struct SiS_Private *SiS_Pr) 8738 { 8739 unsigned short temp; 8740 8741 SiS_LongDelay(SiS_Pr, 1); 8742 8743 do { 8744 temp = SiS_GetCH701x(SiS_Pr,0x66); 8745 temp &= 0x04; /* PLL stable? -> bail out */ 8746 if(temp == 0x04) break; 8747 8748 if(SiS_Pr->ChipType == SIS_740) { 8749 /* Power down LVDS output, PLL normal operation */ 8750 SiS_SetCH701x(SiS_Pr,0x76,0xac); 8751 } 8752 8753 SiS_SetCH701xForLCD(SiS_Pr); 8754 8755 temp = SiS_GetCH701x(SiS_Pr,0x76); 8756 temp &= 0xfb; /* Reset PLL */ 8757 SiS_SetCH701x(SiS_Pr,0x76,temp); 8758 SiS_LongDelay(SiS_Pr, 2); 8759 temp = SiS_GetCH701x(SiS_Pr,0x76); 8760 temp |= 0x04; /* PLL normal operation */ 8761 SiS_SetCH701x(SiS_Pr,0x76,temp); 8762 if(SiS_Pr->ChipType == SIS_740) { 8763 SiS_SetCH701x(SiS_Pr,0x78,0xe0); /* PLL loop filter */ 8764 } else { 8765 SiS_SetCH701x(SiS_Pr,0x78,0x60); 8766 } 8767 SiS_LongDelay(SiS_Pr, 2); 8768 } while(0); 8769 8770 SiS_SetCH701x(SiS_Pr,0x77,0x00); /* MV? */ 8771 } 8772 8773 static void 8774 SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr) 8775 { 8776 unsigned short temp; 8777 8778 temp = SiS_GetCH701x(SiS_Pr,0x03); 8779 temp |= 0x80; /* Set datapath 1 to TV */ 8780 temp &= 0xbf; /* Set datapath 2 to LVDS */ 8781 SiS_SetCH701x(SiS_Pr,0x03,temp); 8782 8783 if(SiS_Pr->ChipType == SIS_740) { 8784 8785 temp = SiS_GetCH701x(SiS_Pr,0x1c); 8786 temp &= 0xfb; /* Normal XCLK phase */ 8787 SiS_SetCH701x(SiS_Pr,0x1c,temp); 8788 8789 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03); 8790 8791 temp = SiS_GetCH701x(SiS_Pr,0x64); 8792 temp |= 0x40; /* ? Bit not defined */ 8793 SiS_SetCH701x(SiS_Pr,0x64,temp); 8794 8795 temp = SiS_GetCH701x(SiS_Pr,0x03); 8796 temp &= 0x3f; /* D1 input to both LVDS and TV */ 8797 SiS_SetCH701x(SiS_Pr,0x03,temp); 8798 8799 if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) { 8800 SiS_SetCH701x(SiS_Pr,0x63,0x40); /* LVDS off */ 8801 SiS_LongDelay(SiS_Pr, 1); 8802 SiS_SetCH701x(SiS_Pr,0x63,0x00); /* LVDS on */ 8803 SiS_ChrontelResetDB(SiS_Pr); 8804 SiS_ChrontelDoSomething2(SiS_Pr); 8805 SiS_ChrontelDoSomething3(SiS_Pr, 0); 8806 } else { 8807 temp = SiS_GetCH701x(SiS_Pr,0x66); 8808 if(temp != 0x45) { 8809 SiS_ChrontelResetDB(SiS_Pr); 8810 SiS_ChrontelDoSomething2(SiS_Pr); 8811 SiS_ChrontelDoSomething3(SiS_Pr, 0); 8812 } 8813 } 8814 8815 } else { /* 650 */ 8816 8817 SiS_ChrontelResetDB(SiS_Pr); 8818 SiS_ChrontelDoSomething2(SiS_Pr); 8819 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34); 8820 SiS_ChrontelDoSomething3(SiS_Pr,temp); 8821 SiS_SetCH701x(SiS_Pr,0x76,0xaf); /* All power on, LVDS normal operation */ 8822 8823 } 8824 8825 } 8826 #endif /* 315 series */ 8827 8828 /*********************************************/ 8829 /* MAIN: SET CRT2 REGISTER GROUP */ 8830 /*********************************************/ 8831 8832 bool 8833 SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 8834 { 8835 #ifdef CONFIG_FB_SIS_300 8836 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 8837 #endif 8838 unsigned short ModeIdIndex, RefreshRateTableIndex; 8839 8840 SiS_Pr->SiS_SetFlag |= ProgrammingCRT2; 8841 8842 if(!SiS_Pr->UseCustomMode) { 8843 SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex); 8844 } else { 8845 ModeIdIndex = 0; 8846 } 8847 8848 /* Used for shifting CR33 */ 8849 SiS_Pr->SiS_SelectCRT2Rate = 4; 8850 8851 SiS_UnLockCRT2(SiS_Pr); 8852 8853 RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex); 8854 8855 SiS_SaveCRT2Info(SiS_Pr,ModeNo); 8856 8857 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8858 SiS_DisableBridge(SiS_Pr); 8859 if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->ChipType == SIS_730)) { 8860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80); 8861 } 8862 SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex); 8863 } 8864 8865 if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) { 8866 SiS_LockCRT2(SiS_Pr); 8867 SiS_DisplayOn(SiS_Pr); 8868 return true; 8869 } 8870 8871 SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8872 8873 /* Set up Panel Link for LVDS and LCDA */ 8874 SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0; 8875 if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) || 8876 ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) || 8877 ((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS30xBLV)) ) { 8878 SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8879 } 8880 8881 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8882 SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8883 } 8884 8885 if(SiS_Pr->SiS_VBType & VB_SISVB) { 8886 8887 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8888 8889 SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8890 #ifdef CONFIG_FB_SIS_315 8891 SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8892 #endif 8893 SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex); 8894 SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8895 #ifdef CONFIG_FB_SIS_315 8896 SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex); 8897 #endif 8898 SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex); 8899 8900 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex); 8901 8902 /* For 301BDH (Panel link initialization): */ 8903 if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) { 8904 8905 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) { 8906 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) { 8907 SiS_ModCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8908 } 8909 } 8910 SiS_SetCRT2ECLK(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8911 } 8912 } 8913 8914 } else { 8915 8916 SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex); 8917 8918 SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8919 8920 SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8921 8922 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8923 if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) { 8924 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 8925 if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) { 8926 #ifdef CONFIG_FB_SIS_315 8927 SiS_SetCH701xForLCD(SiS_Pr); 8928 #endif 8929 } 8930 } 8931 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8932 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex); 8933 } 8934 } 8935 } 8936 8937 } 8938 8939 #ifdef CONFIG_FB_SIS_300 8940 if(SiS_Pr->ChipType < SIS_315H) { 8941 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8942 if(SiS_Pr->SiS_UseOEM) { 8943 if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) { 8944 if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) { 8945 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8946 } 8947 } else { 8948 SiS_OEM300Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8949 } 8950 } 8951 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 8952 if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || 8953 (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) { 8954 SetOEMLCDData2(SiS_Pr, ModeNo, ModeIdIndex,RefreshRateTableIndex); 8955 } 8956 SiS_DisplayOn(SiS_Pr); 8957 } 8958 } 8959 } 8960 #endif 8961 8962 #ifdef CONFIG_FB_SIS_315 8963 if(SiS_Pr->ChipType >= SIS_315H) { 8964 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8965 if(SiS_Pr->ChipType < SIS_661) { 8966 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex); 8967 SiS_OEM310Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8968 } else { 8969 SiS_OEM661Setting(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex); 8970 } 8971 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40); 8972 } 8973 } 8974 #endif 8975 8976 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8977 SiS_EnableBridge(SiS_Pr); 8978 } 8979 8980 SiS_DisplayOn(SiS_Pr); 8981 8982 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) { 8983 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 8984 /* Disable LCD panel when using TV */ 8985 SiS_SetRegSR11ANDOR(SiS_Pr,0xFF,0x0C); 8986 } else { 8987 /* Disable TV when using LCD */ 8988 SiS_SetCH70xxANDOR(SiS_Pr,0x0e,0x01,0xf8); 8989 } 8990 } 8991 8992 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 8993 SiS_LockCRT2(SiS_Pr); 8994 } 8995 8996 return true; 8997 } 8998 8999 9000 /*********************************************/ 9001 /* ENABLE/DISABLE LCD BACKLIGHT (SIS) */ 9002 /*********************************************/ 9003 9004 void 9005 SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr) 9006 { 9007 /* Switch on LCD backlight on SiS30xLV */ 9008 SiS_DDC2Delay(SiS_Pr,0xff00); 9009 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) { 9010 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02); 9011 SiS_WaitVBRetrace(SiS_Pr); 9012 } 9013 if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) { 9014 SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01); 9015 } 9016 } 9017 9018 void 9019 SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr) 9020 { 9021 /* Switch off LCD backlight on SiS30xLV */ 9022 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE); 9023 SiS_DDC2Delay(SiS_Pr,0xff00); 9024 } 9025 9026 /*********************************************/ 9027 /* DDC RELATED FUNCTIONS */ 9028 /*********************************************/ 9029 9030 static void 9031 SiS_SetupDDCN(struct SiS_Private *SiS_Pr) 9032 { 9033 SiS_Pr->SiS_DDC_NData = ~SiS_Pr->SiS_DDC_Data; 9034 SiS_Pr->SiS_DDC_NClk = ~SiS_Pr->SiS_DDC_Clk; 9035 if((SiS_Pr->SiS_DDC_Index == 0x11) && (SiS_Pr->SiS_SensibleSR11)) { 9036 SiS_Pr->SiS_DDC_NData &= 0x0f; 9037 SiS_Pr->SiS_DDC_NClk &= 0x0f; 9038 } 9039 } 9040 9041 #ifdef CONFIG_FB_SIS_300 9042 static unsigned char * 9043 SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr) 9044 { 9045 int i, j, num; 9046 unsigned short tempah,temp; 9047 unsigned char *mydataptr; 9048 9049 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 9050 mydataptr = dataptr; 9051 num = *mydataptr++; 9052 if(!num) return mydataptr; 9053 if(i) { 9054 SiS_SetStop(SiS_Pr); 9055 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 2); 9056 } 9057 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9058 tempah = SiS_Pr->SiS_DDC_DeviceAddr; 9059 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */ 9060 if(temp) continue; /* (ERROR: no ack) */ 9061 tempah = *mydataptr++; 9062 temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */ 9063 if(temp) continue; /* (ERROR: no ack) */ 9064 for(j=0; j<num; j++) { 9065 tempah = *mydataptr++; 9066 temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */ 9067 if(temp) break; 9068 } 9069 if(temp) continue; 9070 if(SiS_SetStop(SiS_Pr)) continue; 9071 return mydataptr; 9072 } 9073 return NULL; 9074 } 9075 9076 static bool 9077 SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr) 9078 { 9079 SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */ 9080 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9081 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9082 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9083 SiS_SetupDDCN(SiS_Pr); 9084 9085 SiS_SetSwitchDDC2(SiS_Pr); 9086 9087 while(*dataptr) { 9088 dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr); 9089 if(!dataptr) return false; 9090 } 9091 return true; 9092 } 9093 #endif 9094 9095 /* The Chrontel 700x is connected to the 630/730 via 9096 * the 630/730's DDC/I2C port. 9097 * 9098 * On 630(S)T chipset, the index changed from 0x11 to 9099 * 0x0a, possibly for working around the DDC problems 9100 */ 9101 9102 static bool 9103 SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor) 9104 { 9105 unsigned short temp, i; 9106 9107 for(i=0; i<20; i++) { /* Do 20 attempts to write */ 9108 if(i) { 9109 SiS_SetStop(SiS_Pr); 9110 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4); 9111 } 9112 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9113 temp = SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */ 9114 if(temp) continue; /* (ERROR: no ack) */ 9115 temp = SiS_WriteDDC2Data(SiS_Pr, (reg | myor)); /* Write RAB (700x: set bit 7, see datasheet) */ 9116 if(temp) continue; /* (ERROR: no ack) */ 9117 temp = SiS_WriteDDC2Data(SiS_Pr, val); /* Write data */ 9118 if(temp) continue; /* (ERROR: no ack) */ 9119 if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */ 9120 SiS_Pr->SiS_ChrontelInit = 1; 9121 return true; 9122 } 9123 return false; 9124 } 9125 9126 /* Write to Chrontel 700x */ 9127 void 9128 SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9129 { 9130 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 9131 9132 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9133 9134 if(!(SiS_Pr->SiS_ChrontelInit)) { 9135 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9136 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9137 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9138 SiS_SetupDDCN(SiS_Pr); 9139 } 9140 9141 if( (!(SiS_SetChReg(SiS_Pr, reg, val, 0x80))) && 9142 (!(SiS_Pr->SiS_ChrontelInit)) ) { 9143 SiS_Pr->SiS_DDC_Index = 0x0a; 9144 SiS_Pr->SiS_DDC_Data = 0x80; 9145 SiS_Pr->SiS_DDC_Clk = 0x40; 9146 SiS_SetupDDCN(SiS_Pr); 9147 9148 SiS_SetChReg(SiS_Pr, reg, val, 0x80); 9149 } 9150 } 9151 9152 /* Write to Chrontel 701x */ 9153 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */ 9154 void 9155 SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9156 { 9157 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9158 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9159 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9160 SiS_SetupDDCN(SiS_Pr); 9161 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */ 9162 SiS_SetChReg(SiS_Pr, reg, val, 0); 9163 } 9164 9165 static 9166 void 9167 SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val) 9168 { 9169 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9170 SiS_SetCH700x(SiS_Pr, reg, val); 9171 else 9172 SiS_SetCH701x(SiS_Pr, reg, val); 9173 } 9174 9175 static unsigned short 9176 SiS_GetChReg(struct SiS_Private *SiS_Pr, unsigned short myor) 9177 { 9178 unsigned short tempah, temp, i; 9179 9180 for(i=0; i<20; i++) { /* Do 20 attempts to read */ 9181 if(i) { 9182 SiS_SetStop(SiS_Pr); 9183 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT * 4); 9184 } 9185 if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */ 9186 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr); /* Write DAB (S0=0=write) */ 9187 if(temp) continue; /* (ERROR: no ack) */ 9188 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_ReadAddr | myor); /* Write RAB (700x: | 0x80) */ 9189 if(temp) continue; /* (ERROR: no ack) */ 9190 if (SiS_SetStart(SiS_Pr)) continue; /* Re-start */ 9191 temp = SiS_WriteDDC2Data(SiS_Pr,SiS_Pr->SiS_DDC_DeviceAddr | 0x01);/* DAB (S0=1=read) */ 9192 if(temp) continue; /* (ERROR: no ack) */ 9193 tempah = SiS_ReadDDC2Data(SiS_Pr); /* Read byte */ 9194 if(SiS_SetStop(SiS_Pr)) continue; /* Stop condition */ 9195 SiS_Pr->SiS_ChrontelInit = 1; 9196 return tempah; 9197 } 9198 return 0xFFFF; 9199 } 9200 9201 /* Read from Chrontel 700x */ 9202 /* Parameter is [Register no (S7-S0)] */ 9203 unsigned short 9204 SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9205 { 9206 unsigned short result; 9207 9208 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9209 9210 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9211 9212 if(!(SiS_Pr->SiS_ChrontelInit)) { 9213 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9214 SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */ 9215 SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */ 9216 SiS_SetupDDCN(SiS_Pr); 9217 } 9218 9219 SiS_Pr->SiS_DDC_ReadAddr = tempbx; 9220 9221 if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) && 9222 (!SiS_Pr->SiS_ChrontelInit) ) { 9223 9224 SiS_Pr->SiS_DDC_Index = 0x0a; 9225 SiS_Pr->SiS_DDC_Data = 0x80; 9226 SiS_Pr->SiS_DDC_Clk = 0x40; 9227 SiS_SetupDDCN(SiS_Pr); 9228 9229 result = SiS_GetChReg(SiS_Pr,0x80); 9230 } 9231 return result; 9232 } 9233 9234 /* Read from Chrontel 701x */ 9235 /* Parameter is [Register no (S7-S0)] */ 9236 unsigned short 9237 SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9238 { 9239 SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */ 9240 SiS_Pr->SiS_DDC_Data = 0x08; /* Bitmask in IndexReg for Data */ 9241 SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */ 9242 SiS_SetupDDCN(SiS_Pr); 9243 SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB */ 9244 9245 SiS_Pr->SiS_DDC_ReadAddr = tempbx; 9246 9247 return SiS_GetChReg(SiS_Pr,0); 9248 } 9249 9250 /* Read from Chrontel 70xx */ 9251 /* Parameter is [Register no (S7-S0)] */ 9252 static 9253 unsigned short 9254 SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx) 9255 { 9256 if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) 9257 return SiS_GetCH700x(SiS_Pr, tempbx); 9258 else 9259 return SiS_GetCH701x(SiS_Pr, tempbx); 9260 } 9261 9262 void 9263 SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg, 9264 unsigned char myor, unsigned short myand) 9265 { 9266 unsigned short tempbl; 9267 9268 tempbl = (SiS_GetCH70xx(SiS_Pr, (reg & 0xFF)) & myand) | myor; 9269 SiS_SetCH70xx(SiS_Pr, reg, tempbl); 9270 } 9271 9272 /* Our own DDC functions */ 9273 static 9274 unsigned short 9275 SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, 9276 unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32, 9277 unsigned int VBFlags2) 9278 { 9279 unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 }; 9280 unsigned char flag, cr32; 9281 unsigned short temp = 0, myadaptnum = adaptnum; 9282 9283 if(adaptnum != 0) { 9284 if(!(VBFlags2 & VB2_SISTMDSBRIDGE)) return 0xFFFF; 9285 if((VBFlags2 & VB2_30xBDH) && (adaptnum == 1)) return 0xFFFF; 9286 } 9287 9288 /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */ 9289 9290 SiS_Pr->SiS_ChrontelInit = 0; /* force re-detection! */ 9291 9292 SiS_Pr->SiS_DDC_SecAddr = 0; 9293 SiS_Pr->SiS_DDC_DeviceAddr = ddcdtype[DDCdatatype]; 9294 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_P3c4; 9295 SiS_Pr->SiS_DDC_Index = 0x11; 9296 flag = 0xff; 9297 9298 cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32); 9299 9300 #if 0 9301 if(VBFlags2 & VB2_SISBRIDGE) { 9302 if(myadaptnum == 0) { 9303 if(!(cr32 & 0x20)) { 9304 myadaptnum = 2; 9305 if(!(cr32 & 0x10)) { 9306 myadaptnum = 1; 9307 if(!(cr32 & 0x08)) { 9308 myadaptnum = 0; 9309 } 9310 } 9311 } 9312 } 9313 } 9314 #endif 9315 9316 if(VGAEngine == SIS_300_VGA) { /* 300 series */ 9317 9318 if(myadaptnum != 0) { 9319 flag = 0; 9320 if(VBFlags2 & VB2_SISBRIDGE) { 9321 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9322 SiS_Pr->SiS_DDC_Index = 0x0f; 9323 } 9324 } 9325 9326 if(!(VBFlags2 & VB2_301)) { 9327 if((cr32 & 0x80) && (checkcr32)) { 9328 if(myadaptnum >= 1) { 9329 if(!(cr32 & 0x08)) { 9330 myadaptnum = 1; 9331 if(!(cr32 & 0x10)) return 0xFFFF; 9332 } 9333 } 9334 } 9335 } 9336 9337 temp = 4 - (myadaptnum * 2); 9338 if(flag) temp = 0; 9339 9340 } else { /* 315/330 series */ 9341 9342 /* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */ 9343 9344 if(VBFlags2 & VB2_SISBRIDGE) { 9345 if(myadaptnum == 2) { 9346 myadaptnum = 1; 9347 } 9348 } 9349 9350 if(myadaptnum == 1) { 9351 flag = 0; 9352 if(VBFlags2 & VB2_SISBRIDGE) { 9353 SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port; 9354 SiS_Pr->SiS_DDC_Index = 0x0f; 9355 } 9356 } 9357 9358 if((cr32 & 0x80) && (checkcr32)) { 9359 if(myadaptnum >= 1) { 9360 if(!(cr32 & 0x08)) { 9361 myadaptnum = 1; 9362 if(!(cr32 & 0x10)) return 0xFFFF; 9363 } 9364 } 9365 } 9366 9367 temp = myadaptnum; 9368 if(myadaptnum == 1) { 9369 temp = 0; 9370 if(VBFlags2 & VB2_LVDS) flag = 0xff; 9371 } 9372 9373 if(flag) temp = 0; 9374 } 9375 9376 SiS_Pr->SiS_DDC_Data = 0x02 << temp; 9377 SiS_Pr->SiS_DDC_Clk = 0x01 << temp; 9378 9379 SiS_SetupDDCN(SiS_Pr); 9380 9381 return 0; 9382 } 9383 9384 static unsigned short 9385 SiS_WriteDABDDC(struct SiS_Private *SiS_Pr) 9386 { 9387 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9388 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) { 9389 return 0xFFFF; 9390 } 9391 if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) { 9392 return 0xFFFF; 9393 } 9394 return 0; 9395 } 9396 9397 static unsigned short 9398 SiS_PrepareReadDDC(struct SiS_Private *SiS_Pr) 9399 { 9400 if(SiS_SetStart(SiS_Pr)) return 0xFFFF; 9401 if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) { 9402 return 0xFFFF; 9403 } 9404 return 0; 9405 } 9406 9407 static unsigned short 9408 SiS_PrepareDDC(struct SiS_Private *SiS_Pr) 9409 { 9410 if(SiS_WriteDABDDC(SiS_Pr)) SiS_WriteDABDDC(SiS_Pr); 9411 if(SiS_PrepareReadDDC(SiS_Pr)) return (SiS_PrepareReadDDC(SiS_Pr)); 9412 return 0; 9413 } 9414 9415 static void 9416 SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno) 9417 { 9418 SiS_SetSCLKLow(SiS_Pr); 9419 if(yesno) { 9420 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9421 SiS_Pr->SiS_DDC_Index, 9422 SiS_Pr->SiS_DDC_NData, 9423 SiS_Pr->SiS_DDC_Data); 9424 } else { 9425 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9426 SiS_Pr->SiS_DDC_Index, 9427 SiS_Pr->SiS_DDC_NData, 9428 0); 9429 } 9430 SiS_SetSCLKHigh(SiS_Pr); 9431 } 9432 9433 static unsigned short 9434 SiS_DoProbeDDC(struct SiS_Private *SiS_Pr) 9435 { 9436 unsigned char mask, value; 9437 unsigned short temp, ret=0; 9438 bool failed = false; 9439 9440 SiS_SetSwitchDDC2(SiS_Pr); 9441 if(SiS_PrepareDDC(SiS_Pr)) { 9442 SiS_SetStop(SiS_Pr); 9443 return 0xFFFF; 9444 } 9445 mask = 0xf0; 9446 value = 0x20; 9447 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9448 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9449 SiS_SendACK(SiS_Pr, 0); 9450 if(temp == 0) { 9451 mask = 0xff; 9452 value = 0xff; 9453 } else { 9454 failed = true; 9455 ret = 0xFFFF; 9456 } 9457 } 9458 if(!failed) { 9459 temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9460 SiS_SendACK(SiS_Pr, 1); 9461 temp &= mask; 9462 if(temp == value) ret = 0; 9463 else { 9464 ret = 0xFFFF; 9465 if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) { 9466 if(temp == 0x30) ret = 0; 9467 } 9468 } 9469 } 9470 SiS_SetStop(SiS_Pr); 9471 return ret; 9472 } 9473 9474 static 9475 unsigned short 9476 SiS_ProbeDDC(struct SiS_Private *SiS_Pr) 9477 { 9478 unsigned short flag; 9479 9480 flag = 0x180; 9481 SiS_Pr->SiS_DDC_DeviceAddr = 0xa0; 9482 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x02; 9483 SiS_Pr->SiS_DDC_DeviceAddr = 0xa2; 9484 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x08; 9485 SiS_Pr->SiS_DDC_DeviceAddr = 0xa6; 9486 if(!(SiS_DoProbeDDC(SiS_Pr))) flag |= 0x10; 9487 if(!(flag & 0x1a)) flag = 0; 9488 return flag; 9489 } 9490 9491 static 9492 unsigned short 9493 SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer) 9494 { 9495 unsigned short flag, length, i; 9496 unsigned char chksum,gotcha; 9497 9498 if(DDCdatatype > 4) return 0xFFFF; 9499 9500 flag = 0; 9501 SiS_SetSwitchDDC2(SiS_Pr); 9502 if(!(SiS_PrepareDDC(SiS_Pr))) { 9503 length = 127; 9504 if(DDCdatatype != 1) length = 255; 9505 chksum = 0; 9506 gotcha = 0; 9507 for(i=0; i<length; i++) { 9508 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9509 chksum += buffer[i]; 9510 gotcha |= buffer[i]; 9511 SiS_SendACK(SiS_Pr, 0); 9512 } 9513 buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr); 9514 chksum += buffer[i]; 9515 SiS_SendACK(SiS_Pr, 1); 9516 if(gotcha) flag = (unsigned short)chksum; 9517 else flag = 0xFFFF; 9518 } else { 9519 flag = 0xFFFF; 9520 } 9521 SiS_SetStop(SiS_Pr); 9522 return flag; 9523 } 9524 9525 /* Our private DDC functions 9526 9527 It complies somewhat with the corresponding VESA function 9528 in arguments and return values. 9529 9530 Since this is probably called before the mode is changed, 9531 we use our pre-detected pSiS-values instead of SiS_Pr as 9532 regards chipset and video bridge type. 9533 9534 Arguments: 9535 adaptnum: 0=CRT1(analog), 1=CRT2/LCD(digital), 2=CRT2/VGA2(analog) 9536 CRT2 DDC is only supported on SiS301, 301B, 301C, 302B. 9537 LCDA is CRT1, but DDC is read from CRT2 port. 9538 DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2) 9539 buffer: ptr to 256 data bytes which will be filled with read data. 9540 9541 Returns 0xFFFF if error, otherwise 9542 if DDCdatatype > 0: Returns 0 if reading OK (included a correct checksum) 9543 if DDCdatatype = 0: Returns supported DDC modes 9544 9545 */ 9546 unsigned short 9547 SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine, 9548 unsigned short adaptnum, unsigned short DDCdatatype, unsigned char *buffer, 9549 unsigned int VBFlags2) 9550 { 9551 unsigned char sr1f, cr17=1; 9552 unsigned short result; 9553 9554 if(adaptnum > 2) 9555 return 0xFFFF; 9556 9557 if(DDCdatatype > 4) 9558 return 0xFFFF; 9559 9560 if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0)) 9561 return 0xFFFF; 9562 9563 if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF) 9564 return 0xFFFF; 9565 9566 sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f); 9567 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04); 9568 if(VGAEngine == SIS_300_VGA) { 9569 cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80; 9570 if(!cr17) { 9571 SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80); 9572 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01); 9573 SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03); 9574 } 9575 } 9576 if((sr1f) || (!cr17)) { 9577 SiS_WaitRetrace1(SiS_Pr); 9578 SiS_WaitRetrace1(SiS_Pr); 9579 SiS_WaitRetrace1(SiS_Pr); 9580 SiS_WaitRetrace1(SiS_Pr); 9581 } 9582 9583 if(DDCdatatype == 0) { 9584 result = SiS_ProbeDDC(SiS_Pr); 9585 } else { 9586 result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer); 9587 if((!result) && (DDCdatatype == 1)) { 9588 if((buffer[0] == 0x00) && (buffer[1] == 0xff) && 9589 (buffer[2] == 0xff) && (buffer[3] == 0xff) && 9590 (buffer[4] == 0xff) && (buffer[5] == 0xff) && 9591 (buffer[6] == 0xff) && (buffer[7] == 0x00) && 9592 (buffer[0x12] == 1)) { 9593 if(!SiS_Pr->DDCPortMixup) { 9594 if(adaptnum == 1) { 9595 if(!(buffer[0x14] & 0x80)) result = 0xFFFE; 9596 } else { 9597 if(buffer[0x14] & 0x80) result = 0xFFFE; 9598 } 9599 } 9600 } 9601 } 9602 } 9603 SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f); 9604 if(VGAEngine == SIS_300_VGA) { 9605 SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17); 9606 } 9607 return result; 9608 } 9609 9610 /* Generic I2C functions for Chrontel & DDC --------- */ 9611 9612 static void 9613 SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr) 9614 { 9615 SiS_SetSCLKHigh(SiS_Pr); 9616 SiS_WaitRetrace1(SiS_Pr); 9617 9618 SiS_SetSCLKLow(SiS_Pr); 9619 SiS_WaitRetrace1(SiS_Pr); 9620 } 9621 9622 unsigned short 9623 SiS_ReadDDC1Bit(struct SiS_Private *SiS_Pr) 9624 { 9625 SiS_WaitRetrace1(SiS_Pr); 9626 return ((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1); 9627 } 9628 9629 /* Set I2C start condition */ 9630 /* This is done by a SD high-to-low transition while SC is high */ 9631 static unsigned short 9632 SiS_SetStart(struct SiS_Private *SiS_Pr) 9633 { 9634 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9635 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9636 SiS_Pr->SiS_DDC_Index, 9637 SiS_Pr->SiS_DDC_NData, 9638 SiS_Pr->SiS_DDC_Data); /* SD->high */ 9639 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9640 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9641 SiS_Pr->SiS_DDC_Index, 9642 SiS_Pr->SiS_DDC_NData, 9643 0x00); /* SD->low = start condition */ 9644 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9645 return 0; 9646 } 9647 9648 /* Set I2C stop condition */ 9649 /* This is done by a SD low-to-high transition while SC is high */ 9650 static unsigned short 9651 SiS_SetStop(struct SiS_Private *SiS_Pr) 9652 { 9653 if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF; /* (SC->low) */ 9654 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9655 SiS_Pr->SiS_DDC_Index, 9656 SiS_Pr->SiS_DDC_NData, 9657 0x00); /* SD->low */ 9658 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* SC->high */ 9659 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9660 SiS_Pr->SiS_DDC_Index, 9661 SiS_Pr->SiS_DDC_NData, 9662 SiS_Pr->SiS_DDC_Data); /* SD->high = stop condition */ 9663 if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF; /* (SC->high) */ 9664 return 0; 9665 } 9666 9667 /* Write 8 bits of data */ 9668 static unsigned short 9669 SiS_WriteDDC2Data(struct SiS_Private *SiS_Pr, unsigned short tempax) 9670 { 9671 unsigned short i,flag,temp; 9672 9673 flag = 0x80; 9674 for(i = 0; i < 8; i++) { 9675 SiS_SetSCLKLow(SiS_Pr); /* SC->low */ 9676 if(tempax & flag) { 9677 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9678 SiS_Pr->SiS_DDC_Index, 9679 SiS_Pr->SiS_DDC_NData, 9680 SiS_Pr->SiS_DDC_Data); /* Write bit (1) to SD */ 9681 } else { 9682 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9683 SiS_Pr->SiS_DDC_Index, 9684 SiS_Pr->SiS_DDC_NData, 9685 0x00); /* Write bit (0) to SD */ 9686 } 9687 SiS_SetSCLKHigh(SiS_Pr); /* SC->high */ 9688 flag >>= 1; 9689 } 9690 temp = SiS_CheckACK(SiS_Pr); /* Check acknowledge */ 9691 return temp; 9692 } 9693 9694 static unsigned short 9695 SiS_ReadDDC2Data(struct SiS_Private *SiS_Pr) 9696 { 9697 unsigned short i, temp, getdata; 9698 9699 getdata = 0; 9700 for(i = 0; i < 8; i++) { 9701 getdata <<= 1; 9702 SiS_SetSCLKLow(SiS_Pr); 9703 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9704 SiS_Pr->SiS_DDC_Index, 9705 SiS_Pr->SiS_DDC_NData, 9706 SiS_Pr->SiS_DDC_Data); 9707 SiS_SetSCLKHigh(SiS_Pr); 9708 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9709 if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01; 9710 } 9711 return getdata; 9712 } 9713 9714 static unsigned short 9715 SiS_SetSCLKLow(struct SiS_Private *SiS_Pr) 9716 { 9717 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9718 SiS_Pr->SiS_DDC_Index, 9719 SiS_Pr->SiS_DDC_NClk, 9720 0x00); /* SetSCLKLow() */ 9721 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9722 return 0; 9723 } 9724 9725 static unsigned short 9726 SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr) 9727 { 9728 unsigned short temp, watchdog=1000; 9729 9730 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9731 SiS_Pr->SiS_DDC_Index, 9732 SiS_Pr->SiS_DDC_NClk, 9733 SiS_Pr->SiS_DDC_Clk); /* SetSCLKHigh() */ 9734 do { 9735 temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); 9736 } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog); 9737 if (!watchdog) { 9738 return 0xFFFF; 9739 } 9740 SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT); 9741 return 0; 9742 } 9743 9744 /* Check I2C acknowledge */ 9745 /* Returns 0 if ack ok, non-0 if ack not ok */ 9746 static unsigned short 9747 SiS_CheckACK(struct SiS_Private *SiS_Pr) 9748 { 9749 unsigned short tempah; 9750 9751 SiS_SetSCLKLow(SiS_Pr); /* (SC->low) */ 9752 SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port, 9753 SiS_Pr->SiS_DDC_Index, 9754 SiS_Pr->SiS_DDC_NData, 9755 SiS_Pr->SiS_DDC_Data); /* (SD->high) */ 9756 SiS_SetSCLKHigh(SiS_Pr); /* SC->high = clock impulse for ack */ 9757 tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index); /* Read SD */ 9758 SiS_SetSCLKLow(SiS_Pr); /* SC->low = end of clock impulse */ 9759 if(tempah & SiS_Pr->SiS_DDC_Data) return 1; /* Ack OK if bit = 0 */ 9760 return 0; 9761 } 9762 9763 /* End of I2C functions ----------------------- */ 9764 9765 9766 /* =============== SiS 315/330 O.E.M. ================= */ 9767 9768 #ifdef CONFIG_FB_SIS_315 9769 9770 static unsigned short 9771 GetRAMDACromptr(struct SiS_Private *SiS_Pr) 9772 { 9773 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9774 unsigned short romptr; 9775 9776 if(SiS_Pr->ChipType < SIS_330) { 9777 romptr = SISGETROMW(0x128); 9778 if(SiS_Pr->SiS_VBType & VB_SIS30xB) 9779 romptr = SISGETROMW(0x12a); 9780 } else { 9781 romptr = SISGETROMW(0x1a8); 9782 if(SiS_Pr->SiS_VBType & VB_SIS30xB) 9783 romptr = SISGETROMW(0x1aa); 9784 } 9785 return romptr; 9786 } 9787 9788 static unsigned short 9789 GetLCDromptr(struct SiS_Private *SiS_Pr) 9790 { 9791 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9792 unsigned short romptr; 9793 9794 if(SiS_Pr->ChipType < SIS_330) { 9795 romptr = SISGETROMW(0x120); 9796 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9797 romptr = SISGETROMW(0x122); 9798 } else { 9799 romptr = SISGETROMW(0x1a0); 9800 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9801 romptr = SISGETROMW(0x1a2); 9802 } 9803 return romptr; 9804 } 9805 9806 static unsigned short 9807 GetTVromptr(struct SiS_Private *SiS_Pr) 9808 { 9809 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9810 unsigned short romptr; 9811 9812 if(SiS_Pr->ChipType < SIS_330) { 9813 romptr = SISGETROMW(0x114); 9814 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9815 romptr = SISGETROMW(0x11a); 9816 } else { 9817 romptr = SISGETROMW(0x194); 9818 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) 9819 romptr = SISGETROMW(0x19a); 9820 } 9821 return romptr; 9822 } 9823 9824 static unsigned short 9825 GetLCDPtrIndexBIOS(struct SiS_Private *SiS_Pr) 9826 { 9827 unsigned short index; 9828 9829 if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 9830 if(!(SiS_IsNotM650orLater(SiS_Pr))) { 9831 if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) { 9832 index >>= 4; 9833 index *= 3; 9834 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9835 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9836 return index; 9837 } 9838 } 9839 } 9840 9841 index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F; 9842 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5; 9843 if(SiS_Pr->SiS_VBType & VB_SIS301C) { /* 1.15.20 and later (not VB specific) */ 9844 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 5; 9845 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) index -= 5; 9846 } else { 9847 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6; 9848 } 9849 index--; 9850 index *= 3; 9851 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9852 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9853 return index; 9854 } 9855 9856 static unsigned short 9857 GetLCDPtrIndex(struct SiS_Private *SiS_Pr) 9858 { 9859 unsigned short index; 9860 9861 index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3; 9862 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2; 9863 else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++; 9864 return index; 9865 } 9866 9867 static unsigned short 9868 GetTVPtrIndex(struct SiS_Private *SiS_Pr) 9869 { 9870 unsigned short index; 9871 9872 index = 0; 9873 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1; 9874 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index = 2; 9875 9876 if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) index = 0; 9877 9878 index <<= 1; 9879 9880 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && 9881 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 9882 index++; 9883 } 9884 9885 return index; 9886 } 9887 9888 static unsigned int 9889 GetOEMTVPtr661_2_GEN(struct SiS_Private *SiS_Pr, int addme) 9890 { 9891 unsigned short index = 0, temp = 0; 9892 9893 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 1; 9894 if(SiS_Pr->SiS_TVMode & TVSetPALM) index = 2; 9895 if(SiS_Pr->SiS_TVMode & TVSetPALN) index = 3; 9896 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 6; 9897 if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) { 9898 index = 4; 9899 if(SiS_Pr->SiS_TVMode & TVSetPALM) index++; 9900 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) index = 7; 9901 } 9902 9903 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 9904 if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || 9905 (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) { 9906 index += addme; 9907 temp++; 9908 } 9909 temp += 0x0100; 9910 } 9911 return (unsigned int)(index | (temp << 16)); 9912 } 9913 9914 static unsigned int 9915 GetOEMTVPtr661_2_OLD(struct SiS_Private *SiS_Pr) 9916 { 9917 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 8)); 9918 } 9919 9920 #if 0 9921 static unsigned int 9922 GetOEMTVPtr661_2_NEW(struct SiS_Private *SiS_Pr) 9923 { 9924 return (GetOEMTVPtr661_2_GEN(SiS_Pr, 6)); 9925 } 9926 #endif 9927 9928 static int 9929 GetOEMTVPtr661(struct SiS_Private *SiS_Pr) 9930 { 9931 int index = 0; 9932 9933 if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2; 9934 if(SiS_Pr->SiS_ROMNew) { 9935 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4; 9936 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6; 9937 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8; 9938 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10; 9939 } else { 9940 if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4; 9941 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6; 9942 if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8; 9943 if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10; 9944 } 9945 9946 if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++; 9947 9948 return index; 9949 } 9950 9951 static void 9952 SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo) 9953 { 9954 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 9955 unsigned short delay=0,index,myindex,temp,romptr=0; 9956 bool dochiptest = true; 9957 9958 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 9959 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf); 9960 } else { 9961 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f); 9962 } 9963 9964 /* Find delay (from ROM, internal tables, PCI subsystem) */ 9965 9966 if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */ 9967 9968 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 9969 romptr = GetRAMDACromptr(SiS_Pr); 9970 } 9971 if(romptr) delay = ROMAddr[romptr]; 9972 else { 9973 delay = 0x04; 9974 if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 9975 if(IS_SIS650) { 9976 delay = 0x0a; 9977 } else if(IS_SIS740) { 9978 delay = 0x00; 9979 } else { 9980 delay = 0x0c; 9981 } 9982 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 9983 delay = 0x00; 9984 } 9985 } 9986 9987 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */ 9988 9989 bool gotitfrompci = false; 9990 9991 /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */ 9992 9993 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 9994 if(SiS_Pr->PDC != -1) { 9995 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f)); 9996 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7)); 9997 return; 9998 } 9999 } else { 10000 if(SiS_Pr->PDCA != -1) { 10001 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0)); 10002 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6)); 10003 return; 10004 } 10005 } 10006 10007 /* Custom Panel? */ 10008 10009 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) { 10010 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10011 delay = 0x00; 10012 if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) { 10013 delay = 0x20; 10014 } 10015 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay); 10016 } else { 10017 delay = 0x0c; 10018 if(SiS_Pr->SiS_VBType & VB_SIS301C) { 10019 delay = 0x03; 10020 if((SiS_Pr->PanelXRes > 1280) && (SiS_Pr->PanelYRes > 1024)) { 10021 delay = 0x00; 10022 } 10023 } else if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10024 if(IS_SIS740) delay = 0x01; 10025 else delay = 0x03; 10026 } 10027 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay); 10028 } 10029 return; 10030 } 10031 10032 /* This is a piece of typical SiS crap: They code the OEM LCD 10033 * delay into the code, at no defined place in the BIOS. 10034 * We now have to start doing a PCI subsystem check here. 10035 */ 10036 10037 switch(SiS_Pr->SiS_CustomT) { 10038 case CUT_COMPAQ1280: 10039 case CUT_COMPAQ12802: 10040 if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 10041 gotitfrompci = true; 10042 dochiptest = false; 10043 delay = 0x03; 10044 } 10045 break; 10046 case CUT_CLEVO1400: 10047 case CUT_CLEVO14002: 10048 gotitfrompci = true; 10049 dochiptest = false; 10050 delay = 0x02; 10051 break; 10052 case CUT_CLEVO1024: 10053 case CUT_CLEVO10242: 10054 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10055 gotitfrompci = true; 10056 dochiptest = false; 10057 delay = 0x33; 10058 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay); 10059 delay &= 0x0f; 10060 } 10061 break; 10062 } 10063 10064 /* Could we find it through the PCI ID? If no, use ROM or table */ 10065 10066 if(!gotitfrompci) { 10067 10068 index = GetLCDPtrIndexBIOS(SiS_Pr); 10069 myindex = GetLCDPtrIndex(SiS_Pr); 10070 10071 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10072 10073 if(SiS_IsNotM650orLater(SiS_Pr)) { 10074 10075 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10076 /* Always use the second pointer on 650; some BIOSes */ 10077 /* still carry old 301 data at the first location */ 10078 /* romptr = SISGETROMW(0x120); */ 10079 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */ 10080 romptr = SISGETROMW(0x122); 10081 if(!romptr) return; 10082 delay = ROMAddr[(romptr + index)]; 10083 } else { 10084 delay = SiS310_LCDDelayCompensation_650301LV[myindex]; 10085 } 10086 10087 } else { 10088 10089 delay = SiS310_LCDDelayCompensation_651301LV[myindex]; 10090 if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) 10091 delay = SiS310_LCDDelayCompensation_651302LV[myindex]; 10092 10093 } 10094 10095 } else if(SiS_Pr->SiS_UseROM && 10096 (!(SiS_Pr->SiS_ROMNew)) && 10097 (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) && 10098 (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) && 10099 (SiS_Pr->SiS_LCDResInfo != Panel_1280x960) && 10100 (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200) && 10101 ((romptr = GetLCDromptr(SiS_Pr)))) { 10102 10103 /* Data for 1280x1024 wrong in 301B BIOS */ 10104 /* Data for 1600x1200 wrong in 301C BIOS */ 10105 delay = ROMAddr[(romptr + index)]; 10106 10107 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 10108 10109 if(IS_SIS740) delay = 0x03; 10110 else delay = 0x00; 10111 10112 } else { 10113 10114 delay = SiS310_LCDDelayCompensation_301[myindex]; 10115 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10116 if(IS_SIS740) delay = 0x01; 10117 else if(SiS_Pr->ChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex]; 10118 else delay = SiS310_LCDDelayCompensation_650301LV[myindex]; 10119 } else if(SiS_Pr->SiS_VBType & VB_SIS301C) { 10120 if(IS_SIS740) delay = 0x01; /* ? */ 10121 else delay = 0x03; 10122 if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) delay = 0x00; /* experience */ 10123 } else if(SiS_Pr->SiS_VBType & VB_SIS30xB) { 10124 if(IS_SIS740) delay = 0x01; 10125 else delay = SiS310_LCDDelayCompensation_3xx301B[myindex]; 10126 } 10127 10128 } 10129 10130 } /* got it from PCI */ 10131 10132 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10133 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0)); 10134 dochiptest = false; 10135 } 10136 10137 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */ 10138 10139 index = GetTVPtrIndex(SiS_Pr); 10140 10141 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10142 10143 if(SiS_IsNotM650orLater(SiS_Pr)) { 10144 10145 if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10146 /* Always use the second pointer on 650; some BIOSes */ 10147 /* still carry old 301 data at the first location */ 10148 /* romptr = SISGETROMW(0x114); */ 10149 /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */ 10150 romptr = SISGETROMW(0x11a); 10151 if(!romptr) return; 10152 delay = ROMAddr[romptr + index]; 10153 10154 } else { 10155 10156 delay = SiS310_TVDelayCompensation_301B[index]; 10157 10158 } 10159 10160 } else { 10161 10162 switch(SiS_Pr->SiS_CustomT) { 10163 case CUT_COMPAQ1280: 10164 case CUT_COMPAQ12802: 10165 case CUT_CLEVO1400: 10166 case CUT_CLEVO14002: 10167 delay = 0x02; 10168 dochiptest = false; 10169 break; 10170 case CUT_CLEVO1024: 10171 case CUT_CLEVO10242: 10172 delay = 0x03; 10173 dochiptest = false; 10174 break; 10175 default: 10176 delay = SiS310_TVDelayCompensation_651301LV[index]; 10177 if(SiS_Pr->SiS_VBType & VB_SIS302LV) { 10178 delay = SiS310_TVDelayCompensation_651302LV[index]; 10179 } 10180 } 10181 } 10182 10183 } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) { 10184 10185 romptr = GetTVromptr(SiS_Pr); 10186 if(!romptr) return; 10187 delay = ROMAddr[romptr + index]; 10188 10189 } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 10190 10191 delay = SiS310_TVDelayCompensation_LVDS[index]; 10192 10193 } else { 10194 10195 delay = SiS310_TVDelayCompensation_301[index]; 10196 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10197 if(IS_SIS740) { 10198 delay = SiS310_TVDelayCompensation_740301B[index]; 10199 /* LV: use 301 data? BIOS bug? */ 10200 } else { 10201 delay = SiS310_TVDelayCompensation_301B[index]; 10202 if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02; 10203 } 10204 } 10205 10206 } 10207 10208 if(SiS_LCDAEnabled(SiS_Pr)) { 10209 delay &= 0x0f; 10210 dochiptest = false; 10211 } 10212 10213 } else return; 10214 10215 /* Write delay */ 10216 10217 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10218 10219 if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SISLVDS) && dochiptest) { 10220 10221 temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4; 10222 if(temp == 8) { /* 1400x1050 BIOS (COMPAL) */ 10223 delay &= 0x0f; 10224 delay |= 0xb0; 10225 } else if(temp == 6) { 10226 delay &= 0x0f; 10227 delay |= 0xc0; 10228 } else if(temp > 7) { /* 1280x1024 BIOS (which one?) */ 10229 delay = 0x35; 10230 } 10231 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay); 10232 10233 } else { 10234 10235 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10236 10237 } 10238 10239 } else { /* LVDS */ 10240 10241 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10242 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10243 } else { 10244 if(IS_SIS650 && (SiS_Pr->SiS_IF_DEF_CH70xx != 0)) { 10245 delay <<= 4; 10246 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,delay); 10247 } else { 10248 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay); 10249 } 10250 } 10251 10252 } 10253 10254 } 10255 10256 static void 10257 SetAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10258 { 10259 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10260 unsigned short index,temp,temp1,romptr=0; 10261 10262 if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p|TVSetYPbPr525p)) return; 10263 10264 if(ModeNo<=0x13) 10265 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; 10266 else 10267 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; 10268 10269 temp = GetTVPtrIndex(SiS_Pr); 10270 temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10271 temp1 = temp; 10272 10273 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10274 if(SiS_Pr->ChipType >= SIS_661) { 10275 temp1 = GetOEMTVPtr661(SiS_Pr); 10276 temp1 >>= 1; 10277 romptr = SISGETROMW(0x260); 10278 if(SiS_Pr->ChipType >= SIS_760) { 10279 romptr = SISGETROMW(0x360); 10280 } 10281 } else if(SiS_Pr->ChipType >= SIS_330) { 10282 romptr = SISGETROMW(0x192); 10283 } else { 10284 romptr = SISGETROMW(0x112); 10285 } 10286 } 10287 10288 if(romptr) { 10289 temp1 <<= 1; 10290 temp = ROMAddr[romptr + temp1 + index]; 10291 } else { 10292 temp = SiS310_TVAntiFlick1[temp][index]; 10293 } 10294 temp <<= 4; 10295 10296 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8f,temp); /* index 0A D[6:4] */ 10297 } 10298 10299 static void 10300 SetEdgeEnhance(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 10301 { 10302 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10303 unsigned short index,temp,temp1,romptr=0; 10304 10305 temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10306 10307 if(ModeNo <= 0x13) 10308 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; 10309 else 10310 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; 10311 10312 if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) { 10313 if(SiS_Pr->ChipType >= SIS_661) { 10314 romptr = SISGETROMW(0x26c); 10315 if(SiS_Pr->ChipType >= SIS_760) { 10316 romptr = SISGETROMW(0x36c); 10317 } 10318 temp1 = GetOEMTVPtr661(SiS_Pr); 10319 temp1 >>= 1; 10320 } else if(SiS_Pr->ChipType >= SIS_330) { 10321 romptr = SISGETROMW(0x1a4); 10322 } else { 10323 romptr = SISGETROMW(0x124); 10324 } 10325 } 10326 10327 if(romptr) { 10328 temp1 <<= 1; 10329 temp = ROMAddr[romptr + temp1 + index]; 10330 } else { 10331 temp = SiS310_TVEdge1[temp][index]; 10332 } 10333 temp <<= 5; 10334 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x3A,0x1F,temp); /* index 0A D[7:5] */ 10335 } 10336 10337 static void 10338 SetYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 10339 { 10340 unsigned short index, temp, i, j; 10341 10342 if(ModeNo <= 0x13) { 10343 index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex; 10344 } else { 10345 index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; 10346 } 10347 10348 temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */ 10349 10350 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */ 10351 else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */ 10352 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 4; /* PAL-N */ 10353 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) temp = 1; /* HiVision uses PAL */ 10354 10355 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10356 for(i=0x35, j=0; i<=0x38; i++, j++) { 10357 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); 10358 } 10359 for(i=0x48; i<=0x4A; i++, j++) { 10360 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]); 10361 } 10362 } else { 10363 for(i=0x35, j=0; i<=0x38; i++, j++) { 10364 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]); 10365 } 10366 } 10367 } 10368 10369 static void 10370 SetPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10371 { 10372 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10373 unsigned short index,temp,i,j,resinfo,romptr=0; 10374 unsigned int lindex; 10375 10376 if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return; 10377 10378 /* NTSC-J data not in BIOS, and already set in SetGroup2 */ 10379 if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return; 10380 10381 if((SiS_Pr->ChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) { 10382 lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff; 10383 lindex <<= 2; 10384 for(j=0, i=0x31; i<=0x34; i++, j++) { 10385 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_TVPhase[lindex + j]); 10386 } 10387 return; 10388 } 10389 10390 /* PAL-M, PAL-N not in BIOS, and already set in SetGroup2 */ 10391 if(SiS_Pr->SiS_TVMode & (TVSetPALM | TVSetPALN)) return; 10392 10393 if(ModeNo<=0x13) { 10394 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 10395 } else { 10396 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 10397 } 10398 10399 temp = GetTVPtrIndex(SiS_Pr); 10400 /* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics, 10401 * 3: PAL Text, 4: HiTV Graphics 5: HiTV Text 10402 */ 10403 if(SiS_Pr->SiS_UseROM) { 10404 romptr = SISGETROMW(0x116); 10405 if(SiS_Pr->ChipType >= SIS_330) { 10406 romptr = SISGETROMW(0x196); 10407 } 10408 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 10409 romptr = SISGETROMW(0x11c); 10410 if(SiS_Pr->ChipType >= SIS_330) { 10411 romptr = SISGETROMW(0x19c); 10412 } 10413 if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) { 10414 romptr = SISGETROMW(0x116); 10415 if(SiS_Pr->ChipType >= SIS_330) { 10416 romptr = SISGETROMW(0x196); 10417 } 10418 } 10419 } 10420 } 10421 if(romptr) { 10422 romptr += (temp << 2); 10423 for(j=0, i=0x31; i<=0x34; i++, j++) { 10424 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 10425 } 10426 } else { 10427 index = temp % 2; 10428 temp >>= 1; /* 0:NTSC, 1:PAL, 2:HiTV */ 10429 for(j=0, i=0x31; i<=0x34; i++, j++) { 10430 if(!(SiS_Pr->SiS_VBType & VB_SIS30xBLV)) 10431 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); 10432 else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) 10433 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]); 10434 else 10435 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]); 10436 } 10437 } 10438 10439 if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision))) { 10440 if((!(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetYPbPr525p | TVSetYPbPr750p))) && (ModeNo > 0x13)) { 10441 if((resinfo == SIS_RI_640x480) || 10442 (resinfo == SIS_RI_800x600)) { 10443 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21); 10444 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0); 10445 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5); 10446 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f); 10447 } else if(resinfo == SIS_RI_1024x768) { 10448 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e); 10449 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b); 10450 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb); 10451 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b); 10452 } 10453 } 10454 } 10455 } 10456 10457 static void 10458 SetDelayComp661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 10459 unsigned short ModeIdIndex, unsigned short RTI) 10460 { 10461 unsigned short delay = 0, romptr = 0, index, lcdpdcindex; 10462 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10463 10464 if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC))) 10465 return; 10466 10467 /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */ 10468 /* (If a custom mode is used, Pass1:1 is always set; hence we do this:) */ 10469 10470 if(SiS_Pr->SiS_ROMNew) { 10471 if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) || 10472 ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && 10473 (SiS_Pr->SiS_LCDInfo & LCDPass11))) { 10474 index = 25; 10475 if(SiS_Pr->UseCustomMode) { 10476 index = SiS_Pr->CSRClock; 10477 } else if(ModeNo > 0x13) { 10478 index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI); 10479 index = SiS_Pr->SiS_VCLKData[index].CLOCK; 10480 } 10481 if(index < 25) index = 25; 10482 index = ((index / 25) - 1) << 1; 10483 if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) { 10484 index++; 10485 } 10486 romptr = SISGETROMW(0x104); 10487 delay = ROMAddr[romptr + index]; 10488 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) { 10489 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f)); 10490 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7)); 10491 } else { 10492 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0)); 10493 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6)); 10494 } 10495 return; 10496 } 10497 } 10498 10499 /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */ 10500 10501 if(SiS_Pr->UseCustomMode) delay = 0x04; 10502 else if(ModeNo <= 0x13) delay = 0x04; 10503 else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4); 10504 delay |= (delay << 8); 10505 10506 if(SiS_Pr->ChipType >= XGI_20) { 10507 10508 delay = 0x0606; 10509 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10510 10511 delay = 0x0404; 10512 if(SiS_Pr->SiS_XGIROM) { 10513 index = GetTVPtrIndex(SiS_Pr); 10514 if((romptr = SISGETROMW(0x35e))) { 10515 delay = (ROMAddr[romptr + index] & 0x0f) << 1; 10516 delay |= (delay << 8); 10517 } 10518 } 10519 10520 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) { 10521 if(SiS_Pr->ChipType == XGI_40 && SiS_Pr->ChipRevision == 0x02) { 10522 delay -= 0x0404; 10523 } 10524 } 10525 } 10526 10527 } else if(SiS_Pr->ChipType >= SIS_340) { 10528 10529 delay = 0x0606; 10530 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10531 delay = 0x0404; 10532 } 10533 /* TODO (eventually) */ 10534 10535 } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10536 10537 /* 3. TV */ 10538 10539 index = GetOEMTVPtr661(SiS_Pr); 10540 if(SiS_Pr->SiS_ROMNew) { 10541 romptr = SISGETROMW(0x106); 10542 if(SiS_Pr->SiS_VBType & VB_UMC) romptr += 12; 10543 delay = ROMAddr[romptr + index]; 10544 } else { 10545 delay = 0x04; 10546 if(index > 3) delay = 0; 10547 } 10548 10549 } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10550 10551 /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */ 10552 10553 if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) && 10554 ((romptr = GetLCDStructPtr661_2(SiS_Pr))) ) { 10555 10556 lcdpdcindex = (SiS_Pr->SiS_VBType & VB_UMC) ? 14 : 12; 10557 10558 /* For LVDS (and sometimes TMDS), the BIOS must know about the correct value */ 10559 delay = ROMAddr[romptr + lcdpdcindex + 1]; /* LCD */ 10560 delay |= (ROMAddr[romptr + lcdpdcindex] << 8); /* LCDA */ 10561 10562 } else { 10563 10564 /* TMDS: Set our own, since BIOS has no idea */ 10565 /* (This is done on >=661 only, since <661 is calling this only for LVDS) */ 10566 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 10567 switch(SiS_Pr->SiS_LCDResInfo) { 10568 case Panel_1024x768: delay = 0x0008; break; 10569 case Panel_1280x720: delay = 0x0004; break; 10570 case Panel_1280x768: 10571 case Panel_1280x768_2:delay = 0x0004; break; 10572 case Panel_1280x800: 10573 case Panel_1280x800_2:delay = 0x0004; break; /* Verified for 1280x800 */ 10574 case Panel_1280x854: delay = 0x0004; break; /* FIXME */ 10575 case Panel_1280x1024: delay = 0x1e04; break; 10576 case Panel_1400x1050: delay = 0x0004; break; 10577 case Panel_1600x1200: delay = 0x0400; break; 10578 case Panel_1680x1050: delay = 0x0e04; break; 10579 default: 10580 if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) { 10581 delay = 0x0008; 10582 } else if((SiS_Pr->PanelXRes == 1280) && (SiS_Pr->PanelYRes == 1024)) { 10583 delay = 0x1e04; 10584 } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) { 10585 delay = 0x0004; 10586 } else if((SiS_Pr->PanelXRes <= 1600) && (SiS_Pr->PanelYRes <= 1200)) { 10587 delay = 0x0400; 10588 } else 10589 delay = 0x0e04; 10590 break; 10591 } 10592 } 10593 10594 /* Override by detected or user-set values */ 10595 /* (but only if, for some reason, we can't read value from BIOS) */ 10596 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) { 10597 delay = SiS_Pr->PDC & 0x1f; 10598 } 10599 if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) { 10600 delay = (SiS_Pr->PDCA & 0x1f) << 8; 10601 } 10602 10603 } 10604 10605 } 10606 10607 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10608 delay >>= 8; 10609 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0)); 10610 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6)); 10611 } else { 10612 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f)); 10613 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7)); 10614 } 10615 } 10616 10617 static void 10618 SetCRT2SyncDither661(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short RTI) 10619 { 10620 unsigned short infoflag; 10621 unsigned char temp; 10622 10623 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10624 10625 if(ModeNo <= 0x13) { 10626 infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2); 10627 } else if(SiS_Pr->UseCustomMode) { 10628 infoflag = SiS_Pr->CInfoFlag; 10629 } else { 10630 infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag; 10631 } 10632 10633 if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 10634 infoflag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37); /* No longer check D5 */ 10635 } 10636 10637 infoflag &= 0xc0; 10638 10639 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 10640 temp = (infoflag >> 6) | 0x0c; 10641 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 10642 temp ^= 0x04; 10643 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x10; 10644 } 10645 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp); 10646 } else { 10647 temp = 0x30; 10648 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp = 0x20; 10649 temp |= infoflag; 10650 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp); 10651 temp = 0; 10652 if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) { 10653 if(SiS_Pr->SiS_ModeType >= Mode24Bpp) temp |= 0x80; 10654 } 10655 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp); 10656 } 10657 10658 } 10659 } 10660 10661 static void 10662 SetPanelParms661(struct SiS_Private *SiS_Pr) 10663 { 10664 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 10665 unsigned short romptr, temp1, temp2; 10666 10667 if(SiS_Pr->SiS_VBType & (VB_SISLVDS | VB_SIS30xC)) { 10668 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x24,0x0f); 10669 } 10670 10671 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10672 if(SiS_Pr->LVDSHL != -1) { 10673 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL); 10674 } 10675 } 10676 10677 if(SiS_Pr->SiS_ROMNew) { 10678 10679 if((romptr = GetLCDStructPtr661_2(SiS_Pr))) { 10680 if(SiS_Pr->SiS_VBType & VB_SISLVDS) { 10681 temp1 = (ROMAddr[romptr] & 0x03) | 0x0c; 10682 temp2 = 0xfc; 10683 if(SiS_Pr->LVDSHL != -1) { 10684 temp1 &= 0xfc; 10685 temp2 = 0xf3; 10686 } 10687 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1); 10688 } 10689 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 10690 temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1; 10691 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1); 10692 } 10693 } 10694 10695 } 10696 } 10697 10698 static void 10699 SiS_OEM310Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RRTI) 10700 { 10701 if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SISLVDS)) { 10702 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 10703 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10704 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI); 10705 SetPanelParms661(SiS_Pr); 10706 } 10707 } else { 10708 SetDelayComp(SiS_Pr,ModeNo); 10709 } 10710 10711 if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) { 10712 SetAntiFlicker(SiS_Pr,ModeNo,ModeIdIndex); 10713 SetPhaseIncr(SiS_Pr,ModeNo,ModeIdIndex); 10714 SetYFilter(SiS_Pr,ModeNo,ModeIdIndex); 10715 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10716 SetEdgeEnhance(SiS_Pr,ModeNo,ModeIdIndex); 10717 } 10718 } 10719 } 10720 10721 static void 10722 SiS_OEM661Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, 10723 unsigned short ModeIdIndex, unsigned short RRTI) 10724 { 10725 if(SiS_Pr->SiS_VBType & VB_SISVB) { 10726 10727 SetDelayComp661(SiS_Pr, ModeNo, ModeIdIndex, RRTI); 10728 10729 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10730 SetCRT2SyncDither661(SiS_Pr, ModeNo, RRTI); 10731 SetPanelParms661(SiS_Pr); 10732 } 10733 10734 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 10735 SetPhaseIncr(SiS_Pr, ModeNo, ModeIdIndex); 10736 SetYFilter(SiS_Pr, ModeNo, ModeIdIndex); 10737 SetAntiFlicker(SiS_Pr, ModeNo, ModeIdIndex); 10738 if(SiS_Pr->SiS_VBType & VB_SIS301) { 10739 SetEdgeEnhance(SiS_Pr, ModeNo, ModeIdIndex); 10740 } 10741 } 10742 } 10743 } 10744 10745 /* FinalizeLCD 10746 * This finalizes some CRT2 registers for the very panel used. 10747 * If we have a backup if these registers, we use it; otherwise 10748 * we set the register according to most BIOSes. However, this 10749 * function looks quite different in every BIOS, so you better 10750 * pray that we have a backup... 10751 */ 10752 static void 10753 SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 10754 { 10755 unsigned short tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp; 10756 unsigned short resinfo,modeflag; 10757 10758 if(!(SiS_Pr->SiS_VBType & VB_SISLVDS)) return; 10759 if(SiS_Pr->SiS_ROMNew) return; 10760 10761 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10762 if(SiS_Pr->LVDSHL != -1) { 10763 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL); 10764 } 10765 } 10766 10767 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return; 10768 if(SiS_Pr->UseCustomMode) return; 10769 10770 switch(SiS_Pr->SiS_CustomT) { 10771 case CUT_COMPAQ1280: 10772 case CUT_COMPAQ12802: 10773 case CUT_CLEVO1400: 10774 case CUT_CLEVO14002: 10775 return; 10776 } 10777 10778 if(ModeNo <= 0x13) { 10779 resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo; 10780 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 10781 } else { 10782 resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO; 10783 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 10784 } 10785 10786 if(IS_SIS650) { 10787 if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) { 10788 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { 10789 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02); 10790 } else { 10791 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03); 10792 } 10793 } 10794 } 10795 10796 if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) { 10797 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10798 /* Maybe all panels? */ 10799 if(SiS_Pr->LVDSHL == -1) { 10800 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10801 } 10802 return; 10803 } 10804 } 10805 10806 if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) { 10807 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10808 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10809 if(SiS_Pr->LVDSHL == -1) { 10810 /* Maybe all panels? */ 10811 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10812 } 10813 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10814 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 10815 if(tempch == 3) { 10816 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10817 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25); 10818 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00); 10819 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b); 10820 } 10821 } 10822 return; 10823 } 10824 } 10825 } 10826 10827 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { 10828 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10829 if(SiS_Pr->SiS_VBType & VB_SISEMI) { 10830 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00); 10831 #ifdef SET_EMI 10832 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c); 10833 #endif 10834 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10); 10835 } 10836 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) { 10837 if(SiS_Pr->LVDSHL == -1) { 10838 /* Maybe ACER only? */ 10839 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01); 10840 } 10841 } 10842 tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4; 10843 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) { 10844 if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) { 10845 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76); 10846 } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10847 if(tempch == 0x03) { 10848 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10849 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25); 10850 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00); 10851 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b); 10852 } 10853 if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) { 10854 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14); 10855 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15); 10856 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16); 10857 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17); 10858 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18); 10859 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19); 10860 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a); 10861 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b); 10862 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c); 10863 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d); 10864 } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) { /* 1.10.8w */ 10865 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90); 10866 if(ModeNo <= 0x13) { 10867 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11); 10868 if((resinfo == 0) || (resinfo == 2)) return; 10869 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18); 10870 if((resinfo == 1) || (resinfo == 3)) return; 10871 } 10872 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); 10873 if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) { 10874 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02); /* 1.10.7u */ 10875 #if 0 10876 tempbx = 806; /* 0x326 */ /* other older BIOSes */ 10877 tempbx--; 10878 temp = tempbx & 0xff; 10879 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); 10880 temp = (tempbx >> 8) & 0x03; 10881 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp); 10882 #endif 10883 } 10884 } else if(ModeNo <= 0x13) { 10885 if(ModeNo <= 1) { 10886 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70); 10887 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff); 10888 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48); 10889 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12); 10890 } 10891 if(!(modeflag & HalfDCLK)) { 10892 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20); 10893 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a); 10894 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28); 10895 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00); 10896 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c); 10897 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc); 10898 if(ModeNo == 0x12) { 10899 switch(tempch) { 10900 case 0: 10901 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95); 10902 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc); 10903 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10); 10904 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95); 10905 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48); 10906 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12); 10907 break; 10908 case 2: 10909 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95); 10910 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48); 10911 break; 10912 case 3: 10913 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95); 10914 break; 10915 } 10916 } 10917 } 10918 } 10919 } 10920 } else { 10921 tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01); 10922 tempcl &= 0x0f; 10923 tempbh &= 0x70; 10924 tempbh >>= 4; 10925 tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04); 10926 tempbx = (tempbh << 8) | tempbl; 10927 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 10928 if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) { 10929 if(SiS_Pr->SiS_SetFlag & LCDVESATiming) { 10930 tempbx = 770; 10931 } else { 10932 if(tempbx > 770) tempbx = 770; 10933 if(SiS_Pr->SiS_VGAVDE < 600) { 10934 tempax = 768 - SiS_Pr->SiS_VGAVDE; 10935 tempax >>= 4; /* 1.10.7w; 1.10.6s: 3; */ 10936 if(SiS_Pr->SiS_VGAVDE <= 480) tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */ 10937 tempbx -= tempax; 10938 } 10939 } 10940 } else return; 10941 } 10942 temp = tempbx & 0xff; 10943 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp); 10944 temp = ((tempbx & 0xff00) >> 4) | tempcl; 10945 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp); 10946 } 10947 } 10948 } 10949 10950 #endif 10951 10952 /* ================= SiS 300 O.E.M. ================== */ 10953 10954 #ifdef CONFIG_FB_SIS_300 10955 10956 static void 10957 SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex, 10958 unsigned short RefTabIndex) 10959 { 10960 unsigned short crt2crtc=0, modeflag, myindex=0; 10961 unsigned char temp; 10962 int i; 10963 10964 if(ModeNo <= 0x13) { 10965 modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; 10966 crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC; 10967 } else { 10968 modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; 10969 crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC; 10970 } 10971 10972 crt2crtc &= 0x3f; 10973 10974 if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) { 10975 SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf); 10976 } 10977 10978 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) { 10979 if(modeflag & HalfDCLK) myindex = 1; 10980 10981 if(SiS_Pr->SiS_SetFlag & LowModeTests) { 10982 for(i=0; i<7; i++) { 10983 if(barco_p1[myindex][crt2crtc][i][0]) { 10984 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port, 10985 barco_p1[myindex][crt2crtc][i][0], 10986 barco_p1[myindex][crt2crtc][i][2], 10987 barco_p1[myindex][crt2crtc][i][1]); 10988 } 10989 } 10990 } 10991 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00); 10992 if(temp & 0x80) { 10993 temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18); 10994 temp++; 10995 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); 10996 } 10997 } 10998 } 10999 11000 static unsigned short 11001 GetOEMLCDPtr(struct SiS_Private *SiS_Pr, int Flag) 11002 { 11003 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11004 unsigned short tempbx=0,romptr=0; 11005 static const unsigned char customtable300[] = { 11006 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 11007 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 11008 }; 11009 static const unsigned char customtable630[] = { 11010 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 11011 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 11012 }; 11013 11014 if(SiS_Pr->ChipType == SIS_300) { 11015 11016 tempbx = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f; 11017 if(SiS_Pr->SiS_VBType & VB_SIS301) tempbx &= 0x07; 11018 tempbx -= 2; 11019 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4; 11020 if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) { 11021 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3; 11022 } 11023 if(SiS_Pr->SiS_UseROM) { 11024 if(ROMAddr[0x235] & 0x80) { 11025 tempbx = SiS_Pr->SiS_LCDTypeInfo; 11026 if(Flag) { 11027 romptr = SISGETROMW(0x255); 11028 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; 11029 else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo]; 11030 if(tempbx == 0xFF) return 0xFFFF; 11031 } 11032 tempbx <<= 1; 11033 if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++; 11034 } 11035 } 11036 11037 } else { 11038 11039 if(Flag) { 11040 if(SiS_Pr->SiS_UseROM) { 11041 romptr = SISGETROMW(0x255); 11042 if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo]; 11043 else tempbx = 0xff; 11044 } else { 11045 tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo]; 11046 } 11047 if(tempbx == 0xFF) return 0xFFFF; 11048 tempbx <<= 2; 11049 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; 11050 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 11051 return tempbx; 11052 } 11053 tempbx = SiS_Pr->SiS_LCDTypeInfo << 2; 11054 if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempbx += 2; 11055 if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++; 11056 11057 } 11058 11059 return tempbx; 11060 } 11061 11062 static void 11063 SetOEMLCDDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 11064 { 11065 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11066 unsigned short index,temp,romptr=0; 11067 11068 if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return; 11069 11070 if(SiS_Pr->SiS_UseROM) { 11071 if(!(ROMAddr[0x237] & 0x01)) return; 11072 if(!(ROMAddr[0x237] & 0x02)) return; 11073 romptr = SISGETROMW(0x24b); 11074 } 11075 11076 /* The Panel Compensation Delay should be set according to tables 11077 * here. Unfortunately, various BIOS versions don't care about 11078 * a uniform way using eg. ROM byte 0x220, but use different 11079 * hard coded delays (0x04, 0x20, 0x18) in SetGroup1(). 11080 * Thus we don't set this if the user selected a custom pdc or if 11081 * we otherwise detected a valid pdc. 11082 */ 11083 if(SiS_Pr->PDC != -1) return; 11084 11085 temp = GetOEMLCDPtr(SiS_Pr, 0); 11086 11087 if(SiS_Pr->UseCustomMode) 11088 index = 0; 11089 else 11090 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex; 11091 11092 if(SiS_Pr->ChipType != SIS_300) { 11093 if(romptr) { 11094 romptr += (temp * 2); 11095 romptr = SISGETROMW(romptr); 11096 romptr += index; 11097 temp = ROMAddr[romptr]; 11098 } else { 11099 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11100 temp = SiS300_OEMLCDDelay2[temp][index]; 11101 } else { 11102 temp = SiS300_OEMLCDDelay3[temp][index]; 11103 } 11104 } 11105 } else { 11106 if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) { 11107 if(romptr) { 11108 romptr += (temp * 2); 11109 romptr = SISGETROMW(romptr); 11110 romptr += index; 11111 temp = ROMAddr[romptr]; 11112 } else { 11113 temp = SiS300_OEMLCDDelay5[temp][index]; 11114 } 11115 } else { 11116 if(SiS_Pr->SiS_UseROM) { 11117 romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8); 11118 if(romptr) { 11119 romptr += (temp * 2); 11120 romptr = SISGETROMW(romptr); 11121 romptr += index; 11122 temp = ROMAddr[romptr]; 11123 } else { 11124 temp = SiS300_OEMLCDDelay4[temp][index]; 11125 } 11126 } else { 11127 temp = SiS300_OEMLCDDelay4[temp][index]; 11128 } 11129 } 11130 } 11131 temp &= 0x3c; 11132 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */ 11133 } 11134 11135 static void 11136 SetOEMLCDData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11137 { 11138 #if 0 /* Unfinished; Data table missing */ 11139 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11140 unsigned short index,temp; 11141 11142 if((SiS_Pr->SiS_UseROM) { 11143 if(!(ROMAddr[0x237] & 0x01)) return; 11144 if(!(ROMAddr[0x237] & 0x04)) return; 11145 /* No rom pointer in BIOS header! */ 11146 } 11147 11148 temp = GetOEMLCDPtr(SiS_Pr, 1); 11149 if(temp == 0xFFFF) return; 11150 11151 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex; 11152 for(i=0x14, j=0; i<=0x17; i++, j++) { 11153 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]); 11154 } 11155 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07)); 11156 11157 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex; 11158 SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]); 11159 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]); 11160 SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38)); 11161 for(i=0x1b, j=3; i<=0x1d; i++, j++) { 11162 SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]); 11163 } 11164 #endif 11165 } 11166 11167 static unsigned short 11168 GetOEMTVPtr(struct SiS_Private *SiS_Pr) 11169 { 11170 unsigned short index; 11171 11172 index = 0; 11173 if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) index += 4; 11174 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11175 if(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART) index += 2; 11176 else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) index += 3; 11177 else if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1; 11178 } else { 11179 if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) index += 2; 11180 if(SiS_Pr->SiS_TVMode & TVSetPAL) index += 1; 11181 } 11182 return index; 11183 } 11184 11185 static void 11186 SetOEMTVDelay(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11187 { 11188 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11189 unsigned short index,temp,romptr=0; 11190 11191 if(SiS_Pr->SiS_UseROM) { 11192 if(!(ROMAddr[0x238] & 0x01)) return; 11193 if(!(ROMAddr[0x238] & 0x02)) return; 11194 romptr = SISGETROMW(0x241); 11195 } 11196 11197 temp = GetOEMTVPtr(SiS_Pr); 11198 11199 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVDelayIndex; 11200 11201 if(romptr) { 11202 romptr += (temp * 2); 11203 romptr = SISGETROMW(romptr); 11204 romptr += index; 11205 temp = ROMAddr[romptr]; 11206 } else { 11207 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11208 temp = SiS300_OEMTVDelay301[temp][index]; 11209 } else { 11210 temp = SiS300_OEMTVDelayLVDS[temp][index]; 11211 } 11212 } 11213 temp &= 0x3c; 11214 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); 11215 } 11216 11217 static void 11218 SetOEMAntiFlicker(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11219 { 11220 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11221 unsigned short index,temp,romptr=0; 11222 11223 if(SiS_Pr->SiS_UseROM) { 11224 if(!(ROMAddr[0x238] & 0x01)) return; 11225 if(!(ROMAddr[0x238] & 0x04)) return; 11226 romptr = SISGETROMW(0x243); 11227 } 11228 11229 temp = GetOEMTVPtr(SiS_Pr); 11230 11231 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVFlickerIndex; 11232 11233 if(romptr) { 11234 romptr += (temp * 2); 11235 romptr = SISGETROMW(romptr); 11236 romptr += index; 11237 temp = ROMAddr[romptr]; 11238 } else { 11239 temp = SiS300_OEMTVFlicker[temp][index]; 11240 } 11241 temp &= 0x70; 11242 SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp); 11243 } 11244 11245 static void 11246 SetOEMPhaseIncr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex) 11247 { 11248 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11249 unsigned short index,i,j,temp,romptr=0; 11250 11251 if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) return; 11252 11253 if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return; 11254 11255 if(SiS_Pr->SiS_UseROM) { 11256 if(!(ROMAddr[0x238] & 0x01)) return; 11257 if(!(ROMAddr[0x238] & 0x08)) return; 11258 romptr = SISGETROMW(0x245); 11259 } 11260 11261 temp = GetOEMTVPtr(SiS_Pr); 11262 11263 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVPhaseIndex; 11264 11265 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 11266 for(i=0x31, j=0; i<=0x34; i++, j++) { 11267 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]); 11268 } 11269 } else { 11270 if(romptr) { 11271 romptr += (temp * 2); 11272 romptr = SISGETROMW(romptr); 11273 romptr += (index * 4); 11274 for(i=0x31, j=0; i<=0x34; i++, j++) { 11275 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 11276 } 11277 } else { 11278 for(i=0x31, j=0; i<=0x34; i++, j++) { 11279 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]); 11280 } 11281 } 11282 } 11283 } 11284 11285 static void 11286 SetOEMYFilter(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex) 11287 { 11288 unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; 11289 unsigned short index,temp,i,j,romptr=0; 11290 11291 if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return; 11292 11293 if(SiS_Pr->SiS_UseROM) { 11294 if(!(ROMAddr[0x238] & 0x01)) return; 11295 if(!(ROMAddr[0x238] & 0x10)) return; 11296 romptr = SISGETROMW(0x247); 11297 } 11298 11299 temp = GetOEMTVPtr(SiS_Pr); 11300 11301 if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 8; 11302 else if(SiS_Pr->SiS_TVMode & TVSetPALN) temp = 9; 11303 /* NTSCJ uses NTSC filters */ 11304 11305 index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex; 11306 11307 if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { 11308 for(i=0x35, j=0; i<=0x38; i++, j++) { 11309 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); 11310 } 11311 for(i=0x48; i<=0x4A; i++, j++) { 11312 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]); 11313 } 11314 } else { 11315 if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) { 11316 romptr += (temp * 2); 11317 romptr = SISGETROMW(romptr); 11318 romptr += (index * 4); 11319 for(i=0x35, j=0; i<=0x38; i++, j++) { 11320 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]); 11321 } 11322 } else { 11323 for(i=0x35, j=0; i<=0x38; i++, j++) { 11324 SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]); 11325 } 11326 } 11327 } 11328 } 11329 11330 static unsigned short 11331 SiS_SearchVBModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo) 11332 { 11333 unsigned short ModeIdIndex; 11334 unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO; 11335 11336 if(*ModeNo <= 5) *ModeNo |= 1; 11337 11338 for(ModeIdIndex=0; ; ModeIdIndex++) { 11339 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break; 11340 if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF) return 0; 11341 } 11342 11343 if(*ModeNo != 0x07) { 11344 if(*ModeNo > 0x03) return ModeIdIndex; 11345 if(VGAINFO & 0x80) return ModeIdIndex; 11346 ModeIdIndex++; 11347 } 11348 11349 if(VGAINFO & 0x10) ModeIdIndex++; /* 400 lines */ 11350 /* else 350 lines */ 11351 return ModeIdIndex; 11352 } 11353 11354 static void 11355 SiS_OEM300Setting(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, 11356 unsigned short RefTableIndex) 11357 { 11358 unsigned short OEMModeIdIndex = 0; 11359 11360 if(!SiS_Pr->UseCustomMode) { 11361 OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo); 11362 if(!(OEMModeIdIndex)) return; 11363 } 11364 11365 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { 11366 SetOEMLCDDelay(SiS_Pr, ModeNo, OEMModeIdIndex); 11367 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { 11368 SetOEMLCDData(SiS_Pr, ModeNo, OEMModeIdIndex); 11369 } 11370 } 11371 if(SiS_Pr->UseCustomMode) return; 11372 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { 11373 SetOEMTVDelay(SiS_Pr, ModeNo,OEMModeIdIndex); 11374 if(SiS_Pr->SiS_VBType & VB_SISVB) { 11375 SetOEMAntiFlicker(SiS_Pr, ModeNo, OEMModeIdIndex); 11376 SetOEMPhaseIncr(SiS_Pr, ModeNo, OEMModeIdIndex); 11377 SetOEMYFilter(SiS_Pr, ModeNo, OEMModeIdIndex); 11378 } 11379 } 11380 } 11381 #endif 11382 11383